1

トークン エントリ ポイント /oauth/token へのアクセスへのリダイレクトに問題があります。詳細は後述します。これを実装するのに多くの時間がかかったので、誰かが私に光を当ててくれることを願っています。

また興味深いのは、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、アクセス、ノンス、およびトークン ストアを実装することでした。これらのコンポーネントはすべて完全に機能しており、テスト済みです。実際、すべての認証/承認を取得し、承認コードを作成します。

最近、Spring Oauth2 github で JDBC ストアをテストする際にバグを見ましたが、これは実際の実装ではなく、特に JDBC を使用していないため、テストに関連していました。

ログイン用の OAuth2 サーバーと Spring Security に常駐する REST リソースにアクセスするためのクライアント Web アプリケーションを作成しました。/oauth/token へのアクセス トークンを要求するまでは、すべてうまくいきます。

安全なRestサービスを最初にヒットすると、リダイレクトが適切に開始され、true DefaultOAuth2RequestFactory createAuthorizationRequest() メソッドになります。ストアからシークレットなどを使用して ClientDetails オブジェクトを完全に読み込みます。したがって、Oauth2 クライアントのすべてのスコープ、許可などがあります。また、redirectURIParameter を適切に検証し、リダイレクトを解決します。次に、TokenStoreUserApprovalHandler に移動し、OAuth2Request オブジェクトを作成します。次に、もちろん、ワークフローにまだ存在しない既存のアクセス トークンを見つけようとします。authenticationKeyGenerator から authenticationkey を作成し、この時点で適切に null を返すストアにクエリを実行します。次に、/oauth/authorize に 2 回リダイレクトし、2 回目に認証コードがあり、approveOrDeny() メソッド内で承認済み (AuthorizationEndPoint) としてマークします。authorizationCodeServices はコードを作成し、Cassandra ストアに適切に保存します。

この時点で、( AuthorizationEndPoint)を呼び出しgetSuccessfulRedirect()て、状態パラメーターをテンプレートに追加します。

OAuth2RestTemplate次に、( class)getAccessToken()メソッドを呼び出します。アクセストークンは問題なく有効であるため、 with acquireAccessToken()を返す呼び出しが呼び出されます。次に、 を呼び出してでアクセス トークンを取得します。次に、メソッドで呼び出しが呼び出され ます。そして で失敗します。は許可タイプで完全に作成され、ヘッダーとしてと の両方が あります。はとして正しいです。isとis の ID 。ヘッダーは次のように表示されますaccessTokenRequest{code=[Q19Y6u], state=[1PyzHf]}accessTokenProviderobtainAccessToken()OAuth2AccessTokenSupportretrieveToken()getRestTemplateAuthorizationCodeResourceDetailsauthorization_codeauthorizationSchemeclientAuthenticationSchemeclientIdclientSecretAuthorizationCodeResourceDetailsoAuth2ClientBeanuserAuthorizationURIhttp://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ファイルにあるコメントを見てください。認証プロバイダー user-service-ref="userService" を取る認証マネージャーである userAuthenticationManager Bean を指す、authorization-request-manager-ref パラメーターを追加しました。

<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) authentication-manager oauthClientAuthenticationManager は、「/oauth/token」がインターセプトされるときに使用されます。これは次のように定義されます。

<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:global-method-security で使用される次の methodSecurityExpressionHandler Bean を定義しています。これが正しいかどうかもわかりません。

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

4)推奨されていないと思われるBean「clientCredentialsTokenEndpointFilter」もあります。これをエントリ ポイント「/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 Token エンドポイントについて: ここで多くの質問があるため、これはエンドポイント /oauth/token です。

  1. これに到達することはありません。
  2. 好きなカスタムフィルターを用意clientCredentialsTokenEndpointFilterしますか?
  3. http-basic エントリ ポイントが必要ですか?
  4. のようにアクセス属性を持たせるべきですか、それともオブジェクトに追加したような、オブジェクトIS_AUTHENTICATED_FULLYに定義した権限を使用できますか?UserPrincipalOAUTH_CLIENT
  5. セッションはどうですか?「ステートレス」または「決して」と言うべきか
  6. も追加corsFilterしようかな。
  7. エントリーポイントは正しいですか?OAuth2AuthenticationEntryPointクラスはどれですか?
  8. csrf トークンを追加する必要がありますか? それはそれをより制限するので、私は信じていません。
  9. 式ハンドラは正しいorg.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandleですか?
  10. authentication-manager-ref を から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>

ここに完全な構成ファイルを追加したいのですが、制限があります。

4

1 に答える 1