【问题标题】:Spring 4.0 Oauth 2 not workingSpring 4.0 Oauth 2 不工作
【发布时间】:2014-11-28 20:57:24
【问题描述】:

spring servlet 文件配置见下文。它曾经可以工作,现在在将依赖项升级到 Spring core 4.0 和 Spring sec oauth 2.0 之后,它就不起作用了。我的意思是,我无法获得令牌。请参阅下面的错误消息和问题:

当我尝试使用以下 URL 获取令牌时,它会给出 406 错误:

网址:/oauth2/oauth/token

“错误”:此请求标识的资源只能生成具有根据请求“接受”标头不可接受的特征的响应。

我是否缺少 Spring 4.0 和 Spring security 3.2 或 Spring security oauth 2.0.0 中的任何新配置

详情如下:

这是一个基于 REST 的 API,没有客户端。我在 chrome 浏览器上用 Postman 测试了这个。 明确地说,我没有在接受标头中发送任何内容。使用旧版本的 spring oauth2,它确实适用于接受标头中的 application/json。

使用下面提到的依赖版本,我得到了这个响应,它工作正常。但是,一旦我升级到新的依赖版本,它就会失败并给出 406:

{ “access_token”:“f9287b1d-243b-453d-9d3e-f5ed67e974f6”, "token_type": "承载者", "refresh_token": "c6a45534-7c20-4dda-b6f1-9a231cb649ed", "expires_in": 299999, “范围”:“读写” }

我使用以下依赖项来工作。 :

<properties>
        <springsec.version>3.1.0.RELEASE</springsec.version>
        <spring.version>3.1.0.RELEASE</spring.version>
        <jersey-version>1.18.1</jersey-version>
        <springoauth2-version>1.0.0.RELEASE</springoauth2-version>      
</properties>

New dependencies I changed to when it started to fail: 

<properties>
        <springsec.version>3.2.5.RELEASE</springsec.version>
        <spring.version>4.1.1.RELEASE</spring.version>
        <jersey-version>1.18.1</jersey-version>
        <springoauth2-version>2.0.3.RELEASE</springoauth2-version>      
</properties>

最初是使用 InMemoryTokenStore 实现的。但是,现在我们要使用 JDBCTokenStore。我读到,Spring oauth2 2.0 有更好的特性,所以我开始更改依赖项并 除此之外,我必须更改代码中的一些包引用,因为它们现在在 2.0.0 中已更改。

这是 spring servlet 上下文文件:

<?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: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.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd ">

    <http pattern="/oauth/token" create-session="stateless"
        authentication-manager-ref="authenticationManager"
        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" />
        <custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" /> 
        <access-denied-handler ref="oauthAccessDeniedHandler" />
    </http>

    <http pattern="/resources/**" create-session="never"
        entry-point-ref="oauthAuthenticationEntryPoint"
        xmlns="http://www.springframework.org/schema/security">
        <anonymous enabled="false" />
        <intercept-url pattern="/resources/**" method="GET" />
        <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
        <access-denied-handler ref="oauthAccessDeniedHandler" />
    </http>

    <http pattern="/logout" create-session="never" 
        entry-point-ref="oauthAuthenticationEntryPoint"
        xmlns="http://www.springframework.org/schema/security">
        <anonymous enabled="false" />
        <intercept-url pattern="/logout" method="GET" />
        <sec:logout invalidate-session="true" logout-url="/logout" success-handler-ref="logoutSuccessHandler"   />
        <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
        <access-denied-handler ref="oauthAccessDeniedHandler" />
    </http>

    <bean id="logoutSuccessHandler" class="prototype.oauth2.authentication.security.LogoutImpl" >
        <property name="tokenstore" ref="tokenStore"></property>
    </bean>

    <bean id="oauthAuthenticationEntryPoint"
        class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    </bean>

    <bean id="clientAuthenticationEntryPoint"
        class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
        <property name="realmName" value="springsec/client" />
        <property name="typeName" value="Basic" />
    </bean>

    <bean id="oauthAccessDeniedHandler"
        class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler">
    </bean>

    <bean id="clientCredentialsTokenEndpointFilter"
        class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
        <property name="authenticationManager" ref="authenticationManager" />
    </bean>

    <authentication-manager alias="authenticationManager"
        xmlns="http://www.springframework.org/schema/security">
        <authentication-provider user-service-ref="clientDetailsUserService" />
    </authentication-manager>

    <bean id="clientDetailsUserService"
        class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
        <constructor-arg ref="clientDetails" />
    </bean>

    <bean id="clientDetails" class="prototype.oauth2.authentication.security.ClientDetailsServiceImpl"/>

    <authentication-manager id="userAuthenticationManager" 
        xmlns="http://www.springframework.org/schema/security">
        <authentication-provider  ref="customUserAuthenticationProvider">
        </authentication-provider>
    </authentication-manager>

    <bean id="customUserAuthenticationProvider"
        class="prototype.oauth2.authentication.security.CustomUserAuthenticationProvider">
    </bean>

    <oauth:authorization-server
        client-details-service-ref="clientDetails" token-services-ref="tokenServices">
        <oauth:authorization-code />
        <oauth:implicit/>
        <oauth:refresh-token/>
        <oauth:client-credentials />
        <oauth:password authentication-manager-ref="userAuthenticationManager"/>
    </oauth:authorization-server>

    <oauth:resource-server id="resourceServerFilter"
        resource-id="springsec" token-services-ref="tokenServices" />

    <bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.InMemoryTokenStore" />      

    <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="300000"></property>
        <property name="clientDetailsService" ref="clientDetails" />
    </bean>


    <mvc:annotation-driven />   <!-- Declares explicit support for annotation-driven MVC controllers  @RequestMapping, @Controller -->

    <mvc:default-servlet-handler />

    <bean id="sampleResource" class="prototype.oauth2.authentication.resources.Resource"></bean>

