【发布时间】:2017-08-30 23:32:04
【问题描述】:
我正在学习 Spring Security。我已经基于 github 骨架项目制作了一个标准的登录和注册页面。只要我在数据库中只使用一个角色,我就可以通过我得到的一个角色轻松管理默认成功 url。但现在我想添加两个基于 ADMIN 和 USER 角色的默认 url。
我在这里阅读了这个determine target url based on roles in spring security 3.1 答案并尝试实现它,但isUserInRole() 方法总是返回一个错误值。我正在使用 jdbc 身份验证。
我的 MVC 配置:
@Configuration
@ComponentScan(basePackages={"hu.kreszapp"})
public class MvcConfig extends WebMvcConfigurerAdapter{
@Bean
public BCryptPasswordEncoder passwordEncoder() {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
return bCryptPasswordEncoder;
}
}
我的安全配置:
@Configuration
@EnableWebSecurity
@ComponentScan(basePackages={"hu.kreszapp"})
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
private DataSource dataSource;
@Value("${spring.queries.users-query}")
private String usersQuery;
@Value("${spring.queries.roles-query}")
private String rolesQuery;
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.
jdbcAuthentication()
.usersByUsernameQuery(usersQuery)
.authoritiesByUsernameQuery(rolesQuery)
.dataSource(dataSource)
.passwordEncoder(bCryptPasswordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.
sessionManagement() //session management
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS) //session management
.and()
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/login").permitAll()
.antMatchers("/registration").permitAll()
.antMatchers("/home").hasRole("ADMIN")//hasAuthority("ADMIN")
.antMatchers("/game").hasRole("USER").anyRequest()//hasAuthority("USER").anyRequest()
.authenticated().and().csrf().disable().formLogin()
.loginPage("/login").failureUrl("/login?error=true")
.defaultSuccessUrl("/default")
.usernameParameter("email")
.passwordParameter("password")
.and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/").and().exceptionHandling()
.accessDeniedPage("/access-denied");
}
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/**", "/static/**", "/css/**", "/js/**", "/templates/images/**");
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
auth
.inMemoryAuthentication()
.withUser("admin").password("admin").roles("ADMIN");
}
}
我的控制器:
@RequestMapping(value="/home", method = RequestMethod.GET)
public ModelAndView home(){
ModelAndView modelAndView = new ModelAndView();
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
User user = userService.findUserByEmail(auth.getName());
modelAndView.addObject("userName", "Welcome " + user.getUsername() + " (" + user.getEmail() + ")");
modelAndView.addObject("adminMessage","Content Available Only for Users with Admin Role");
modelAndView.setViewName("/home");
return modelAndView;
}
@RequestMapping(value="/game", method = RequestMethod.GET)
public ModelAndView game(){
ModelAndView modelAndView = new ModelAndView();
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
User user = userService.findUserByEmail(auth.getName());
modelAndView.addObject("userName", "Welcome " + user.getUsername() + " (" + user.getEmail() + ")");
modelAndView.addObject("adminMessage","Content Available Only for Users with Admin Role");
modelAndView.setViewName("/game");
return modelAndView;
}
@RequestMapping(value="/default")
public String default(HttpServletRequest request){
Principal u = request.getUserPrincipal();
logger.info("user principal:" + u.toString());
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String role = auth.getAuthorities().toString();
logger.info("Role:" + u.toString());
boolean r1 = request.isUserInRole("USER");
boolean r2 = request.isUserInRole("ADMIN");
boolean r3 =request.isUserInRole("1");
boolean r4 =request.isUserInRole("2");
logger.info("isUserInRole values:"+ r1 + " " + r2 + " " + r3 +" "+ r4);
if(request.isUserInRole("ADMIN")) {
logger.info("Admin check lefut!");
return "home";
}
logger.warn("Admin check nem fut let!");
return "game";
}
在我的默认控制器中-代表按角色重定向到指定页面-request.isUserInRole("ADMIN") 方法总是返回错误值...但是我的数据库中有具有 ADMIN 角色的用户并且日志也证明了我指定的用户已被授予管理员角色:
Principal u = request.getUserPrincipal();
logger.info("user principal:" + u.toString());
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String role = auth.getAuthorities().toString();
logger.info("Role:" + u.toString());
我的问题是,为什么这种方法不能通知 ADMIN 用户,我如何通过 jdbc 身份验证按角色重定向?
提前谢谢你
【问题讨论】:
-
我认为是最新的,spring security 4。大约一个月前,我用 spring initializr 创建了这个项目。
-
request.isUserInRole("USER") 将以 ROLE_ 为前缀。它将寻找 ROLE_USER。您在数据库中的角色是否以 ROLE_ 为前缀?
-
不,我没有这些前缀……我晚上试试。添加这个作为答案,如果它是解决方案,我会标记它。 :) 谢谢
标签: spring authentication spring-security roles