我在尝试配置一个场景时遇到麻烦,我希望在使用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。:如果这个问题听起来令人困惑,那就很抱歉。尽管英语不是我的第一语言,但这个问题很难解释。