首页 > 解决方案 > 声明未添加到 Identity Server 4 中的令牌

问题描述

我实现了身份服务 ProfileService 来添加地址声明:

public async Task GetProfileDataAsync(ProfileDataRequestContext context) {
  
  User user = await _userManager.GetUserAsync(context.Subject);

  ClaimsPrincipal principal = await _claimsFactory.CreateAsync(user); 

  ClaimsIdentity identity = (ClaimsIdentity)principal.Identity;

  identity.AddClaims(
    new List<Claim> {
      new Claim(JwtClaimTypes.Address, "My Address")
    }
  );

  var claims = identity.Claims;

  context.AddRequestedClaims(identity.Claims);

}

我添加了一个断点,并且声明有地址声明。

但令牌没有地址声明。

我错过了什么?

我的 IdentityServer4 配置

services.AddIdentityServer(options =>
{
    options.Events.RaiseErrorEvents = true;
    options.Events.RaiseInformationEvents = true;
    options.Events.RaiseFailureEvents = true;
    options.Events.RaiseSuccessEvents = true;
    options.EmitStaticAudienceClaim = true;
})
  .AddInMemoryIdentityResources(
    new List<IdentityResource> { 
      new IdentityResources.OpenId(),
      new IdentityResources.Profile(),
      new IdentityResources.Email(),
      new IdentityResources.Address()
    }
  )
  .AddInMemoryApiResources(
    new List<ApiResource> { 
      new ApiResource {
        Name = "api",
        DisplayName = "API Resource",
        Enabled = true,
        Scopes = { "api" },
        UserClaims = { JwtClaimTypes.Address }
      }
    }
  )
  .AddInMemoryApiScopes(
    new List<ApiScope> { 
    new ApiScope("api", "API Scope")
    }
  )
  .AddInMemoryClients(
    new List<Client> { 
      new Client {
        ClientId = "spa",
        ClientName = "SPA Client",
        AllowAccessTokensViaBrowser = true,
        AllowedGrantTypes = GrantTypes.Code,
        AllowOfflineAccess = true,
        RequireClientSecret = false,
        RequireConsent = false,
        RequirePkce = true,
        AccessTokenType = AccessTokenType.Jwt,
        AccessTokenLifetime = 3600,
        IdentityTokenLifetime = 360,
        RefreshTokenUsage = TokenUsage.ReUse,
        AlwaysSendClientClaims = true,
        UpdateAccessTokenClaimsOnRefresh = true,
        AlwaysIncludeUserClaimsInIdToken = true,
        AllowedScopes = { 
          IdentityServerConstants.StandardScopes.OpenId,
          IdentityServerConstants.StandardScopes.Profile, 
          IdentityServerConstants.StandardScopes.Email, 
          IdentityServerConstants.StandardScopes.OfflineAccess,
          "api"
        },  
        AllowedCorsOrigins = { "https://localhost:5002" },
        PostLogoutRedirectUris = { "https://localhost:5002/signout" },
        RedirectUris = { "https://localhost:5002/signin", "https://localhost:5002/renew" }
      }
    }               
  )
  .AddAspNetIdentity<User>()
  .AddProfileService<ProfileService>()
  .AddDeveloperSigningCredential();

更新

我添加了以下 IdentityResources:

new IdentityResources.Address(),
new IdentityResource("subscription", new String[] { "subscription"})

然后我通过添加两个范围来更新 SPA 客户端:

IdentityServerConstants.StandardScopes.Address,
"subscription"

最后,在使用 OidcClient.js 时,我请求了这两个 Scope。

因为 ASP.Net 身份添加了这 2 个声明,所以我将在令牌上获取它们。

但是如果 ASP.NET Identity 没有添加声明,如果我尝试在 ProfileService 中执行它,它们不会添加到令牌中。知道为什么吗?

我错过了 IS ProfileService 的目的,因为没有添加声明。

标签: identityserver4

解决方案


如果您的用户有address声明,那么只要您address在登录时包含范围,它将自动添加到他们的个人资料中。

编辑:如果所需的声明与 api 资源相关联,那么它将不会在配置文件中返回,而是在access_token. 因此,如果您想查看用户的地址,则必须将其包含在身份资源中。


推荐阅读