IdentityServer4 RequestedClaimTypes 为空

IdentityServer4 RequestedClaimTypes is Empty

在我的个人资料服务中,为什么 RequestedClaimTypes 为空?我期待要求提供个人资料声明。根据 this,它们应该包含 FamilyName 和 Given Name 声明类型。

GetIdentityResources

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

客户端

new Client
{
    ClientId = "46a0ab4a-1321-4d77-abe5-98f09310df0b",
    ClientName = "TypeScript SPA client",
    RequireClientSecret = false, // if false this is a public client.
    AllowedGrantTypes = GrantTypes.Implicit,
    AllowAccessTokensViaBrowser = true,

    RedirectUris = { "http://localhost:3000/callback" },
    PostLogoutRedirectUris = { "http://localhost:3000/" },
    AllowedCorsOrigins = { "http://localhost:3000" },

    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
    },

    RequireConsent = false,
},

oidc-client 配置打字稿

const myOidcClientSettings: OidcClientSettings = {
  authority: `${protocol}//${hostname}:5000`,
  client_id: '46a0ab4a-1321-4d77-abe5-98f09310df0b',
  post_logout_redirect_uri: `${protocol}//${hostname}${port ? `:${port}` : ''}/`,
  redirect_uri: `${protocol}//${hostname}${port ? `:${port}` : ''}/callback`,
  response_type: 'id_token token',
  scope: 'openid profile'
};

const myUserManagerSettings: UserManagerSettings = {
  ...myOidcClientSettings,
  automaticSilentRenew: false,
  filterProtocolClaims: true,
  loadUserInfo: true,
  monitorSession: false,
  silent_redirect_uri: `${protocol}//${hostname}${port ? `:${port}` : ''}/callback`,
};

在登录中 Post 我添加以下声明:

Claim[] claims =
{
  new Claim(JwtClaimTypes.Name, $"{loginResponse.FirstName} {loginResponse.LastName}"),
  new Claim(JwtClaimTypes.Email, loginResponse.EmailAddress),
  new Claim(JwtClaimTypes.PhoneNumber, loginResponse.PhoneNumber),
  new Claim(JwtClaimTypes.FamilyName, loginResponse.LastName),
  new Claim(JwtClaimTypes.GivenName, loginResponse.FirstName),
  //new Claim(JwtClaimTypes.AuthorizationCodeHash, aRequest.Password), // The Password will be need by the BFF but can NOT be sent to the Typescript client
};

await HttpContext.Authentication.SignInAsync(subjectId, userName, authenticationProperties, claims);

ProfileService

    public Task GetProfileDataAsync(ProfileDataRequestContext aProfileDataRequestContext)
{
  Logger.LogDebug("Get profile called for {subject} from {client} with {claimTypes} because {caller}",
      aProfileDataRequestContext.Subject.GetSubjectId(),
      aProfileDataRequestContext.Client.ClientName,
      aProfileDataRequestContext.RequestedClaimTypes,
      aProfileDataRequestContext.Caller);

  if (aProfileDataRequestContext.RequestedClaimTypes.Any())
  {
    aProfileDataRequestContext.AddFilteredClaims(aProfileDataRequestContext.Subject.Claims);
  }

  return Task.FromResult(0);
}

配置文件不包含配置文件项目的结果用户信息:(为了便于阅读而缩写

"User info": {
  "id_token": "eyJhbGciOiJSUzI1N",
  "session_state": "M5uV9nYzvmlWjvpjmX--OOPcwAEeVesV7aG9ZO0svS8.8f757e9a033183149734adb156fbb39d",
  "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6",
  "token_type": "Bearer",
  "scope": "openid profile",
  "profile": {
    "sid": "4372a4cbb9938449a39d72db1a9fc6f0",
    "sub": "TestDemo12@gmail.com",
    "auth_time": 1505037917,
    "idp": "local",
    "amr": [
      "pwd"
    ]
  },
  "expires_at": 1505042091,
  "state": {
    "returnUrl": "/en-us/test"
  }
}

看来您必须向您的客户端添加以下选项,

AlwaysIncludeUserClaimsInIdToken = true

以便您的客户将声明包含在令牌中。