2017-04-05 57 views
-1

我正在學習Spring Security。我製作了一個基於github骨架項目的標準登錄和註冊頁面。只要我只在數據庫中使用了一個角色,我就可以輕鬆地通過我獲得的角色來管理默認成功url。但現在我想添加兩個基於ADMIN和USER角色的默認網址。 我在這裏讀到這個determine target url based on roles in spring security 3.1答案,我試圖實現它,但isUserInRole()方法總是返回一個錯誤的值。我正在使用jdbc身份驗證。重定向到基於角色的控制器中的url使用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")方法始終以假值返回...但是,我h在我的數據庫管理員角色和日誌AVE用戶也證明了我指定的用戶管理員角色授予:

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身份驗證按角色重定向?

謝謝您提前

+0

最新的一個,我相信,春季安全4.我創建春天項目initializr大約一個月前。 – F3R1

+0

request.isUserInRole(「USER」)將以ROLE_開頭。它會查找ROLE_USER。您的數據庫中的角色是否以ROLE_爲前綴? – jmw5598

+1

不,我沒有這些前綴...我會在晚上嘗試。添加這個作爲答案,我會標記它,如果這是解決方案。 :) 謝謝 – F3R1

回答

0

Spring安全爲ROLE_賦予角色前綴。代碼request.isUserInRole("USER")將尋找ROLE_USER。如果您的數據庫中的角色也沒有作爲前綴,那麼它們不會相同。

您還可以在configure(HttpSecurity http)方法中設置Spring Security使用的前綴。

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
     .servletApi().rolePrefix("MY_ROLE_PREFIX_"); 
} 

http://docs.spring.io/spring-security/site/docs/current/apidocs/org/springframework/security/config/annotation/web/builders/HttpSecurity.html

相關問題