web-dev-qa-db-ja.com

AcquireTokenSilentは常にサイレントでトークンを取得できませんでした

ADALを使用すると、SQLに永続化されたトークンキャッシュを使用して2つのAuthenticationContextを取得できます。

AcquireTokenByAuthorizationCodeを使用すると、トークンがデータベースに書き込まれますが、AcquireTokenSilentを使用すると、常に

サイレントでトークンを取得できませんでした。メソッドAcquireTokenを呼び出す

問題の複製の詳細は次のとおりです。

コンテキストを作成します

AuthenticationContext authContext = new AuthenticationContext(_authority, new AzureAdalCache(companyId, _entries, _unitOfWork));

次に、承認によってトークンを取得します

authContext.AcquireTokenByAuthorizationCode(authorizationCode, new Uri(redirectUri), _clientCredential);

この時点で、データベースにエントリを保存します

次に、これを呼び出すと、例外が発生します。

authContext.AcquireTokenSilent(_authority, _clientCredential, new UserIdentifier(companyId.ToString(), UserIdentifierType.UniqueId)).AccessToken;

私も同じ結果で試しました:

authContext.AcquireTokenSilent(_authority, _clientId).AccessToken;
authContext.AcquireTokenSilent(_authority, _clientCredential, UserIdentifier.AnyUser).AccessToken;

AzureAdalCacheの実装を this Gist に投稿します。

キャッシュの各エントリは これのように です。

何が欠けていますか?

更新

@vibronetのコメントの回答に基づいて私はこれを持っています

AuthenticationContext authContext = new AuthenticationContext(_authority, new AzureAdalCache(companyId, _entries, _unitOfWork));
authContext.AcquireTokenByAuthorizationCode(authorizationCode, new Uri(redirectUri), _clientCredential, _eWSResource);
string result = authContext.AcquireTokenSilent(_eWSResource, _clientId, UserIdentifier.AnyUser).AccessToken;
14
Ricardo Polo

問題は、基本的に私がアプリでCommon Authority https://login.windows.net/common/oauth2/authorizeを使用していたことです。 AcquireTokenByAuthorizationCode()では機能しますが、AcquireTokenSilent()では機能しません。

そのため、AcquireTokenByAuthorizationCode()を呼び出すときにTenantIdを保存するために必要でした。また、権限は、AcquireTokenSilent()を呼び出すときにhttps://login.windows.net/<tenant ID>/oauth2/authorizeなどの権限を使用します。これにより、上記と同じコードが機能します。

8
Ricardo Polo

私は電話を理解していません:

authContext.AcquireTokenSilent(
    _authority,
    _clientCredential,
    new UserIdentifier(companyId.ToString(), UserIdentifierType.UniqueId)
).AccessToken;

UserIdentifierはキャッシュ内の値と一致する必要があり、CompanyIDはトークンに対して返されるIDのようには聞こえません。

私が他のスレッドで指摘したサンプル、具体的には https://github.com/AzureADSamples/WebApp-WebAPI-OpenIDConnect-DotNet/blobのAcquireTokenSilentの呼び出しで使用される識別子を見てください。 /master/TodoListWebApp/Controllers/TodoListController.cs

その呼び出しで使用する識別子を選択することはできません。これは、AADが発行する主張によって決まります。選択できる唯一の識別子は、個々のAcquireToken *呼び出しではなく、キャッシュインスタンスレベルです。

4
vibronet

トークンがキャッシュに存在するかどうかを確認し、そうでない場合はサインアウトして、ユーザーにサインインするように依頼します。

AuthenticationContext authContext = new AuthenticationContext(Startup.Authority,
                        new NaiveSessionCache(userObjectID));
                    if (authContext.TokenCache.Count == 0)
                    {
                        authContext.TokenCache.Clear();
                        CosmosInterface.Utils.AuthenticationHelper.token = null;
                        HttpContext.GetOwinContext().Authentication.SignOut(
                            OpenIdConnectAuthenticationDefaults.AuthenticationType,
                            CookieAuthenticationDefaults.AuthenticationType);
                    }
1
Kurkula

ASPNetCore(1.0)でも同じ問題があり、ログイン後に認証トークンを保存しなかったことが原因でした。StartupクラスにOnAuthorizationCodeReceivedを追加し、Response ypeを_ResponseType = OpenIdConnectResponseType.CodeIdToken_。

それが役に立てば幸い。

サンプル: https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-openidconnect-aspnetcore/blob/aspnet10/WebApp-WebAPI-OpenIdConnect-DotNet/Startup.cs#L1

1
teocomi

これは古い質問ですが、私にとっては、クライアントのCookieをクリアする必要があり、それによってブラウザーに再認証を強制し、すべてが再び問題なくなりました。

0
ScottFoster1000