【发布时间】:2015-04-14 22:54:13
【问题描述】:
使用:
- spring-security 3.2.5
- spring-security-oauth 2.0.7
我有一个使用 spring-security-oauth (oauth2) 构建的工作 oauth2 提供程序。
我已将我的客户端配置为使用 authorization_code 授权类型。
提供程序完美运行: 使用 curl 进行测试,我可以获得授权码并将其交换为访问令牌。 所以在服务提供商方面,一切都很好。
现在我正在尝试使用 spring-security-oauth 来实现客户端应用程序。 我正在使用 xml 配置,强烈基于示例 here,但使用我自己的提供程序(上面提到)而不是 google。
当我调用客户端上的受保护资源时,OAuth2ClientAuthenticationProcessingFilter 尝试获取访问令牌,因此它重定向到我的服务提供商。这会强制用户按预期登录,然后将他重定向到配置的redirect_uri(重定向uri 是为我的OAuth2ClientAuthenticationProcessingFilter 配置的:类似于http://myClient/context/external/login)。
问题是:客户端从未读取服务提供者返回的请求中的授权码。因此OAuth2ClientAuthenticationProcessingFilter 重新启动流程,要求提供授权码。
我已经能够通过修改OAuth2ClientAuthenticationProcessingFilter 来读取请求并在AccessTokenRequest 中设置授权码来使其工作。这是sn-p:
OAuth2AccessToken accessToken;
try {
String code = request.getParameter("code");
if(code != null) {
restTemplate.getOAuth2ClientContext().getAccessTokenRequest().setAuthorizationCode(code);
}
accessToken = restTemplate.getAccessToken();
...
在尝试此操作之前,我尝试在方法org.springframework.security.oauth2.client.token.AccessTokenRequest.setAuthorizationCode() 上创建“调用层次结构”,以查找代码中spring 确实调用该方法的位置,但它什么也没返回。
这是一个错误吗?
我真的不想用我自己的替换OAuth2ClientAuthenticationProcessingFilter。
是否有人让它工作(在那个版本或其他版本中)?
更新
这是从未调用过的 setAuthorizationCode() 方法(我最初的问题中有错误)。但我挖掘了更多,我意识到这不是问题。
我可以断言 OAuth2ClientContextFilter 在 OAuth2ClientAuthenticationProcessingFilter 之前被调用(我用调试器检查过)。
我发现了什么,但不知道是否正常:
DefaultAccessTokenRequest 的默认构造函数只调用一次:在应用程序启动时。永远不会调用另一个构造函数(获取参数映射的构造函数)。由于我在RestTemplateBeanDefinitionParser 中看到访问令牌请求的范围为“请求”,因此我希望在对我的客户端应用程序的每个新http 请求上调用带有参数映射的构造函数。
在RestTemplateBeanDefinitionParser:
BeanDefinitionBuilder request = BeanDefinitionBuilder.genericBeanDefinition(DefaultAccessTokenRequest.class);
request.setScope("request");
request.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
request.addConstructorArgValue("#{request.parameterMap}");
request.addPropertyValue("currentUri", "#{request.getAttribute('currentUri')}");
这可以解释我从未从请求中读取授权码的问题。我在最初的问题中提到的 hack 只是推迟了问题。现在我收到 csrf 保护错误,因为当我认为一旦获得访问令牌后,AccessTokenRequest 就不再需要它时,AccessTokenRequest 总是会记住一些 stateKey。
再次,也许我只是误解了洞的想法,所以请随时告诉我:)
我没有发布我的配置,因为它与that one here 非常相似。
【问题讨论】:
标签: java spring-security spring-security-oauth2