OAUTH 从 2.0.0 升级到 2.3.3
OAUTH Upgrade from 2.0.0 to 2.3.3
我想获得一些 OAUTH2 的经验,所以我尝试获取一些教程 运行...我已经从这个开始 spring-security-oauth2-tutorial
我从这个代码库升级到 spring-security-oauth2-2.0.0。经过一些更改后一切正常......
在此之后,我尝试更新到 spring-security-oauth2-2.3.3,但这次我无法解决即将出现的问题。到目前为止,我通过 GET-Requests 进行身份验证,就像在教程中显示的那样...... GET-Request 看起来像这样:
并返回给我访问令牌等等...升级到 2.3.3 后,此调用无效。我发现,只允许 POST-请求...所以我尝试使用工具 "Postman" 将相同的数据发送到我的服务器,但后来我收到了这个异常:
142475 [qtp105302830-20] DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
142475 [qtp105302830-20] DEBUG org.springframework.security.web.FilterChainProxy - /oauth/token at position 1 of 7 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
142475 [qtp105302830-20] DEBUG org.springframework.security.web.FilterChainProxy - /oauth/token at position 2 of 7 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
142475 [qtp105302830-20] DEBUG org.springframework.security.web.FilterChainProxy - /oauth/token at position 3 of 7 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
142476 [qtp105302830-20] DEBUG org.springframework.security.web.FilterChainProxy - /oauth/token at position 4 of 7 in additional filter chain; firing Filter: 'ClientCredentialsTokenEndpointFilter'
142476 [qtp105302830-20] DEBUG org.springframework.security.web.FilterChainProxy - /oauth/token at position 5 of 7 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
142476 [qtp105302830-20] DEBUG org.springframework.security.web.FilterChainProxy - /oauth/token at position 6 of 7 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
142476 [qtp105302830-20] DEBUG org.springframework.security.web.FilterChainProxy - /oauth/token at position 7 of 7 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
142476 [qtp105302830-20] DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
142476 [qtp105302830-20] DEBUG org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /oauth/token; Attributes: [IS_AUTHENTICATED_FULLY]
142476 [qtp105302830-20] DEBUG org.springframework.web.context.support.XmlWebApplicationContext - Publishing event in Root WebApplicationContext: org.springframework.security.access.event.AuthenticationCredentialsNotFoundEvent[source=FilterInvocation: URL: /oauth/token]
142476 [qtp105302830-20] DEBUG org.springframework.security.web.access.ExceptionTranslationFilter - Authentication exception occurred; redirecting to authentication entry point
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:339)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:198)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1634)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1317)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1219)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:219)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.Server.handle(Server.java:531)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:352)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:281)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
at org.eclipse.jetty.io.ChannelEndPoint.run(ChannelEndPoint.java:118)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:132)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:762)
at org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:680)
at java.base/java.lang.Thread.run(Thread.java:844)
142507 [qtp105302830-20] DEBUG org.springframework.security.web.access.ExceptionTranslationFilter - Calling Authentication entry point.
142507 [qtp105302830-20] DEBUG org.springframework.security.oauth2.provider.error.DefaultOAuth2ExceptionRenderer - Written [error="unauthorized", error_description="An Authentication object was not found in the SecurityContext"] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter@6fa103cd]
142507 [qtp105302830-20] DEBUG org.springframework.security.web.context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
我认为我犯了一个非常基本的错误,因为我试图调试我的代码但没有达到(MyClientDetailsService、MyUserDetailsService)。我在未经授权的情况下从邮递员那里进行了令牌调用(oauth/token),所有数据都作为表单数据发送到正文中。
这是我当前的 spring-security-xml:
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd ">
<!-- This is default url to get a token from OAuth -->
<http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request
parameters -->
<custom-filter ref="clientCredentialsTokenEndpointFilter"
after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<!-- This is where we tells spring security what URL should be protected
and what roles have access to them -->
<http pattern="/api/**" create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<intercept-url pattern="/api/**" access="ROLE_APP" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test" />
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test/client" />
<property name="typeName" value="Basic" />
</bean>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager" />
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
xmlns="http://www.springframework.org/schema/beans">
<constructor-arg>
<list>
<bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
<bean class="org.springframework.security.access.vote.RoleVoter" />
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</constructor-arg>
</bean>
<authentication-manager id="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="userDetailsService">
</authentication-provider>
</authentication-manager>
<bean id="userDetailsService" class="com.mystuff.MyUserDetailsService" />
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails" />
</bean>
<!-- This defined token store, we have used inmemory tokenstore for now
but this can be changed to a user defined one -->
<bean id="tokenStore"
class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore" />
<!-- This is where we defined token based configurations, token validity
and other things -->
<bean id="tokenServices"
class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore" />
<property name="supportRefreshToken" value="true" />
<property name="accessTokenValiditySeconds" value="120" />
<property name="clientDetailsService" ref="clientDetails" />
</bean>
<bean id="userApprovalHandler" class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler">
<property name="tokenStore" ref="tokenStore"/>
<property name="requestFactory" ref="requestFactory"/>
</bean>
<bean id="requestFactory" class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
<constructor-arg ref="clientDetails" />
</bean>
<oauth:authorization-server
client-details-service-ref="clientDetails"
token-services-ref="tokenServices"
user-approval-handler-ref="userApprovalHandler">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password />
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter"
resource-id="test" token-services-ref="tokenServices" />
<bean id="clientDetails" class="com.mystuff.MyClientDetailsService" />
<sec:global-method-security
pre-post-annotations="enabled" proxy-target-class="true">
<!--you could also wire in the expression handler up at the layer of the
http filters. See https://jira.springsource.org/browse/SEC-1452 -->
<sec:expression-handler ref="oauthExpressionHandler" />
</sec:global-method-security>
<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
</beans>
好的,因为我认为这是一个非常基本的错误...
经过一段时间的调试后,我发现了错误,我只是通过 post-请求错误的方式发送了数据。我在 "Postman" 中使用了表单数据主体,但正确的解决方案是使用 x-www-form-urlencoded 主体...
我修改后一切正常!
我想获得一些 OAUTH2 的经验,所以我尝试获取一些教程 运行...我已经从这个开始 spring-security-oauth2-tutorial
我从这个代码库升级到 spring-security-oauth2-2.0.0。经过一些更改后一切正常...... 在此之后,我尝试更新到 spring-security-oauth2-2.3.3,但这次我无法解决即将出现的问题。到目前为止,我通过 GET-Requests 进行身份验证,就像在教程中显示的那样...... GET-Request 看起来像这样:
并返回给我访问令牌等等...升级到 2.3.3 后,此调用无效。我发现,只允许 POST-请求...所以我尝试使用工具 "Postman" 将相同的数据发送到我的服务器,但后来我收到了这个异常:
142475 [qtp105302830-20] DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
142475 [qtp105302830-20] DEBUG org.springframework.security.web.FilterChainProxy - /oauth/token at position 1 of 7 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
142475 [qtp105302830-20] DEBUG org.springframework.security.web.FilterChainProxy - /oauth/token at position 2 of 7 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
142475 [qtp105302830-20] DEBUG org.springframework.security.web.FilterChainProxy - /oauth/token at position 3 of 7 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
142476 [qtp105302830-20] DEBUG org.springframework.security.web.FilterChainProxy - /oauth/token at position 4 of 7 in additional filter chain; firing Filter: 'ClientCredentialsTokenEndpointFilter'
142476 [qtp105302830-20] DEBUG org.springframework.security.web.FilterChainProxy - /oauth/token at position 5 of 7 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
142476 [qtp105302830-20] DEBUG org.springframework.security.web.FilterChainProxy - /oauth/token at position 6 of 7 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
142476 [qtp105302830-20] DEBUG org.springframework.security.web.FilterChainProxy - /oauth/token at position 7 of 7 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
142476 [qtp105302830-20] DEBUG org.springframework.security.web.util.matcher.AntPathRequestMatcher - Checking match of request : '/oauth/token'; against '/oauth/token'
142476 [qtp105302830-20] DEBUG org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Secure object: FilterInvocation: URL: /oauth/token; Attributes: [IS_AUTHENTICATED_FULLY]
142476 [qtp105302830-20] DEBUG org.springframework.web.context.support.XmlWebApplicationContext - Publishing event in Root WebApplicationContext: org.springframework.security.access.event.AuthenticationCredentialsNotFoundEvent[source=FilterInvocation: URL: /oauth/token]
142476 [qtp105302830-20] DEBUG org.springframework.security.web.access.ExceptionTranslationFilter - Authentication exception occurred; redirecting to authentication entry point
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:339)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:198)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1634)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1317)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1219)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:219)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
at org.eclipse.jetty.server.Server.handle(Server.java:531)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:352)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:281)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:102)
at org.eclipse.jetty.io.ChannelEndPoint.run(ChannelEndPoint.java:118)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.produce(EatWhatYouKill.java:132)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:762)
at org.eclipse.jetty.util.thread.QueuedThreadPool.run(QueuedThreadPool.java:680)
at java.base/java.lang.Thread.run(Thread.java:844)
142507 [qtp105302830-20] DEBUG org.springframework.security.web.access.ExceptionTranslationFilter - Calling Authentication entry point.
142507 [qtp105302830-20] DEBUG org.springframework.security.oauth2.provider.error.DefaultOAuth2ExceptionRenderer - Written [error="unauthorized", error_description="An Authentication object was not found in the SecurityContext"] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter@6fa103cd]
142507 [qtp105302830-20] DEBUG org.springframework.security.web.context.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed
我认为我犯了一个非常基本的错误,因为我试图调试我的代码但没有达到(MyClientDetailsService、MyUserDetailsService)。我在未经授权的情况下从邮递员那里进行了令牌调用(oauth/token),所有数据都作为表单数据发送到正文中。
这是我当前的 spring-security-xml:
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sec="http://www.springframework.org/schema/security"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd ">
<!-- This is default url to get a token from OAuth -->
<http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
<anonymous enabled="false" />
<http-basic entry-point-ref="clientAuthenticationEntryPoint" />
<!-- include this only if you need to authenticate clients via request
parameters -->
<custom-filter ref="clientCredentialsTokenEndpointFilter"
after="BASIC_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<!-- This is where we tells spring security what URL should be protected
and what roles have access to them -->
<http pattern="/api/**" create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<intercept-url pattern="/api/**" access="ROLE_APP" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test" />
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="test/client" />
<property name="typeName" value="Basic" />
</bean>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="clientAuthenticationManager" />
</bean>
<bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"
xmlns="http://www.springframework.org/schema/beans">
<constructor-arg>
<list>
<bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter" />
<bean class="org.springframework.security.access.vote.RoleVoter" />
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</constructor-arg>
</bean>
<authentication-manager id="clientAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService" />
</authentication-manager>
<authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="userDetailsService">
</authentication-provider>
</authentication-manager>
<bean id="userDetailsService" class="com.mystuff.MyUserDetailsService" />
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails" />
</bean>
<!-- This defined token store, we have used inmemory tokenstore for now
but this can be changed to a user defined one -->
<bean id="tokenStore"
class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore" />
<!-- This is where we defined token based configurations, token validity
and other things -->
<bean id="tokenServices"
class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore" />
<property name="supportRefreshToken" value="true" />
<property name="accessTokenValiditySeconds" value="120" />
<property name="clientDetailsService" ref="clientDetails" />
</bean>
<bean id="userApprovalHandler" class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler">
<property name="tokenStore" ref="tokenStore"/>
<property name="requestFactory" ref="requestFactory"/>
</bean>
<bean id="requestFactory" class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">
<constructor-arg ref="clientDetails" />
</bean>
<oauth:authorization-server
client-details-service-ref="clientDetails"
token-services-ref="tokenServices"
user-approval-handler-ref="userApprovalHandler">
<oauth:authorization-code />
<oauth:implicit />
<oauth:refresh-token />
<oauth:client-credentials />
<oauth:password />
</oauth:authorization-server>
<oauth:resource-server id="resourceServerFilter"
resource-id="test" token-services-ref="tokenServices" />
<bean id="clientDetails" class="com.mystuff.MyClientDetailsService" />
<sec:global-method-security
pre-post-annotations="enabled" proxy-target-class="true">
<!--you could also wire in the expression handler up at the layer of the
http filters. See https://jira.springsource.org/browse/SEC-1452 -->
<sec:expression-handler ref="oauthExpressionHandler" />
</sec:global-method-security>
<oauth:expression-handler id="oauthExpressionHandler" />
<oauth:web-expression-handler id="oauthWebExpressionHandler" />
</beans>
好的,因为我认为这是一个非常基本的错误...
经过一段时间的调试后,我发现了错误,我只是通过 post-请求错误的方式发送了数据。我在 "Postman" 中使用了表单数据主体,但正确的解决方案是使用 x-www-form-urlencoded 主体...
我修改后一切正常!