繁体   English   中英

使用spring-security-oauth2的SSO:永远不会读取身份验证代码

[英]SSO using spring-security-oauth2 : Authentication Code never read

使用:

  • 春季安全性3.2.5
  • 春季安全oauth 2.0.7

我有一个使用spring-security-oauth(oauth2)构建的可工作的oauth2提供程序。

我在其中配置了客户端以使用authorization_code授予类型。

该提供程序运行良好:使用curl进行测试,我可以获得授权码并将其交换为访问令牌。 因此,在服务提供商方面,一切都很好。

现在,我正在尝试使用spring-security-oauth实现客户端应用程序。 我使用的是xml配置,强烈基于此处的示例,但使用的是我自己的提供程序(上面已提及)而不是Google。

当我在客户端上调用受保护资源时, OAuth2ClientAuthenticationProcessingFilter尝试获取访问令牌,因此它将重定向到我的服务提供商。 这将迫使用户按预期方式登录,然后将其重定向到已配置的redirect_uri(重定向uri是为我的OAuth2ClientAuthenticationProcessingFilter配置的uri:类似http:// myClient / context / external / login )。 问题是: 客户端从不读取服务提供商返回的请求中的授权代码 因此, OAuth2ClientAuthenticationProcessingFilter重新启动该流程,要求输入授​​权码。

通过修改OAuth2ClientAuthenticationProcessingFilter来读取请求并在AccessTokenRequest设置授权代码,我已经能够使其工作。 这是代码段:

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用我自己的OAuth2ClientAuthenticationProcessingFilter替换。

有人使它起作用(在该版本或其他版本中)吗?

更新

永远不会调用setAuthorizationCode()方法(我最初的问题是错误)。 但是我进行了更多的挖掘,我意识到这不是问题。

我可以断言OAuth2ClientContextFilter是在OAuth2ClientAuthenticationProcessingFilter之前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')}");

这可以解释我的授权代码从未从请求中读取的问题。 我在最初的问题中提到的骇客只是将问题推后了。 现在,我得到csrf保护错误,因为当我假设一旦获得访问令牌就不再需要stateKey时, AccessTokenRequest stateKey记住一些stateKey

再说一次,也许我只是误会了这个空洞的想法,所以随时告诉我:)

我没有发布我的配置,因为它与此处的配置几乎相同。

您需要一个OAuth2ClientContextFilter ,它需要在身份验证处理过滤器之前触发(它基本上会执行您自定义过滤器中的工作)。 从您发布的代码中我无法分辨出您是否有一个,并且没有被触发,或者您没有一个。

对所有花费宝贵时间来帮助我的人表示抱歉。 我的调试是如此专注,以至于我错过了配置问题。 永远不要像这样配置Oauth2RestTemplate

<beans:bean id="myRestTemplate" class="org.springframework.security.oauth2.client.OAuth2RestTemplate">
     <beans:constructor-arg ref="myResourceId"/>
</beans:bean>

这就解释了为什么DefaultAccessTokenRequest不在请求范围内,因此调用了它的默认控制器,而不是一个接受请求的参数映射。 不要像我一样使用xml名称空间!

<oauth:rest-template id="myRestTemplate" resource="myResourceId"/>

仍然想知道为什么我这样做了:P

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM