2015-04-10 7 views
7

gesetzt Token wird ich ein Problem mit meinem erinnere mich Konfiguration bin Begegnung:Problem mit Spring Security erinnere mich nicht auf SecurityContextHolder

[nio-8080-exec-8] s.s.w.a.r.RememberMeAuthenticationFilter : SecurityContextHolder not populated with remember-me token, as it already contained: 'org.springframew[email protected]73939efa: Principal: Member ... 

Hier meine Frühling Sicherheitskonfiguration ist:

@Configuration 
@EnableWebSecurity 
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private MemberUserDetailsService memberUserDetailsService; 

    @Autowired 
    private BCryptPasswordEncoder passwordEncoder; 

    @Autowired 
    private AccessDecisionManager accessDecisionManager; 

    @Autowired 
    private ApplicationEventPublisher eventPublisher; 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     //@formatter:off 
     http 
     .headers() 
     .cacheControl() 
      .and() 
     .and() 
     .csrf() 
     .csrfTokenRepository(csrfTokenRepository()) 
     .and() 
     .rememberMe() 
     .tokenValiditySeconds(60*60*24*7) 
     .and() 
      .exceptionHandling() 
      .accessDeniedHandler(accessDeniedHandler()) 
     .and() 
      .formLogin() 
      .loginProcessingUrl("/api/signin") 
      .failureHandler(authenticationFailureHandler()) 
      .successHandler(authenticationSuccessHandler()) 
     .and() 
      .logout() 
      .logoutRequestMatcher(new AntPathRequestMatcher("/api/signout")) 
      .logoutSuccessHandler(logoutSuccessHandler()) 
     .and() 
      .addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class) 
      .authorizeRequests() 
       .accessDecisionManager(accessDecisionManager) 
       .antMatchers("/resources/**", "/**").permitAll() 
       .anyRequest().authenticated(); 
     //@formatter:on 
    } 

    private LogoutSuccessHandler logoutSuccessHandler() { 
     return new LogoutSuccessHandler() { 
      @Override 
      public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { 
       response.setStatus(HttpStatus.OK.value()); 
      } 
     }; 
    } 

    private AccessDeniedHandler accessDeniedHandler() { 
     return new AccessDeniedHandler() { 
      @Override 
      public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { 
       // TODO: deal with InvalidCsrfTokenException 
       response.setStatus(HttpStatus.FORBIDDEN.value()); 
      } 
     }; 
    } 

    private AuthenticationFailureHandler authenticationFailureHandler() { 
     return new AuthenticationFailureHandler() { 
      @Override 
      public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { 
       response.setStatus(HttpStatus.UNAUTHORIZED.value()); 
      } 
     }; 
    } 

    private AuthenticationSuccessHandler authenticationSuccessHandler() { 
     return new AuthenticationSuccessHandler() { 
      @Override 
      public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { 
       Member member = (Member) authentication.getPrincipal(); 
       eventPublisher.publishEvent(new SigninApplicationEvent(member)); 
       // TODO: overhaul below 
       response.addHeader("MEMBER_ROLE", member.getRole().name()); 
       response.setStatus(HttpStatus.OK.value()); 
      } 
     }; 
    } 

    @Bean 
    @Override 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
     return super.authenticationManagerBean(); 
    } 

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.userDetailsService(memberUserDetailsService).passwordEncoder(passwordEncoder); 
    } 

    private CsrfTokenRepository csrfTokenRepository() { 
     HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository(); 
     repository.setHeaderName("X-XSRF-TOKEN"); 
     return repository; 
    } 
} 

und auch:

@Configuration 
@EnableGlobalMethodSecurity(prePostEnabled = true) 
public class CoreSecurityConfiguration { 

    @Bean 
    public MemberUserDetailsService memberUserDetailsService() { 
     return new MemberUserDetailsService(); 
    } 

