簡體   English   中英

IdentityServer4聲明不屬於混合流令牌的一部分

[英]IdentityServer4 claims are not part of the token on hybrid flow

我正在嘗試構建混合流,並使用IdentityServer4對返回的訪問令牌進行聲明。 我正在使用QuickStart UI控件。

在用戶成功通過身份驗證之后,在我的AccountController ,我有以下代碼用於登錄:

await HttpContext.SignInAsync("anon@nymous.com", "anon@nymous.com", null, new Claim("MyName", "Ophir"));

在導致此流程的MVC網站中,在我要“保護”的頁面上,我具有以下代碼:

[Authorize]
public IActionResult RestrictedMvcResource()
{
       var token = _httpContext.HttpContext.GetTokenAsync("access_token").Result;
       var identity = User.Identity;
       return View();
}

成功登錄后,調試器會將此代碼正常運行,並且獲取訪問令牌。

問題是,如果我解碼訪問令牌(我正在使用https://jwt.io/ ),我會看到名稱和主題,但看不到我已定義的MyName聲明。

(我的系統中還有一個用於client_credentials流,該流確實返回了對令牌的聲明-但它使用了不同的代碼流)。

如何為混合流返回令牌的聲明?

編輯:

解決此問題是兩件事的結合:

  1. 根據(選定)答案中的建議實施IProfileService 這是我的實現:
public class ProfileService : IProfileService
{
    public Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        context.AddRequestedClaims(context.Subject.Claims);

        foreach (Claim claim in context.Subject.Claims)
        {
            if (context.IssuedClaims.Contains(claim))
                continue;

            context.IssuedClaims.Add(claim);
        }

        return Task.FromResult(0);
    }

    public Task IsActiveAsync(IsActiveContext context)
    {
        context.IsActive = true;
        return Task.FromResult(0);
    }
}

這將添加令牌上尚未存在的所有聲明。

  1. 調用HttpContext.SignInAsync ,必須傳遞聲明列表,否則context.Subject.Claims集合中將沒有其他聲明。

如果要向令牌添加自定義聲明,則可以實現自定義IProfileService

您可以在Identity Server 4文檔中找到更多信息。

一個簡單的自定義配置文件服務的示例是:

public class CustomProfileService : IProfileService
{
    public Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        context.AddRequestedClaims(context.Subject.Claims);
        context.IssuedClaims.Add(new Claim("MyName", "Ophir"));
        return Task.FromResult(0);
    }

    public Task IsActiveAsync(IsActiveContext context)
    {
        context.IsActive = true;    
        return Task.FromResult(0);
    }
}

一旦有了它,只需將其注冊到DI:

services.AddTransient<IProfileService, CustomProfileService>();

每當請求access_tokenid_token時,它將被調用。 如果您只想要特定類型令牌的額外聲明,則需要根據Ruard的注釋檢查context.Caller

編輯:另外,也可以按照Identity Server 4快速入門之一中的示例,將聲明直接添加到用戶配置中:

            new TestUser
            {
                SubjectId = "1",
                Username = "alice",
                Password = "password",

                Claims = new []
                {
                    new Claim("MyName", "Ophir")
                }
            },

如果最終沒有實現自定義IProfileService並繼續使用DefaultProfileService ,則還需要在配置中添加自定義IdentityResource

return new List<IdentityResource>
{
    //..Your other configured identity resources

    new IdentityResource(
    name: "custom.name",
    displayName: "Custom Name",
    claimTypes: new[] { "MyName" });
};

任何希望在令牌中添加此聲明的客戶端都需要請求custom.name范圍。

AspNet.Security.OpenIdConnect.Server不會序列化未設置目標的聲明。 我在使用OpenIdDict時遇到了這個問題。

嘗試這個:

var claim = new Claim("MyName", "Ophir");
claim.SetDestinations(OpenIdConnectConstants.Destinations.AccessToken);

await HttpContext.SignInAsync("anon@nymous.com", "anon@nymous.com", null, claim);

您可能需要添加以下名稱空間:

using AspNet.Security.OpenIdConnect.Extensions;
using AspNet.Security.OpenIdConnect.Primitives;

我將身份聲明添加到身份服務器的令牌的過程分為兩個步驟。

通過像其他答案之一所示的自定義配置文件服務,您可以為用戶定義自己的聲明。

然后可以通過userinfo端點請求這些聲明。

或者,您創建一個名為IncludeNameInAccessToken的Api(資源),如果您請求將Api作為范圍,則默認將名稱聲明添加到訪問令牌中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM