验证成功后,Spring安全性的null上下文

时间:2014-09-15 12:37:06

标签: spring security

我面临一个有趣的问题。通过实施AuthenticationProvider

实施自定义提供程序

查看我的私有方法以获取安全上下文。当我使用SecurityContextHolder.getContext()时,我得到的是没有身份验证的空上下文对象,但是当我从会话中读取它时,它似乎正常工作(session.getAttribute(“SPRING_SECURITY_CONTEXT”))

  private SecurityContext getSecurityContext() throws ServiceException {
HttpServletRequest request =
    ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpSession session = request.getSession(false);
SecurityContext context = SecurityContextHolder.getContext();

if (context == null || context.getAuthentication() == null) {
  if (session == null) {
    throw new ServiceException(ErrorCode.INVALID_REQUEST, "User has not logged in");
  }
  context = (SecurityContext) session.getAttribute("SPRING_SECURITY_CONTEXT");
}
return context;// SecurityContextHolder.getContext();

当我调试代码时, SecurityContextPersistenceFilter 中的finally块被称为清空SecurityContextHolder。这导致创建并返回空的上下文对象(因此后续调用时身份验证令牌为空)。

finally {
        SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext();
        // Crucial removal of SecurityContextHolder contents - do this before anything else.
        **SecurityContextHolder.clearContext();**
        repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse());
        request.removeAttribute(FILTER_APPLIED);

        if (debug) {
            logger.debug("SecurityContextHolder now cleared, as request processing completed");
        }

看起来像SecurityContextPersistenceFilter过滤器应该在认证后执行实际身份验证之前执行,从而导致此错误行为。

你可以建议可能出现的问题吗?让我对此进行更多调查。

这也是我的配置

http
    .exceptionHandling()
        .accessDeniedHandler(getAccessDeniedHandler()).and()
    .exceptionHandling()
        .authenticationEntryPoint(authenticationEntryPoint).and()
    .formLogin()
        .failureUrl("/accessdenied").loginPage("/accessdenied").loginProcessingUrl("/login")
        .successHandler(loginSuccessHandler).failureHandler(loginFailedHandler)
        .usernameParameter("j_username").passwordParameter("j_password").and()
    .logout()
        .logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler)
        .deleteCookies("JSESSIONID").permitAll().and()
    .antMatcher("/login")
        .addFilterBefore(captchaFilter, UsernamePasswordAuthenticationFilter.class)
    .csrf().disable()
    .headers().frameOptions().disable()
    .authorizeRequests()
        .antMatchers("/logout").permitAll()
        .antMatchers("/login").permitAll()
        .antMatchers("/accessdenied").permitAll()
        .antMatchers("/master/countries").permitAll()
        .antMatchers("/master/languages").permitAll()
        .antMatchers("/captcha**").permitAll()
        .antMatchers("/page").permitAll()
        .antMatchers("/common/**").permitAll()
        .antMatchers("/member/registration").permitAll()
        .antMatchers("/ewallet**").authenticated()
        .antMatchers("/transfer**").authenticated()
        .antMatchers("/sales**").authenticated()
        .antMatchers("/products**").authenticated()
        .antMatchers("/events").authenticated()
        .antMatchers("/archives").authenticated()
        .antMatchers("/announcements").authenticated();

这是对的吗?或者需要进行任何更改。我想我在这里错过了一些东西。我想在登录过滤器工作之前使用验证码过滤器。

0 个答案:

没有答案