Spring会话 - 在配置HeaderHttpSessionStrategy

时间:2016-07-08 09:12:28

标签: java spring-security spring-boot spring-session

我在尝试配置一个场景时遇到麻烦,我希望在使用HttpSession时,Spring Security / Spring Session的集合传播Header而不是Cookie。基本上,我的配置是这样的:

@Configuration
@EnableRedisHttpSession
public class RedisHttpSessionTimeoutConfiguration {

    // ... some code here

    @Bean
    public HttpSessionStrategy httpSessionStrategy(){
        return new HeaderHttpSessionStrategy();
    }
}

除此之外,我还使用OAuth2来管理身份验证,我的最终Spring启动看起来像:

// some annotations such as @EnableDiscoveryClient / @EnableZuulProxy
@SpringBootApplication
@Import(RedisHttpSessionTimeoutConfiguration.class)
public class Application extends AbstractHttpSessionApplicationInitializer {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Component
    @EnableOAuth2Sso
    public static class OAuth2WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/**")
              .authorizeRequests()
              .anyRequest().authenticated()

            .and().csrf().csrfTokenRepository(getCSRFTokenRepository())
            .and().addFilterAfter(createCSRFHeaderFilter(), CsrfFilter.class);

        }

        private Filter createCSRFHeaderFilter() {
            return new OncePerRequestFilter() {
                @Override
                protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
                    CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
                    if (csrf != null) {
                        Cookie cookie = WebUtils.getCookie(request, RequiredCookieAndHeaders.CSRF);
                        String token = csrf.getToken();
                        if (cookie == null || token != null && !token.equals(cookie.getValue())) {
                            cookie = new Cookie(RequiredCookieAndHeaders.CSRF, token);
                            cookie.setPath("/");
                            response.addCookie(cookie);
                        }
                    }
                    filterChain.doFilter(request, response);
                }
            };
        }

        private CsrfTokenRepository getCSRFTokenRepository() {
            HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
            repository.setHeaderName(RequiredCookieAndHeaders.CSRF_ANGULAR_HEADER_NAME);

            return repository;
        }
//some more code
}

发生的情况是,如果我评论返回bean的配置返回新的HeaderHttpSessionStrategy(); 我的代码可以工作,我可以成功验证。但是,如果我保留此代码,由于某些未知原因(至少对我来说)我得到 OAuth2ClientAuthenticationProcessingFilter:身份验证请求失败:org.springframework.security.authentication.BadCredentialsException:无法获取访问令牌

调试两个代码(启用和不启用HeaderHttpSession)我意识到在这个方法org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.getParametersForTokenRequest(...)代码尝试时会出现问题恢复一个savedState(request.getPreservedState()) - 它会在设置Header时产生null。

有人有线索吗?

从此处编辑

只是为了补充我的描述 - 我的OAuth流程是什么:重定向到我有一个授权端点的OpenAM端点。一切正常后,此授权将重定向到/ login。它是,我不控制这个OpenAM服务器传播的内容。更多信息,我的application.yml:

...

security:
  oauth2:
    sso:
      loginPath: /login

    client:
      accessTokenUri: http://${authserver.hostname}:${authserver.port}/${authserver.contextPath}/oauth2/access_token
      userAuthorizationUri: http://${authserver.hostname}:${authserver.port}/${authserver.contextPath}/oauth2/authorize
      clientId: poc-x
      clientSecret: poc-x-pass
      clientAuthenticationScheme: header
      scope: api
...

P.S。:如果这个问题听起来令人困惑,那就很抱歉。尽管英语不是我的第一语言,但这个问题很难解释。

0 个答案:

没有答案