本文介绍了重定向到访问令牌入口点OAuth令牌时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在重定向到访问令牌入口点/OAuth/Token时遇到了问题,下面将详细说明。因为我花了很多时间,所以希望有人能给我一些启发正在实施此操作。

此外,有趣的是,即使按照他们的说明,我也不能使用SoapUI5.0社区版进行测试。它修改了授权码,但后来失败了,因为您需要将重定向URI设置为"urn:ietf:wg:oauth:2.0:oob"。

由于Spring-Security-OAuth2缺少很多好的文档,我花了很多时间调试和记录我决定分享的工作我的注释和配置代码,可能对其他人也有帮助。

我在我的POM上使用以下依赖项版本:

<org.springframework-version>4.0.5.RELEASE</org.springframework-version>
<org.springframework.security-version>3.2.5.RELEASE</org.springframework.security-version>
<org.springframework.security.oauth2-version>2.0.3.RELEASE</org.springframework.security.oauth2-version>
现在,我们的想法是使用Cassandra作为持久性存储来实现所有的客户端ID对象、用户主体、访问、随机数和令牌存储。所有这些组件都工作得很好,并且经过了测试。事实上,它获取所有身份验证/授权,创建授权码。

我最近在测试Spring OAuth2 GitHub上的JDBC存储时看到了一个错误,但这与测试而不是实际实现有关,特别是因为使用JDBC。

我已经编写了一个客户端Web应用程序来访问驻留在OAuth2服务器和用于登录的Spring Security中的REST资源。一切都很顺利,直到我去请求/OAuth/Token的访问令牌。

当我首先启动安全REST服务时,它会正确地开始执行重定向,并执行Tru DefaultOAuth2RequestFactory createAuthorizationRequest()方法。负载量ClientDetail与商店的秘密等完美地结合在一起。因此,它拥有OAuth2客户端的所有作用域、授权等。它还正确地验证了redirectURIParameter并解决该重定向。然后,它转到TokenStoreUserApprovalHandler并创建OAuth2Request对象。然后,当然,尝试查找现有的访问令牌,该令牌在工作流程中尚不存在。它从authationKeyGenerator创建身份验证密钥,并查询存储,该存储此时正确地返回NULL。然后,当它第二次拥有授权码并在ApproveOrDeny()方法中标记为已批准(AuthorizationEndPoint)时,它将两次重定向回/OAuth/Authorize。AuthizationCodeServices创建代码并将其正确存储在我的Cassandra商店中。

此时它调用(AuthorizationEndPoint)getSuccessfulRedirect(),将状态参数添加到模板。

然后它调用(OAuth2RestTemplate类)getAccessToken()方法。由于访问令牌是正确有效的,因此它随后调用acquireAccessToken(),这将返回一个accessTokenRequest{code=[Q19Y6u], state=[1PyzHf]}。然后它调用accessTokenProvider以在obtainAccessToken()处获取访问令牌。然后调用OAuth2AccessTokenSupportretrieveToken()方法。并在getRestTemplate失败。AuthorizationCodeResourceDetails是用授权类型authorization_code完美创建的,它同时具有和clientAuthenticationScheme作为报头。clientIdclientSecret相同。AuthorizationCodeResourceDetails的id为oAuth2ClientBeanuserAuthorizationURI的id为http://myhost.com:8080/MyAPI/oauth/authorize。页眉显示为

{Authorization=[Basic .....]}

萃取器为org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport。表单为{grant_type=[authorization_code], code=[Xc7yni], redirect_uri=[http://myhost.com:8080/OAuthClient/support]}

然后应用程序冻结,并显示在日志中:

DEBUG: org.springframework.security.authentication.DefaultAuthenticationEventPublisher - No event was found for the exception org.springframework.security.authentication.InternalAuthenticationServiceException
DEBUG: org.springframework.security.web.authentication.www.BasicAuthenticationFilter - Authentication request for failed: org.springframework.security.authentication.InternalAuthenticationServiceException

然后我的客户端Web应用程序出现以下异常:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is error="access_denied", error_description="Error requesting access token."
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)

现在,我认为我在OAuth2和Spring Security的XML配置上有一些错误。因此,配置文件如下所示。

我确实有几个关于它的问题,所以首先是以下问题:

1)<oauth2:authorization-server>我不确定我的配置是否正确。请看我对我的XML文件的评论。我已经添加了AUTHORIZATION-REQUEST-MANAGER-REF参数,该参数指向我的用户身份验证管理器Bean,即身份验证管理器它接受身份验证提供者User-Service-ref="userService"