</beans>

以下是两种实现的 curl 响应:

这是 Spring 4 和 Spring oauth 2.0.3 的新实现

curl -v -X POST -d "username=user1&password=user1&client_id=client1&client_secret=client1&grant_type=password" -H "Accept:application/json" [url1]

它失败了:

> Accept:application/json
> Content-Length: 89
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 89 out of 89 bytes
* STATE: DO => DO_DONE handle 0x60002de40; line 1263 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x60002de40; line 1384 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x60002de40; line 1395 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 406 Not Acceptable
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Content-Type: text/html;charset=utf-8
< Content-Language: en
< Content-Length: 1108
< Date: Mon, 06 Oct 2014 18:16:23 GMT

这是使用 Spring 3 和 Spring oauth 1.0 的旧实现 - 它给出了正确的响应

curl -v -X POST -d "username=user1&password=user1&client_id=client1&client_secret=client1&grant_type=password" -H "Accept:application/json" [url2]

> Host: localhost:8088
> Accept:application/json
> Content-Length: 89
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 89 out of 89 bytes
* STATE: DO => DO_DONE handle 0x60002de40; line 1263 (connection #0)
* STATE: DO_DONE => WAITPERFORM handle 0x60002de40; line 1384 (connection #0)
* STATE: WAITPERFORM => PERFORM handle 0x60002de40; line 1395 (connection #0)
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 200 OK
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Cache-Control: no-store
< Pragma: no-cache
< Content-Type: application/json
< Transfer-Encoding: chunked
< Date: Mon, 06 Oct 2014 18:16:55 GMT
<
* STATE: PERFORM => DONE handle 0x60002de40; line 1565 (connection #0)
* Connection #0 to host localhost left intact
* Expire cleared
{"access_token":"5a626e3f-8ef5-425f-945d-02f15abc7c2d","token_type":"bearer","refresh_token":"bc841c6c-7c44-42c0-811b-228526b43989","expires_in":292343,"scope":"read write"}

【问题讨论】:

  • 我认为这与 Spring Security 无关,因此您发布的配置无关紧要。您在接受标头中发送什么?客户在哪里?它是如何实现的?
  • 感谢戴夫的回复。
  • 对不起,我想回复你更多细节,并提交了。让我在单独的帖子中发布更多详细信息。在 cmets 中,不允许添加所有细节。
  • 如果您的代表不够高,您可以为您的原始帖子提出修改建议。单独的帖子将作为重复而关闭。
  • 再次感谢。我刚刚编辑并发布了 spring-servlet 配置 xml 和有关实现的其他详细信息。

标签: java spring spring-security spring-security-oauth2


【解决方案1】:

这解决了问题:

<dependency> 
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId> 
  <version>2.3.3</version> 
</dependency>

错误不是直截了当的。它给出了 406 并抱怨接受标头。根据 Dave Syer 的建议,它可能与依赖问题有关,我开始研究杰克逊依赖。

【讨论】:

    猜你喜欢
    • 2018-10-16
    • 1970-01-01
    • 2016-03-27
    • 1970-01-01
    • 2012-12-24
    • 2019-02-18
    • 2018-08-29
    • 2020-08-16
    • 1970-01-01
    相关资源
    最近更新 更多