簡體   English   中英

如何在身份服務器 4 的客戶端獲得額外的聲明?

[英]How to get additional claims on client side in identity server 4?

在我的身份服務器的 Startup.cs 文件中,我的服務器配置如下。 我正在使用 asp.net 身份進行用戶管理。

services.AddIdentityServer()
                .AddDeveloperSigningCredential()
                .AddInMemoryPersistedGrants()
                .AddInMemoryIdentityResources(Config.GetIdentityResources())
                .AddInMemoryApiResources(Config.GetApiResources())
                .AddInMemoryClients(Config.GetClients())
                .AddAspNetIdentity<ApplicationUser>();

services.AddTransient<IProfileService, ProfileService>();

IdentiyResources如下所示。 在這里,我想將額外的聲明作為IS_Token返回,我想將其用於我的應用程序的一些進一步的業務邏輯。

public static IEnumerable<IdentityResource> GetIdentityResources()
        {
            return new List<IdentityResource>
                {
                    new IdentityResources.OpenId(),
                    new IdentityResources.Profile(),
                    new IdentityResource("IS_token", new []{ "IS_token" } ),
                };
        }

我還增加了在IssuedClaims這種說法我里面IProfileService如下。

public class ProfileService : IProfileService
    {
        private readonly IUserClaimsPrincipalFactory<ApplicationUser> _claimsFactory;
        private readonly UserManager<ApplicationUser> _userManager;

        public ProfileService(UserManager<ApplicationUser> userManager, IUserClaimsPrincipalFactory<ApplicationUser> claimsFactory)
        {
            _userManager = userManager;
            _claimsFactory = claimsFactory;
        }

        public async Task GetProfileDataAsync(ProfileDataRequestContext context)
        {
            var sub = context.Subject.GetSubjectId();
            var user = await _userManager.FindByIdAsync(sub);
            var principal = await _claimsFactory.CreateAsync(user);

            var claims = principal.Claims.ToList();
            claims = claims.Where(claim => context.RequestedClaimTypes.Contains(claim.Type)).ToList();
            claims.Add(new Claim(JwtClaimTypes.GivenName, user.UserName));
            claims.Add(new Claim(IdentityServerConstants.StandardScopes.Email, user.Email));

            //Get user claims from AspNetUserClaims table
            var userClaims = await _userManager.GetClaimsAsync(user);
            claims.AddRange(userClaims);

            context.IssuedClaims = claims;
        }

        public async Task IsActiveAsync(IsActiveContext context)
        {
            var sub = context.Subject.GetSubjectId();
            var user = await _userManager.FindByIdAsync(sub);
            context.IsActive = user != null;
        }
    }

我的MVC客戶端配置如下

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

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

                        // where to redirect to after login
                        RedirectUris = { "http://localhost:5002/signin-oidc" },

                        // where to redirect to after logout
                        PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },

                        AllowedScopes = new List<string>
                        {
                            IdentityServerConstants.StandardScopes.OpenId,
                            IdentityServerConstants.StandardScopes.Profile,
                            "IS_token",
                            "api"
                        },

                        AllowOfflineAccess = true
                    },

在我的 MVC 應用程序中,我在Startup.cs文件中有以下代碼

services.AddMvc();

    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

    services.AddAuthentication(options =>
    {
        options.DefaultScheme = "Cookies";
        options.DefaultChallengeScheme = "oidc";
    })
    .AddCookie("Cookies")
    .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("api");
        options.Scope.Add("offline_access");
    });

當我在身份服務器中對用戶進行身份驗證並返回到我的安全鏈接時,我得到了以下聲明,但我的用戶聲明中缺少 IS_token。

我的安全頁面的cshtml

<dl>

    @foreach (var claim in User.Claims)

    {

        <dt>@claim.Type</dt>

        <dd>@claim.Value</dd>



    }

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

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

</dl> 

這是我的受保護頁面的屏幕截圖

我的安全頁面的輸出

正如您在圖像中IS_token ,缺少IS_token 我怎樣才能獲得IS_token聲明???

我需要在身份服務器的客戶端配置中設置AlwaysIncludeUserClaimsInIdToken = true 所以我應該如下定義我的客戶。

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

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

                        // where to redirect to after login
                        RedirectUris = { "http://localhost:5002/signin-oidc" },

                        // where to redirect to after logout
                        PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },

                        AllowedScopes = new List<string>
                        {
                            IdentityServerConstants.StandardScopes.OpenId,
                            IdentityServerConstants.StandardScopes.Profile,
                            "IS_token",
                            "poslink"
                        },

                        AlwaysIncludeUserClaimsInIdToken = true,

                        AllowOfflineAccess = true
                    },

在您的客戶端配置中,在 AddOpenIdConnect 中,您應該添加:

options.Scope.Add("IS_token");

否則,此范圍的聲明將被您的GetProfileDataAsync實現過濾掉

暫無
暫無

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

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