<oauth2:authorization-server client-details-service-ref="webServiceClientService" 
    token-services-ref="tokenServices" user-approval-page="/oauth/userapproval" 
    error-page="/oauth/error" authorization-endpoint-url="/oauth/authorize" 
    token-endpoint-url="/oauth/token" user-approval-handler-ref="userApprovalHandler" 
    redirect-resolver-ref="resolver">
    <oauth2:authorization-code
        authorization-code-services-ref="codes" />
    <oauth2:implicit/>
    <oauth2:refresh-token/>
    <oauth2:client-credentials/>
    <oauth2:password authentication-manager-ref="userAuthenticationManager"/>
    <!-- <oauth2:custom-grant token-granter-ref=""/> -->
</oauth2:authorization-server>

2)当"/OAuth/Token"被拦截时,使用身份验证管理器oauthClientAuthenticationManager。定义如下:

<sec:authentication-manager id="oauthClientAuthenticationManager">
    <sec:authentication-provider user-service-ref="clientDetailsUserService">
        <sec:password-encoder ref="passwordEncoder" />
    </sec:authentication-provider>
</sec:authentication-manager>
3)我定义了以下在sec中使用的方法SecurityExpressionHandler Bean:global-method-Security。也不确定这是否正确。

<beans:bean id="methodSecurityExpressionHandler"
        class="org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler" />

4)我还有一个Bean"clientCredentialsTokenEndpoint tFilter",我认为不推荐这样做。我将其用作入口点"/OAuth/Token"的定制过滤器,但我认为这是错误的。

<beans:bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
    <beans:property name="authenticationManager" ref="oauthClientAuthenticationManager"/>
</beans:bean>
A filter and authentication endpoint for the OAuth2 Token Endpoint. Allows clients to authenticate using request
parameters if included as a security filter, as permitted by the specification (but not recommended). It is
recommended by the specification that you permit HTTP basic authentication for clients, and not use this filter at
all.
5)现在用于OAuth令牌终端:这是端点/OAuth/内标识,因为我在这里有很多问题:

  1. 这永远达不到。
  2. 我是否应该使用类似clientCredentialsTokenEndpointFilter的自定义筛选器?
  3. 我必须有http-Basic入口点吗?
  4. 我应该像IS_AUTHENTICATED_FULLY中那样拥有访问属性,还是可以使用我在UserPrincipal对象上定义的权限,例如我在那里添加的OAUTH_CLIENT
  5. 会议怎么办?我应该说"无国籍"还是"从不"
  6. 是否也要添加corsFilter
  7. 入口点是否正确?OAuth2AuthenticationEntryPoint类是什么?
  8. 我必须添加CSRF令牌吗?我相信情况并非如此更多限制。
  9. 作为org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandle的表达式处理程序是否正确?
  10. 身份验证管理器-引用I可以从oauthClientAuthenticationManager更改为userAuthenticationManager

<sec:http use-expressions="true" create-session="stateless" authentication-manager-ref="userAuthenticationManager" entry-point-ref="oauthAuthenticationEntryPoint" pattern="/oauth/token"> <sec:intercept-url pattern="/oauth/token" access="hasAuthority('OAUTH_CLIENT')" /> <!-- <sec:intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" /> --> <sec:http-basic entry-point-ref="oauthAuthenticationEntryPoint"/> <!-- <sec:http-basic/> --> <sec:anonymous enabled="false" /> <sec:custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER" /> <sec:access-denied-handler ref="oauthAccessDeniedHandler" /> <sec:expression-handler ref="webSecurityExpressionHandler" /> <!-- <sec:custom-filter ref="corsFilter" after="LAST"/> --> </sec:http>

我想在此处添加完整的配置文件,但有限制。

推荐答案

/OAUTH/TOKEN终结点应该使用客户端凭据进行保护,并且看起来您将其连接到了用户身份验证管理器。您没有展示它的配置或实现,但是通过InternalAuthenticationServiceException判断它是失败的,异常不被归类为安全异常。解决了这两个问题,你就有可能成功了。

(顺便说一句,@Configuration样式要方便得多,我建议您开始使用它以及它提供的更多默认设置,直到您掌握它的诀窍为止。)

这篇关于重定向到访问令牌入口点OAuth令牌时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 14:09