java - Spring 记得我没有使用自定义过滤器和 Java 配置

标签 java spring spring-mvc spring-security

我正在使用自定义身份验证过滤器来捕获 spring mvc 应用程序中的附加登录参数。我想启用记住我的功能,并且我正在使用 Java 配置。但是记住我功能不起作用。如果用户选中登录页面上的“记住我”复选框,我可以看到一个新条目已添加到 persistent_logins 表中。但是一旦 session 超时并且用户单击任何应用程序链接,他/她将被重定向到登录页面。请在下面找到相关代码,

CustomAuthenticationFilter.java:-

public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        final Long locationId = Long.parseLong(request.getParameter("locations"));
        request.getSession().setAttribute("LOCATION_ID", locationId);

        return super.attemptAuthentication(request, response); 
    } 
}

SecurityConfig.java:-

@Configuration
@EnableWebMvcSecurity
@ComponentScan(basePackageClasses=com.test.web.service.impl.UserServiceImpl.class)
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    DataSource dataSource;

    @Autowired
    private AuthenticationManagerBuilder auth;

    @Autowired
    public void configureGlobal(UserDetailsService userDetailsService, AuthenticationManagerBuilder auth) throws Exception {
        auth
        .userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

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

    @Autowired
    AccessDeniedExceptionHandler accessDeniedExceptionHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .authorizeRequests()
        .antMatchers("/resources/**").permitAll()
        .antMatchers("/error/**").permitAll()
        .antMatchers("/secured/**").hasRole("ADMIN")
        .anyRequest().authenticated()
        .and()
        .formLogin()
        .loginPage("/login")
        .permitAll()
        .and()
        .logout()
        .permitAll()
        .and()
        .exceptionHandling()
        .accessDeniedHandler(accessDeniedExceptionHandler);

        http.addFilterBefore(customAuthenticationFilter(),
                UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() {
        AuthenticationManager manager = null;
        try {
            manager = super.authenticationManagerBean();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return manager;
    }


    @Bean
    public SimpleUrlAuthenticationSuccessHandler simpleUrlAuthenticationSuccessHandler() {
        SimpleUrlAuthenticationSuccessHandler handler = new SimpleUrlAuthenticationSuccessHandler();
        handler.setDefaultTargetUrl("/");
        return handler;
    }

    @Bean
    public SimpleUrlAuthenticationFailureHandler simpleUrlAuthenticationFailureHandler() {
        SimpleUrlAuthenticationFailureHandler handler = new SimpleUrlAuthenticationFailureHandler();
        handler.setDefaultFailureUrl("/login?error");
        return handler;
    }

    @Bean
    public CustomAuthenticationFilter customAuthenticationFilter () {
        CustomAuthenticationFilter filter= new  CustomAuthenticationFilter();
        filter.setRequiresAuthenticationRequestMatcher(
                new AntPathRequestMatcher("/login","POST"));
        filter.setAuthenticationManager(authenticationManagerBean());
        filter.setUsernameParameter("username");
        filter.setPasswordParameter("password");
        filter.setAuthenticationSuccessHandler(simpleUrlAuthenticationSuccessHandler());
        filter.setAuthenticationFailureHandler(simpleUrlAuthenticationFailureHandler());
        filter.setRememberMeServices(persistentTokenBasedRememberMeServices());
        return filter;
    }


    @Bean
    public PersistentTokenBasedRememberMeServices persistentTokenBasedRememberMeServices() {
        PersistentTokenBasedRememberMeServices service = new PersistentTokenBasedRememberMeServices("remember_me_key", userDetailsService, persistentTokenRepository());
        service.setCookieName("remember_me");
        service.setTokenValiditySeconds(864000);
        return service;
    }

    @Autowired
    public UserDetailsService userDetailsService;

    @Bean
    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl tokenRepositoryImpl = new JdbcTokenRepositoryImpl();
        tokenRepositoryImpl.setDataSource(dataSource);
        return tokenRepositoryImpl;
    }
}

如果有人能指出正确的方向,我将非常感激。

更新:-

在 session 过期时单击任何应用程序链接后,我在日志中看到以下输出。从日志看来,RememberMeAuthenticationFilter 似乎没有被解雇。

2016-02-22 19:22:12 DEBUG FilterChainProxy:337 - / at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-02-22 19:22:12 DEBUG FilterChainProxy:337 - / at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-02-22 19:22:12 DEBUG HttpSessionSecurityContextRepository:136 - No HttpSession currently exists
2016-02-22 19:22:12 DEBUG HttpSessionSecurityContextRepository:90 - No SecurityContext was available from the HttpSession: null. A new one will be created.
2016-02-22 19:22:12 DEBUG FilterChainProxy:337 - / at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-02-22 19:22:12 DEBUG HstsHeaderWriter:129 - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@36fb061c
2016-02-22 19:22:12 DEBUG FilterChainProxy:337 - / at position 4 of 13 in additional filter chain; firing Filter: 'CsrfFilter'
2016-02-22 19:22:12 DEBUG FilterChainProxy:337 - / at position 5 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2016-02-22 19:22:12 DEBUG AntPathRequestMatcher:127 - Request 'GET /' doesn't match 'POST /logout
2016-02-22 19:22:12 DEBUG FilterChainProxy:337 - / at position 6 of 13 in additional filter chain; firing Filter: 'CustomAuthenticationFilter'
2016-02-22 19:22:12 DEBUG AntPathRequestMatcher:127 - Request 'GET /' doesn't match 'POST /login
2016-02-22 19:22:12 DEBUG FilterChainProxy:337 - / at position 7 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2016-02-22 19:22:12 DEBUG AntPathRequestMatcher:127 - Request 'GET /' doesn't match 'POST /login
2016-02-22 19:22:12 DEBUG FilterChainProxy:337 - / at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2016-02-22 19:22:12 DEBUG FilterChainProxy:337 - / at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2016-02-22 19:22:12 DEBUG FilterChainProxy:337 - / at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2016-02-22 19:22:12 DEBUG AnonymousAuthenticationFilter:102 - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
2016-02-22 19:22:12 DEBUG FilterChainProxy:337 - / at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
2016-02-22 19:22:12 DEBUG SessionManagementFilter:92 - Requested session ID 87ABB37D528FC51FFC5C47A717813C79 is invalid.
2016-02-22 19:22:12 DEBUG FilterChainProxy:337 - / at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2016-02-22 19:22:12 DEBUG FilterChainProxy:337 - / at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2016-02-22 19:22:12 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/'; against '/logout'
2016-02-22 19:22:12 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/'; against '/resources/**'
2016-02-22 19:22:12 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/'; against '/error/**'
2016-02-22 19:22:12 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/'; against '/secured/**'
2016-02-22 19:22:12 DEBUG FilterSecurityInterceptor:194 - Secure object: FilterInvocation: URL: /; Attributes: [authenticated]
2016-02-22 19:22:12 DEBUG FilterSecurityInterceptor:310 - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
2016-02-22 19:22:12 DEBUG AffirmativeBased:65 - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@732b4495, returned: -1
2016-02-22 19:22:12 TRACE AnnotationConfigWebApplicationContext:331 - Publishing event in Root WebApplicationContext: org.springframework.security.access.event.AuthorizationFailureEvent[source=FilterInvocation: URL: /]
2016-02-22 19:22:12 DEBUG ExceptionTranslationFilter:165 - Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied

更新 2:-

添加 rememberMe() 调用后,RememberMeAuthenticationFilter 被调用,但 remember-me 功能仍无法使用与之前相同的行为。最新的日志是,

2016-02-22 20:00:08 DEBUG FilterChainProxy:337 - / at position 1 of 14 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2016-02-22 20:00:08 DEBUG FilterChainProxy:337 - / at position 2 of 14 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2016-02-22 20:00:08 DEBUG HttpSessionSecurityContextRepository:136 - No HttpSession currently exists
2016-02-22 20:00:08 DEBUG HttpSessionSecurityContextRepository:90 - No SecurityContext was available from the HttpSession: null. A new one will be created.
2016-02-22 20:00:08 DEBUG FilterChainProxy:337 - / at position 3 of 14 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2016-02-22 20:00:08 DEBUG HstsHeaderWriter:129 - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@1c6103c2
2016-02-22 20:00:08 DEBUG FilterChainProxy:337 - / at position 4 of 14 in additional filter chain; firing Filter: 'CsrfFilter'
2016-02-22 20:00:08 DEBUG FilterChainProxy:337 - / at position 5 of 14 in additional filter chain; firing Filter: 'LogoutFilter'
2016-02-22 20:00:08 DEBUG AntPathRequestMatcher:127 - Request 'GET /' doesn't match 'POST /logout
2016-02-22 20:00:08 DEBUG FilterChainProxy:337 - / at position 6 of 14 in additional filter chain; firing Filter: 'CustomAuthenticationFilter'
2016-02-22 20:00:08 DEBUG AntPathRequestMatcher:127 - Request 'GET /' doesn't match 'POST /login
2016-02-22 20:00:08 DEBUG FilterChainProxy:337 - / at position 7 of 14 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2016-02-22 20:00:08 DEBUG AntPathRequestMatcher:127 - Request 'GET /' doesn't match 'POST /login
2016-02-22 20:00:08 DEBUG FilterChainProxy:337 - / at position 8 of 14 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2016-02-22 20:00:08 DEBUG FilterChainProxy:337 - / at position 9 of 14 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2016-02-22 20:00:08 DEBUG FilterChainProxy:337 - / at position 10 of 14 in additional filter chain; firing Filter: 'RememberMeAuthenticationFilter'
2016-02-22 20:00:08 DEBUG FilterChainProxy:337 - / at position 11 of 14 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2016-02-22 20:00:08 DEBUG AnonymousAuthenticationFilter:102 - Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS'
2016-02-22 20:00:08 DEBUG FilterChainProxy:337 - / at position 12 of 14 in additional filter chain; firing Filter: 'SessionManagementFilter'
2016-02-22 20:00:08 DEBUG SessionManagementFilter:92 - Requested session ID 0C8F3CE7D018DA453CDD9E23A8125212 is invalid.
2016-02-22 20:00:08 DEBUG FilterChainProxy:337 - / at position 13 of 14 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2016-02-22 20:00:08 DEBUG FilterChainProxy:337 - / at position 14 of 14 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2016-02-22 20:00:08 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/'; against '/logout'
2016-02-22 20:00:08 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/'; against '/resources/**'
2016-02-22 20:00:08 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/'; against '/error/**'
2016-02-22 20:00:08 DEBUG AntPathRequestMatcher:145 - Checking match of request : '/'; against '/secured/**'
2016-02-22 20:00:08 DEBUG FilterSecurityInterceptor:194 - Secure object: FilterInvocation: URL: /; Attributes: [authenticated]
2016-02-22 20:00:08 DEBUG FilterSecurityInterceptor:310 - Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS
2016-02-22 20:00:08 DEBUG AffirmativeBased:65 - Voter: org.springframework.security.web.access.expression.WebExpressionVoter@3c682cd2, returned: -1
2016-02-22 20:00:08 TRACE AnnotationConfigWebApplicationContext:331 - Publishing event in Root WebApplicationContext: org.springframework.security.access.event.AuthorizationFailureEvent[source=FilterInvocation: URL: /]
2016-02-22 20:00:08 DEBUG ExceptionTranslationFilter:165 - Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied  

最佳答案

看起来 remember 在 configure() 中没有启用; 参见例子

http://docs.spring.io/spring-security/site/docs/3.2.x/apidocs/org/springframework/security/config/annotation/web/builders/HttpSecurity.html#rememberMe()

你需要做的

.formLogin()
        .loginPage("/login")
        .permitAll()
        .and()
        .rememberMe()
        .rememberMeServices(persistentTokenBasedRememberMeServices());

关于java - Spring 记得我没有使用自定义过滤器和 Java 配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35551623/

相关文章:

java - 字符串和运行时错误。 (颠倒字符串中字符顺序的程序)

java - 将数据从 Activity 传递到可滑动 View fragment

java - Spring DispatcherServlet 与图像 Servlet 配置

java - 断言集合不包含项目

java - 从命令行编译 vaadin widgetset

java - JQuery AutoComplete 与 Spring MVC 返回列表,但未过滤

java - Mockito等待新线程的方法执行多次

java - Spring 安全: Add custom message for authentication failure ( "Bad Credentials" to "Invalid Credentials")

java - 使用正确的编码通过ajax将西里尔字符串从jsp发送到java类

java - 创建 Map 并将其传递给请求范围的属性