2017-10-09 26 views
1

MSグラフAPIのSSOプロバイダを作成しています Spring OAuth2を利用するAzure AD v2エンドポイント。SpringセキュリティでのMicrosoft Graph OAuth2認証のコンフィグレーション - エラーAADSTS90014

私は実装と一定のテストを進めていますが、私は困惑しているAADから返されたエラーを見つけました。結局のところ、これはすべて標準のOAuth 2フローであるべきです。

MS devポータルでローカルホストのリダイレクトURL(レコードの場合、httpスキームをサポートしている唯一のものです)を提供しました。だから、私がhttp://localhost/myapp/auth/office365を呼び出すと、春のセキュリティが呼び出しを傍受し、クライアントIDがhttps://login.microsoftonline.com/common/oauth2/v2.0/authorizeのブラウザに正しいパラメータでリダイレクトされます。

マイクロソフトは私に同意画面を表示し、その後、期待される認証コードパラメータでHTTP GET経由でSpring Securityアプリケーションにリダイレクトされます。

問題は、アプリケーションがベアラトークン頭痛のために与えられた認証コードをネゴシエートしようとするときです。 Spring Securityはhttps://login.microsoftonline.com/common/oauth2/v2.0/tokenへのPOSTを呼び出しますが、401エラーで終了します。ここで

スタックトレース

error="invalid_request", error_description="AADSTS90014: The request body must contain the following parameter: 'client_id'. 
Trace ID: 9acd2a10-1cfb-443f-9c57-78d608c00c00 
Correlation ID: bf063914-8926-4e8f-b102-7522d0e3b0af 
Timestamp: 2017-10-09 15:51:44Z", correlation_id="bf063914-8926-4e8f-b102-7522d0e3b0af", error_codes="[90014]", timestamp="2017-10-09 15:51:44Z", trace_id="9acd2a10-1cfb-443f-9c57-78d608c00c00" 
    at org.springframework.security.oauth2.common.exceptions.OAuth2ExceptionJackson2Deserializer.deserialize(OAuth2ExceptionJackson2Deserializer.java:100) 
    at org.springframework.security.oauth2.common.exceptions.OAuth2ExceptionJackson2Deserializer.deserialize(OAuth2ExceptionJackson2Deserializer.java:33) 
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4001) 
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3072) 
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:235) 
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readInternal(AbstractJackson2HttpMessageConverter.java:215) 
    at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:193) 
    at org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport$AccessTokenErrorHandler.handleError(OAuth2AccessTokenSupport.java:235) 
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:700) 
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:653) 
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:621) 
    at org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport.retrieveToken(OAuth2AccessTokenSupport.java:137) 
    at org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider.obtainAccessToken(AuthorizationCodeAccessTokenProvider.java:209) 
    at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainNewAccessTokenInternal(AccessTokenProviderChain.java:148) 
    at org.springframework.security.oauth2.client.token.AccessTokenProviderChain.obtainAccessToken(AccessTokenProviderChain.java:121) 
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.acquireAccessToken(OAuth2RestTemplate.java:221) 
    at org.springframework.security.oauth2.client.OAuth2RestTemplate.getAccessToken(OAuth2RestTemplate.java:173) 
    at org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter.attemptAuthentication(OAuth2ClientAuthenticationProcessingFilter.java:105) 
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 

である私は、原因を見つけるために、春のセキュリティ実装に見てきました、。

エラーメッセージerror="invalid_request", error_description="AADSTS90014: The request body must contain the following parameter: 'client_id'.は自明です.Microsoft Graphは、依頼本体に依然として基本認証ヘッダーによって提供されているクライアントIDが必要です。 今すぐ停止。私はクラスパスを汚染しないために、普通の古いSpring Securityを使用し、サードパーティの特定のjarファイルは使用しません。

SpringのOAuth 2のJavaソースコードを見ると、問題は明らかです。 SpringはクライアントIDをgetParametersForAuthorizeRequestでのみ使用します。これはリダイレクトURLの生成に使用されます。 getParametersForTokenRequestの場合、クライアントIDはフォームに指定されていません。

質問:誰がここにいるのですか? MS が認証コードを取得した後にトークン要求のクライアントIDをに要求していることをSpringに通知するにはどうすればよいですか?

答えて

1

実際には、Microsoft Graphで認証するのではなく、実際に認証することはありません。 Azure Active Directoryに対して実際に認証しています。 Microsoft Graph APIは、終了するベアラトークンを受け取りますが、アクセストークン自体は発行しません。

承認コードフローにどのエンドポイントを使用しているのかは不明ですが、AADにはv1v2の2つがあります。主な違いは、v2が中央登録を使用し、仕事/学校と個人アカウントの両方を認証できることです。

エンドポイントに関係なく、アクセストークンを要求しているときに、要求本体にclientidを指定する必要があります。実際には、あなたが身体に提供する必要があるいくつかの値があります。また、これらは、application/x-www-form-urlencodedとして提供する必要があることにも注意してください。

あなたが提供v1のエンドポイント(行だけ読みやすくするために壊す)の場合:

grant_type=authorization_code 
&client_id={client-id} 
&code={authoization-code} 
&redirect_uri={redirect-uri} 
&client_secret={client-secret} 
&resource={resource-uri} 

v2のエンドポイントはほぼ同じですが、scope代わりのresourceを使用しています。

grant_type=authorization_code 
&client_id={client-id} 
&code={authoization-code} 
&redirect_uri={redirect-uri} 
&client_secret={client-secret} 
&scope={scopes} 

OPさん編集

今、Spring Securityに戻ります。 Springはデフォルトで、Azure ADに対してHTTP基本認証方式を使用します。そのスキームでは、クライアントIDとシークレットはHTTP Authorizationヘッダーにエンコードされ、フォームには認証コードと状態パラメータしか含まれていないので、なぜAADが認証を拒否したのかについて私は(OP、ndr)

クライアントIDとシークレットをフォームに渡すために、Spring Securityにサポートされている別の認証方式を使用するように指示できます。 form認証スキームは、クライアントIDとシークレットをフォームにプッシュします。 以下のコードは動作し、アクセストークンを取得します。

<oauth2:resource 
    id="msAdAuthenticationSource" 
    client-id="${oauth.appId}" 
    client-secret="${oauth.appSecret}" 
    type="authorization_code" 
    authentication-scheme="form" 
    client-authentication-scheme="form" 
    use-current-uri="true" 
    user-authorization-uri="${oauth.authorizationUri}" 
    access-token-uri="${oauth.accessTokenUri}" 
    scope="${oauth.scopes}" 
    pre-established-redirect-uri="${oauth.redirectUri}" /> 
authentication-scheme="form" 
client-authentication-scheme="form" 

問題解決に注意してください、もっとたくさん来て!

+1

私は、Springを試しても同じ結論に達しました。フォームに渡されるクライアントIDのために修正が必要なSpring Securityの設定の一部があります。私はあなたの答えを編集して –

+1

Marc、私の質問(V2エンドポイントを表示する)と** Springセキュリティを有効にする**設定を提供する答えの両方を編集した後、受け入れられた答えを授与しました。 –

関連する問題