【发布时间】:2019-06-27 06:53:36
【问题描述】:
我想在我的一个 spring mvc 项目中实现基于 URL 的授权。在我的 spring mvc 项目中,我使用的是 java 配置。我参考了这个站点https://www.baeldung.com/role-and-privilege-for-spring-security-registration 来实现基于角色和权限的授权。
所以我创建了以下表格来实现。
这是用户表。
这个角色表。
这是角色和权限的映射表。
这是权限表。
以下是控制器端的代码。
@Controller
@RequestMapping(value={"/user"})
public class UserController {
@ResponseBody
@RequestMapping(value={"/userDashboard"},method = RequestMethod.GET)
public String userDashboard(ModelMap model){
return "UserDashboard";
}
@ResponseBody
@RequestMapping(value={"/testUser"},method = RequestMethod.GET)
public String testUser(ModelMap model){
return "TestUser";
}
}
以下是实现 UserDetailService 的代码。
@Service("authService")
@Transactional
public class AuthService implements UserDetailsService {
@Autowired
private UserDaoInterface userDaoInterface;
private static final Logger log = Logger.getLogger(AuthService.class);
@Override
public UserDetails loadUserByUsername(String userName) {
User user = null;
try {
user = userDaoInterface.getUserByUserName(userName);
} catch (Exception e) {
log.error("AuthService @loadUserByUsername --Exception while fetching user from username",e);
}
if(user == null) {
throw new UsernameNotFoundException("Username not found");
}
UserDetails userDetails = new org.springframework.security.core.userdetails.User(user.getUsername(),
user.getPassword(),!user.getIsDeleted(),true,true,true,getAuthorities(user.getRole()));
log.info("UserService userDetails " + userDetails);
return userDetails;
}
private Collection<? extends GrantedAuthority> getAuthorities(Role role) {
return getGrantedAuthorities(getPrivileges(role));
}
private List<String> getPrivileges(Role role) {
List<String> privileges = new ArrayList<>();
List<Privilege> collection = new ArrayList<>();
collection.addAll(role.getPrivileges());
for (Privilege item : collection) {
privileges.add(item.getName());
}
return privileges;
}
private List<GrantedAuthority> getGrantedAuthorities(List<String> privileges) {
List<GrantedAuthority> authorities = new ArrayList<>();
for (String privilege : privileges) {
authorities.add(new SimpleGrantedAuthority(privilege));
}
return authorities;
}
}
Spring 安全配置
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
@ComponentScan("com.project")
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService authService;
@Autowired
PersistentTokenRepository tokenRepository;
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(authService);
auth.authenticationProvider(authenticationProvider());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(authService);
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
@Bean
public PersistentTokenBasedRememberMeServices getPersistentTokenBasedRememberMeServices() {
return new PersistentTokenBasedRememberMeServices("remember-me", authService, tokenRepository);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated()
.and()
.formLogin()
.loginProcessingUrl("/login")
.defaultSuccessUrl("/login")
.and()
.logout().logoutUrl("/logout")
.logoutSuccessUrl("/")
.and().csrf()
.and().rememberMe().rememberMeParameter("remember-me").tokenRepository(tokenRepository).tokenValiditySeconds(86400);
}
}
当我通过存储在用户表中的凭据登录系统并尝试访问像 http://localhost:8080/RestProject/user/testUser 这样的 url 时,用户有权访问此 url,但根据上述实现,用户不应被允许访问此 url。所以我无法理解动态权限在这里是如何工作的?
【问题讨论】:
-
您的 Spring Security 配置在哪里?暴露一个
UserDetailsService是不够的。 -
这个应该在Spring Security Configuration中配置。
-
@Supun Dharmarathne 如果它应该在 Spring 安全配置中,那么在 UserDetailService 中的 getAuthorities 方法中上述实现的含义是什么。
-
@Supun Dharmarathne 我明白了为什么我们需要在 spring 安全配置中进行一些配置。所以我需要在 spring 安全配置中添加类似 .antMatchers("/user/userDashboard").hasRole("Admin") 的代码。有没有办法只注册登录用户的权限,而不是使用antMatchers注册所有角色的权限?
-
@HimanshuPatel 您配置了所有登录用户都可以访问
http://localhost:8080/RestProject/user/testUser。因此,您的配置按预期工作。
标签: spring spring-mvc spring-security