声明未添加到 Identity Server 4 中的令牌
Claim not added to token in Identity Server 4
我实现了身份服务配置文件服务以添加地址声明:
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);
}
我添加了一个断点并声明了 Address 声明。
但令牌没有地址声明。
我错过了什么?
我的 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();
更新
我添加了以下身份资源:
new IdentityResources.Address(),
new IdentityResource("subscription", new String[] { "subscription"})
然后我通过添加两个作用域更新了 SPA 客户端:
IdentityServerConstants.StandardScopes.Address,
"subscription"
最后,在使用 OidcClient.js 时,我请求了这两个范围。
因为 ASP.Net Identity 添加了这 2 个声明,所以我会将它们放在令牌上。
但如果 ASP.NET Identity 不添加声明,如果我尝试在 ProfileService 中添加声明,则它们不会添加到令牌中。知道为什么吗?
由于未添加声明,我错过了 IS ProfileService 的用途。
如果您的用户拥有 address
声明,那么只要您在登录时包含 address
范围,它就会自动添加到他们的个人资料中。
编辑:如果要求的声明与 api 资源相关联,则它不会在配置文件中返回,而是在 access_token
中返回。因此,如果您想查看用户的地址,则必须将其包含在身份资源中。
您应该将地址范围添加到客户端定义中的 AllowedScopes 列表中:
AllowedScopes = {
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
IdentityServerConstants.StandardScopes.OfflineAccess,
"api"
},
我实现了身份服务配置文件服务以添加地址声明:
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);
}
我添加了一个断点并声明了 Address 声明。
但令牌没有地址声明。
我错过了什么?
我的 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();
更新
我添加了以下身份资源:
new IdentityResources.Address(),
new IdentityResource("subscription", new String[] { "subscription"})
然后我通过添加两个作用域更新了 SPA 客户端:
IdentityServerConstants.StandardScopes.Address,
"subscription"
最后,在使用 OidcClient.js 时,我请求了这两个范围。
因为 ASP.Net Identity 添加了这 2 个声明,所以我会将它们放在令牌上。
但如果 ASP.NET Identity 不添加声明,如果我尝试在 ProfileService 中添加声明,则它们不会添加到令牌中。知道为什么吗?
由于未添加声明,我错过了 IS ProfileService 的用途。
如果您的用户拥有 address
声明,那么只要您在登录时包含 address
范围,它就会自动添加到他们的个人资料中。
编辑:如果要求的声明与 api 资源相关联,则它不会在配置文件中返回,而是在 access_token
中返回。因此,如果您想查看用户的地址,则必须将其包含在身份资源中。
您应该将地址范围添加到客户端定义中的 AllowedScopes 列表中:
AllowedScopes = {
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email,
IdentityServerConstants.StandardScopes.OfflineAccess,
"api"
},