ハイブリッドフローへの切り替えとAPIアクセスの追加

以前のクイックスタートでは、APIアクセスとユーザー認証の両方を検討しました。今度は2つの部分を一緒に持っていきたいと思っています。

OpenID ConnectとOAuth 2.0の組み合わせの美しさは、単一のプロトコルとトークンサービスとの単一の交換の両方で達成できるということです。

前回のクイックスタートでは、OpenID Connect暗黙のフローを使用しました。暗黙のフローでは、すべてのトークンがブラウザを介して送信されますが、これはアイデンティティトークンにとってはまったく問題ありません。今度は、アクセストークンを要求したい。

アクセストークンはアイデンティティトークンよりもはるかに敏感であり、必要でない場合には「外部」の世界にそれらを公開したくありません。OpenID Connectには「Hybrid Flow」というフローがあり、これは両方の世界のベストを提供し、アイデンティティトークンはブラウザチャネル経由で送信されるため、クライアントはそれ以上の作業を行う前に検証することができます。検証が成功すると、クライアントはトークンサービスのバックチャネルを開いてアクセストークンを取得します。

クライアント設定の変更

多くの変更は必要ありません。最初に、クライアントがハイブリッドフローを使用できるようにしたいとします。さらに、クライアントがユーザーのコンテキストに属さないサーバーからサーバーへのAPI呼び出しを許可するようにします(クライアントの資格情報のクイックスタートに非常に似ています)。これはAllowedGrantTypesプロパティを使用して表されます。

次に、クライアントシークレットを追加する必要があります。これは、バックチャンネルのアクセストークンを取得するために使用されます。

最後に、クライアントにoffline_accessスコープへのアクセスを許可します。これにより、長期間存続するAPIアクセスのリフレッシュトークンを要求できます。

new Client
{
    ClientId = "mvc",
    ClientName = "MVC Client",
    AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,

    ClientSecrets =
    {
        new Secret("secret".Sha256())
    },

    RedirectUris           = { "http://localhost:5002/signin-oidc" },
    PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },

    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        "api1"
    },
    AllowOfflineAccess = true
};

MVCクライアントの変更

MVCクライアントの変更も最小限に抑えられています。ASP.NET Core OpenID Connectハンドラには、ハイブリッドフローの組み込みサポートが含まれているため、一部のコンフィグレーション値を変更するだけで済みます。

ClientSecretIdentityServerの秘密と一致するように設定します。スコープoffline_accessとapi1スコープを追加し、ResponseTypeを(これは基本的に「ハイブリッドフローを使用する」という意味の)code id_token .

.AddOpenIdConnect("oidc", options =>
{
    options.SignInScheme = "Cookies";

    options.Authority = "http://localhost:5000";
    options.RequireHttpsMetadata = false;

    options.ClientId = "mvc";
    options.ClientSecret = "secret";
    options.ResponseType = "code id_token";

    options.SaveTokens = true;
    options.GetClaimsFromUserInfoEndpoint = true;

    options.Scope.Add("api1");
    options.Scope.Add("offline_access");
    options.ClaimActions.MapJsonKey("website", "website");
});

MVCクライアントを実行すると、大きな違いはなく、同意画面に追加のAPIとオフラインアクセススコープが表示されるようになりました。

アクセストークンの使用

OpenID Connectミドルウェアは自動的にあなたのためにトークン(私たちの場合はID、アクセス、更新)を保存します。それがSaveTokensセッティングです。

技術的には、トークンはクッキーのプロパティセクション内に格納されます。それらにアクセスする最も簡単な方法は、Microsoft.AspNetCore.Authentication名前空間の拡張メソッドを使用することです。

例えばあなたのクレームビューでは:

<dt>access token</dt>
<dd>@await ViewContext.HttpContext.GetTokenAsync("access_token")</dd>

<dt>refresh token</dt>
<dd>@await ViewContext.HttpContext.GetTokenAsync("refresh_token")</dd>

アクセストークンを使用してAPIにアクセスするには、トークンを取得して HttpClient に設定するだけです。

public async Task<IActionResult> CallApiUsingUserAccessToken()
{
    var accessToken = await HttpContext.GetTokenAsync("access_token");

    var client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
    var content = await client.GetStringAsync("http://localhost:5001/identity");

    ViewBag.Json = JArray.Parse(content).ToString();
    return View("json");
}