    @Bean 
    public BCryptPasswordEncoder passwordEncoder() { 
     BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); 
     return passwordEncoder; 
    } 

    @Bean 
    public SessionRegistryImpl sessionRegistry() { 
     SessionRegistryImpl sessionRegistry = new SessionRegistryImpl(); 
     return sessionRegistry; 
    } 

    @Bean 
    public AffirmativeBased accessDecisionManager() { 
     AffirmativeBased accessDecisionManager = new AffirmativeBased(accessDecisionVoters()); 
     return accessDecisionManager; 
    } 

    private List<AccessDecisionVoter<? extends Object>> accessDecisionVoters() { 
     List<AccessDecisionVoter<? extends Object>> accessDecisionVoters = new ArrayList<>(); 
     accessDecisionVoters.add(roleHierarchyVoter()); 
     accessDecisionVoters.add(webExpressionVoter()); 
     return accessDecisionVoters; 
    } 

    @Bean 
    public WebExpressionVoter webExpressionVoter() { 
     WebExpressionVoter webExpressionVoter = new WebExpressionVoter(); 
     webExpressionVoter.setExpressionHandler(defaultWebSecurityExpressionHandler()); 
     return webExpressionVoter; 
    } 

    @Bean 
    public DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler() { 
     DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler = new DefaultWebSecurityExpressionHandler(); 
     defaultWebSecurityExpressionHandler.setRoleHierarchy(roleHierarchy()); 
     return defaultWebSecurityExpressionHandler; 
    } 

    @Bean 
    public RoleHierarchyVoter roleHierarchyVoter() { 
     RoleHierarchyVoter roleHierarchyVoter = new RoleHierarchyVoter(roleHierarchy()); 
     return roleHierarchyVoter; 
    } 

    @Bean 
    public RoleHierarchyImpl roleHierarchy() { 
     RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl(); 
     //@formatter:off 
     roleHierarchy.setHierarchy(
       "ROLE_ADMINISTRATOR > ROLE_MODERATOR\n" + 
       "ROLE_MODERATOR > ROLE_SUBSCRIBED_PARENTS\n" + 
       "ROLE_MODERATOR > ROLE_SUBSCRIBED_CHILDCARE_WORKER\n" + 
       "ROLE_SUBSCRIBED_PARENTS > ROLE_BASIC_PARENTS\n" + 
       "ROLE_SUBSCRIBED_CHILDCARE_WORKER > ROLE_BASIC_CHILDCARE_WORKER"); 
     //@formatter:on 
     return roleHierarchy; 
    } 

} 

Kann somemone bitte helfen?

bearbeiten 1:

MemberUserDetailsService:

@Component 
public class MemberUserDetailsService implements UserDetailsService { 

    @Autowired 
    private MemberRepository memberRepository; 

    @Override 
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { 
     Member member = memberRepository.findByEmail(email); 
     if (member == null) { 
      throw new UsernameNotFoundException("Username: " + email + " not found!"); 
     } 
     return member; 
    } 

} 

bearbeiten 2: Hier ist die neue config:

@Configuration 
@EnableWebSecurity 
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { 

    @Autowired 
    private MemberUserDetailsService memberUserDetailsService; 

    @Autowired 
    private BCryptPasswordEncoder passwordEncoder; 

    @Autowired 
    private AccessDecisionManager accessDecisionManager; 

    @Autowired 
    private ApplicationEventPublisher eventPublisher; 

    @Autowired 
    private CsrfTokenRepository csrfTokenRepository; 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     //@formatter:off 
     http 
     .headers() 
     .cacheControl() 
      .and() 
     .and() 
     .csrf() 
     .csrfTokenRepository(csrfTokenRepository()) 
     .and() 
     .rememberMe() 
     .key("myKey") 
     .tokenValiditySeconds(60*60*24*7) 
     .userDetailsService(memberUserDetailsService) 
     .and() 
      .exceptionHandling() 
      .accessDeniedHandler(accessDeniedHandler()) 
     .and() 
      .formLogin() 
      .loginProcessingUrl("/api/signin") 
      .failureHandler(authenticationFailureHandler()) 
      .successHandler(authenticationSuccessHandler()) 
     .and() 
      .logout() 
      .logoutRequestMatcher(new AntPathRequestMatcher("/api/signout")) 
      .logoutSuccessHandler(logoutSuccessHandler()) 
     .and() 
      .addFilter(usernamePasswordAuthenticationFilter()) 
      .addFilter(rememberMeAuthenticationFilter()) 
      .addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class) 
      .authorizeRequests() 
       .accessDecisionManager(accessDecisionManager) 
       .antMatchers("/resources/**", "/**").permitAll() 
       .anyRequest().authenticated(); 
     //@formatter:on 
    } 

    private LogoutSuccessHandler logoutSuccessHandler() { 
     return new LogoutSuccessHandler() { 
      @Override 
      public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { 
       response.setStatus(HttpStatus.OK.value()); 
      } 
     }; 
    } 

    private AccessDeniedHandler accessDeniedHandler() { 
     return new AccessDeniedHandler() { 
      @Override 
      public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException { 
       // TODO: deal with InvalidCsrfTokenException & MissingCsrfTokenException 
       response.setStatus(HttpStatus.FORBIDDEN.value()); 
      } 
     }; 
    } 

    private AuthenticationFailureHandler authenticationFailureHandler() { 
     return new AuthenticationFailureHandler() { 
      @Override 
      public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { 
       response.setStatus(HttpStatus.UNAUTHORIZED.value()); 
      } 
     }; 
    } 

    private AuthenticationSuccessHandler authenticationSuccessHandler() { 
     return new AuthenticationSuccessHandler() { 
      @Override 
      public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { 
       response.setStatus(HttpStatus.OK.value()); 
       Member member = (Member) authentication.getPrincipal(); 
       eventPublisher.publishEvent(new SigninApplicationEvent(member)); 
       response.setStatus(HttpStatus.OK.value()); 
       // TODO: overhaul below 
       response.addHeader("MEMBER_ROLE", member.getRole().name()); 
      } 
     }; 
    } 

    @Bean 
    @Override 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
     return super.authenticationManagerBean(); 
    } 

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     auth.authenticationProvider(rememberMeAuthenticationProvider()).userDetailsService(memberUserDetailsService).passwordEncoder(passwordEncoder); 
    } 

    @Bean 
    protected CsrfTokenRepository csrfTokenRepository() { 
     HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository(); 
     repository.setHeaderName("X-XSRF-TOKEN"); 
     return repository; 
    } 

    @Bean 
    public RememberMeAuthenticationProvider rememberMeAuthenticationProvider() { 
     return new RememberMeAuthenticationProvider("myKey"); 
    } 

    @Bean 
    public RememberMeServices rememberMeServices() { 
     return new TokenBasedRememberMeServices("myKey", memberUserDetailsService); 
    } 

    @Bean 
    public RememberMeAuthenticationFilter rememberMeAuthenticationFilter() throws Exception { 
     return new RememberMeAuthenticationFilter(authenticationManager(), rememberMeServices()); 
    } 

    @Bean 
    public UsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter() throws Exception { 
     UsernamePasswordAuthenticationFilter filter = new UsernamePasswordAuthenticationFilter(); 
     filter.setRememberMeServices(rememberMeServices()); 
     filter.setAuthenticationManager(authenticationManager()); 
     return filter; 
    } 

} 
+0

