我遇到了重定向访问令牌入口点/ oauth /令牌的问题,这些问题将详细说明。我希望有人可以给我一些启发,因为我花了很多时间 实施这个。
另外,有趣的是,即使按照他们的指示,我也无法使用SoapUI 5.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作为持久性存储来实现所有clientId对象,UserPrincipal,访问,nonce和令牌存储。所有这些组件 正在完美地工作并经过测试。实际上,它会获取所有身份验证/授权,并创建授权码。
我最近看到一个关于在Spring Oauth2 github上测试JDBC存储的错误,但这与测试不是实际的实现有关,特别是因为没有 使用JDBC。
我已经编写了一个客户端webapplication来访问一个REST资源,该资源位于OAuth2服务器和Spring Security之间,用于登录。一切顺利,直到我请求 访问令牌到/ oauth / token。
当我首先点击安全Rest服务时,它正确地开始进行重定向,并且使用默认的PriorityOAuth2RequestFactory createAuthorizationRequest()方法。加载 ClientDetails与商店中的秘密等完美对象。所以它拥有Oauth2客户端的所有范围,授权等。它还可以正确验证redirectURIParameter 并解决重定向问题。然后转到TokenStoreUserApprovalHandler并创建OAuth2Request对象。然后,当然,尝试找到一个现有的访问令牌 在工作流程上尚不存在。它从authenticationKeyGenerator创建authenticationkey,并查询此时正确返回null的存储。 然后它在第二次有授权代码时重定向回/ oauth / authorize两次,并在approveOrDeny()方法中标记为已批准(AuthorizationEndPoint)。 authorizationCodeServices创建代码并将其正确存储在我的Cassandra商店中。
此时它会调用(AuthorizationEndPoint
)getSuccessfulRedirect()
,并将状态参数添加到模板中。
然后调用(OAuth2RestTemplate
class)getAccessToken()
方法。由于访问令牌很好并且有效,因此调用acquireAccessToken()
并返回accessTokenRequest
{code=[Q19Y6u], state=[1PyzHf]}
。然后它调用accessTokenProvider
以获取obtainAccessToken()
处的访问令牌。然后调用OAuth2AccessTokenSupport
来调用
retrieveToken()
方法。并在getRestTemplate
失败。 AuthorizationCodeResourceDetails
与授权类型authorization_code
完美匹配,并且authorizationScheme
都有clientAuthenticationScheme
和clientId
作为标题。 clientSecret
与AuthorizationCodeResourceDetails
一样正确。 oAuth2ClientBean
的ID为userAuthorizationURI
,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
然后应用程序冻结并显示在日志中:
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)
然后我的客户端Web应用程序出现以下异常:
<oauth2:authorization-server>
现在,我相信我的OAuth2和Spring Security的xml配置有些问题。所以配置文件如下。
我确实有几个问题,所以首先是问题:
1)<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>
我不确定我是否正确配置了此配置。请查看我在xml文件中的注释。
我添加了authorization-request-manager-ref参数,该参数指向我的userAuthenticationManager bean,一个身份验证管理器
它采用身份验证提供者user-service-ref =&#34; userService&#34;
<sec:authentication-manager id="oauthClientAuthenticationManager">
<sec:authentication-provider user-service-ref="clientDetailsUserService">
<sec:password-encoder ref="passwordEncoder" />
</sec:authentication-provider>
</sec:authentication-manager>
2)authentication&manager oauthClientAuthenticationManager用于&#34; / oauth / token&#34;被截获。 其定义如下:
<beans:bean id="methodSecurityExpressionHandler"
class="org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler" />
3)我定义了以下methodSecurityExpressionHandler bean,它在sec:global-method-security中使用。 不确定这是否正确。
<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.
4)我还有一个bean&#34; clientCredentialsTokenEndpointFilter&#34;我相信不推荐。 我使用它作为入口点的自定义过滤器&#34; / oauth / token&#34;但我相信这是错误的。
clientCredentialsTokenEndpointFilter
5)现在为Oauth令牌端点: 这是端点/ oauth / token,因为我在这里有很多问题:
IS_AUTHENTICATED_FULLY
之类的自定义过滤器吗?UserPrincipal
中的访问属性,还是可以使用我在OAUTH_CLIENT
对象上定义的权限,例如我添加的corsFilter
?OAuth2AuthenticationEntryPoint
吗?org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandle
类?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>
。{{1}}
我想在这里添加完整的配置文件,但是有一个限制。
答案 0 :(得分:0)
/ oauth / token端点应使用客户端凭据进行保护,看起来您将其连接到用户身份验证管理器。您没有显示其配置或实现,但是根据InternalAuthenticationServiceException
判断它没有被异常分类为安全异常。修复这两件事情,你可能会做生意。
(顺便说一句,@Configuration
样式更方便,我建议您先使用它,然后再提供它提供的更多默认值,直到您掌握它为止。)