C# 如何在identity server 4中获取客户端的附加声明?

C# 如何在identity server 4中获取客户端的附加声明?,c#,asp.net,asp.net-core,asp.net-identity,identityserver4,C#,Asp.net,Asp.net Core,Asp.net Identity,Identityserver4,在我的identity server的Startup.cs文件中,我将服务器配置如下。我正在使用asp.net标识进行用户管理 services.AddIdentityServer() .AddDeveloperSigningCredential() .AddInMemoryPersistedGrants() .AddInMemoryIdentityResources(Config.GetIdenti

在我的identity server的Startup.cs文件中,我将服务器配置如下。我正在使用asp.net标识进行用户管理

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

services.AddTransient<IProfileService, ProfileService>();
我还在我的
IProfileService
中的IssuedClaims中添加此索赔,如下所示

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;
        }
    }
                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
                    },
当我在identity server中验证用户身份并返回到我的安全链接时,我得到了以下声明,但我的用户声明中缺少IS_令牌

我的安全页面的
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> 

@foreach(User.Claims中的var声明)
{
@索赔.类型
@索赔价值
}
访问令牌
@等待ViewContext.HttpContext.GetTokenAsync(“访问令牌”)
刷新令牌
@等待ViewContext.HttpContext.GetTokenAsync(“刷新令牌”)
这是我的安全页面的屏幕截图


正如您在图像
中所看到的,令牌
丢失。如何获取
IS_token
claim???

我需要在identity server的客户端配置中设置
AlwaysIncludeUserClaimsInIdToken=true
。所以我应该定义我的客户如下

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;
        }
    }
                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
                    },
新客户端
{
ClientId=“mvc”,
ClientName=“MVC客户端”,
AllowedGrantTypes=GrantTypes.HybridAndClientCredentials,
RequireSent=false,
客户秘密=
{
新密码(“Secret.Sha256())
},
//登录后重定向到哪里
重定向URI={”http://localhost:5002/signin-oidc“},
//注销后重定向到何处
PostLogoutRedirectUris={”http://localhost:5002/signout-回调oidc“},
AllowedScopes=新列表
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
“是您的代币”,
“poslink”
},
AlwaysIncludeUserClaimsInIdToken=真,
AllowOfflineAccess=true
},

在客户端配置的AddOpenIdConnect中,您应该添加:

options.Scope.Add(“IS_标记”)


否则,此作用域的声明将被
GetProfileDataAsync

的实现过滤掉,这对您没有帮助,因为ID令牌不是刷新令牌或访问令牌。
                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
                    },