die Schritte Geben Sie bitte die zu diesem Thema geführt. – Mithun

+0

Die Schritte, die zu dem Problem führen, sind nur ein Sicherheits-Login für Frühling. – balteo

+0

Bitte teilen Sie den Code für 'MemberUserDetailsService' ebenfalls mit. – Mithun

Antwort

3

Da Sie nicht erinnern-me-Service angegeben haben Implementierungstyp, TokenBasedRememberMeServices wird standardmäßig verwendet.

Sie finden den Hinweis unten aus der Dokumentation, wenn TokenBasedRememberMeServices mit:

nicht Vergessen Sie Ihre RememberMeServices Implementierung auf Ihre UsernamePasswordAuthenticationFilter.setRememberMeServices() Eigenschaft hinzufügen, umfassen die RememberMeAuthenticationProvider in Ihrer AuthenticationManager.setProviders() Liste, und fügen Sie RememberMeAuthenticationFilter in Ihre FilterChainProxy (typischerweise sofort nach UsernamePasswordAuthenticationFilter)

Sie müssen die folgenden Änderungen vorzunehmen:

  1. In configure() Methode Sie

    http.rememberMe().key("yourKey")

    .addFilter(usernamePasswordAuthenticationFilter()) .addFilter(rememberMeAuthenticationFilter())

  2. erstellen UsernamePasswordAuthenticationFilter und RememberMeAuthenticationFilter

    einen Schlüssel und Filter hinzufügen müssen
    @Bean 
    public UsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter() 
           throws Exception { 
        UsernamePasswordAuthenticationFilter filter = 
           new UsernamePasswordAuthenticationFilter(); 
        filter.setRememberMeServices(memberUserDetailsService);  
        filter.setAuthenticationManager(authenticationManager()); 
        return filter; 
    } 
    
    @Bean 
    public RememberMeAuthenticationFilter rememberMeAuthenticationFilter() 
            throws Exception { 
        RememberMeAuthenticationFilter filter = 
          new RememberMeAuthenticationFilter(authenticationManager(), memberUserDetailsService); 
        return filter; 
    } 
    
  3. RememberMeAuthenticationProvider in die Liste der Anbieter hinzufügen:

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) 
        throws Exception {    
        auth.userDetailsService(memberUserDetailsService) 
         .passwordEncoder(passwordEncoder) 
         .and() 
         .authenticationProvider(new RememberMeAuthenticationProvider("yourKey")); 
    } 
    
+0

Danke für Ihre Eingabe. Ich habe den bereitgestellten Code ausprobiert. Es hat jedoch zwei Fehler: in 'Filter.setRememberMeServices (memberUserDetailsService); '&' new RememberMeAuthenticationFilter (authenticationManager(), memberUserDetailsService); '** memberUserDetailsService ** sollte ** rememberMeServices ** sein? – balteo

+0

Es scheint leider nicht zu funktionieren. Ich bearbeite meinen Beitrag, um die genauen Änderungen widerzuspiegeln. Was ist mit Filterreihenfolge? Ist es wichtig? – balteo

+0

Vielen Dank für die Korrekturen. In Bezug auf die Reihenfolge der Filter sollte "UsernamePasswordAuthenticationFilter" in der Filterkette vor "RememberMeAuthenticationFilter" stehen, was in der Konfiguration bereits beachtet wurde. Nur noch eine Änderung, nicht sicher, ob es funktioniert, können Sie 'CsrfHeaderFilter' entfernen und versuchen. – Mithun

Verwandte Themen