spring サーブレットのファイル構成については、以下を参照してください。以前は機能していましたが、依存関係を Spring コア 4.0 および Spring sec oauth 2.0 にアップグレードした後、機能しなくなりました。つまり、トークンを取得できません。以下のエラー メッセージと問題を参照してください。
次の URL を使用してトークンを取得しようとすると、406 エラーが発生します。
URL: /oauth2/oauth/トークン
「エラー」: この要求によって識別されるリソースは、要求の「受け入れ」ヘッダーに従って受け入れられない特性を持つ応答を生成することしかできません。
Spring 4.0 および Spring security 3.2 または Spring security oauth 2.0.0 で新しい構成が欠落していますか?
詳細は次のとおりです。
これは REST ベースの API であり、クライアントはありません。私はこれをChromeブラウザのPostmanでテストしていました。明示的に、受け入れヘッダーで何も送信しませんでした。Spring oauth2 の古いバージョンでは、accept ヘッダーの application/json で動作します。
以下の依存関係バージョンでは、この応答が返され、正常に動作します。しかし、新しい依存バージョンにアップグレードするとすぐに失敗し、406 が表示されます。
{ "access_token": "f9287b1d-243b-453d-9d3e-f5ed67e974f6", "token_type": "bearer", "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 で変更されたため、コード内のいくつかのパッケージ参照を変更する必要がありました。
Spring サーブレット コンテキスト ファイルは次のとおりです。
<?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"}