添加了自定义声明,显示在访问令牌中缺少 ID 令牌
Added Custom Claim, showing in ID token missing in Access token
我有一个 .NET Core 身份提供程序(它也使用 IdentityServer4),它使用 Azure AD 对 SPA 应用程序进行身份验证。我正在添加一个“oid”声明,其中包含从 Azure 接收到的对象标识符值。问题是,在 SPA 应用程序中,我可以在 ID 令牌中看到“oid”声明,但在访问令牌中看不到它。我也需要访问令牌中的 oid。这是相关代码:
Startup.cs
services.AddAuthentication()
.AddCookie("Cookies", options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(10);
})
.AddOpenIdConnect(ActiveDirectoryTenants.TenantA, ActiveDirectoryTenants.TenantA, options => Configuration.Bind("TenantAAzureAd", options))
.AddOpenIdConnect(ActiveDirectoryTenants.TenantB, ActiveDirectoryTenants.TenantB, options => Configuration.Bind("TenantBAzureAd", options));
AddActiveDirectoryOpenIdConnectOptions(services, ActiveDirectoryTenants.TenantA);
AddActiveDirectoryOpenIdConnectOptions(services, ActiveDirectoryTenants.TenantB);
我有一个共同的功能,可以为这些配置添加其他选项。我尝试在 OnTokenValidated 中添加 oid 声明,但没有在访问令牌中收到 oid 声明。
protected virtual void AddActiveDirectoryOpenIdConnectOptions(IServiceCollection services, string tenant)
{
services.Configure<OpenIdConnectOptions>(tenant, options =>
{
options.Authority = options.Authority + "/v2.0/";
options.TokenValidationParameters.ValidateIssuer = false;
options.Events = new OpenIdConnectEvents
{
OnRedirectToIdentityProvider = ctx =>
{
ctx.ProtocolMessage.LoginHint = ctx.Properties.GetString("username");
return Task.CompletedTask;
},
OnTokenValidated = ctx =>
{
//Maybe need to add oid here???
}
};
});
}
成功登录到 Azure AD 后正在添加 oid 声明。
AccountController.cs
public async Task<IActionResult> ExternalLoginCallback(string returnUrl, string remoteError = null, string openIdScheme = null)
{
var authResult = await HttpContext.AuthenticateAsync(openIdScheme ?? ActiveDirectoryTenants.TenantA);
var externalUser = authResult.Principal;
var claims = externalUser.Claims.ToList();
var applicationUser = //gets the user based on the email found in claims, omitted for brevity
await userManager.AddClaimAsync(applicationUser, new Claim("oid", claims.First(x => x.Type == http://schemas.microsoft.com/identity/claims/objectidentifier).Value));
await signInManager.SignInAsync(applicationUser, false, "AzureAD");
return Redirect("~/");
}
在 SPA 应用程序中收到的 ID 令牌(注意 oid 声明):
{
"nbf": xxx,
"exp": xxx,
"iss": "https://localhost:3000",
"aud": "xxx-spa-test",
"iat": xxx,
"at_hash": "",
"s_hash": "",
"sid": "",
"sub": "guid",
"auth_time": 1620026953,
"idp": "AzureAD",
"display_name": "Test User",
"oid": "guid",
"role": [
"Staff",
],
"name": "test@azureaddomain",
"amr": [
"external"
]
}
SPA 应用程序中收到的访问令牌(注意缺少的 oid 声明):
{
"nbf": xxx,
"exp": xxx,
"iss": "https://localhost:3000",
"aud": [
"https://localhost:3000/resources",
"xxx-api-test-scope"
],
"client_id": "xxx-spa-test",
"sub": "guid",
"auth_time": 1620026953,
"idp": "AzureAD",
"role": [
"Staff",
],
"name": "test@azureaddomain",
"scope": [
"openid",
"profile",
"xxx-api-test-scope"
],
"amr": [
"external"
]
}
为了在访问令牌中结束声明,您需要添加一个 ApiScope 并向其中添加 Userclaim 名称。或者,添加一个 ApiScope 和一个包含 UserClaim 的 ApiResource。
喜欢
var apiresource1 = new ApiResource()
{
Name = "apiresource1", //This is the name of the API
ApiSecrets = new List<Secret>
{
new Secret("myapisecret".Sha256())
},
Description = "This is the order Api-resource description",
Enabled = true,
DisplayName = "Orders API Service",
Scopes = new List<string> { "apiscope1"},
UserClaims = new List<string>
{
//Custom user claims that should be provided when requesting access to this API.
//These claims will be added to the access token, not the ID-token!
"apiresource1-userclaim3",
}
};
查看我的回答了解更多详情
我有一个 .NET Core 身份提供程序(它也使用 IdentityServer4),它使用 Azure AD 对 SPA 应用程序进行身份验证。我正在添加一个“oid”声明,其中包含从 Azure 接收到的对象标识符值。问题是,在 SPA 应用程序中,我可以在 ID 令牌中看到“oid”声明,但在访问令牌中看不到它。我也需要访问令牌中的 oid。这是相关代码:
Startup.cs
services.AddAuthentication()
.AddCookie("Cookies", options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(10);
})
.AddOpenIdConnect(ActiveDirectoryTenants.TenantA, ActiveDirectoryTenants.TenantA, options => Configuration.Bind("TenantAAzureAd", options))
.AddOpenIdConnect(ActiveDirectoryTenants.TenantB, ActiveDirectoryTenants.TenantB, options => Configuration.Bind("TenantBAzureAd", options));
AddActiveDirectoryOpenIdConnectOptions(services, ActiveDirectoryTenants.TenantA);
AddActiveDirectoryOpenIdConnectOptions(services, ActiveDirectoryTenants.TenantB);
我有一个共同的功能,可以为这些配置添加其他选项。我尝试在 OnTokenValidated 中添加 oid 声明,但没有在访问令牌中收到 oid 声明。
protected virtual void AddActiveDirectoryOpenIdConnectOptions(IServiceCollection services, string tenant)
{
services.Configure<OpenIdConnectOptions>(tenant, options =>
{
options.Authority = options.Authority + "/v2.0/";
options.TokenValidationParameters.ValidateIssuer = false;
options.Events = new OpenIdConnectEvents
{
OnRedirectToIdentityProvider = ctx =>
{
ctx.ProtocolMessage.LoginHint = ctx.Properties.GetString("username");
return Task.CompletedTask;
},
OnTokenValidated = ctx =>
{
//Maybe need to add oid here???
}
};
});
}
成功登录到 Azure AD 后正在添加 oid 声明。
AccountController.cs
public async Task<IActionResult> ExternalLoginCallback(string returnUrl, string remoteError = null, string openIdScheme = null)
{
var authResult = await HttpContext.AuthenticateAsync(openIdScheme ?? ActiveDirectoryTenants.TenantA);
var externalUser = authResult.Principal;
var claims = externalUser.Claims.ToList();
var applicationUser = //gets the user based on the email found in claims, omitted for brevity
await userManager.AddClaimAsync(applicationUser, new Claim("oid", claims.First(x => x.Type == http://schemas.microsoft.com/identity/claims/objectidentifier).Value));
await signInManager.SignInAsync(applicationUser, false, "AzureAD");
return Redirect("~/");
}
在 SPA 应用程序中收到的 ID 令牌(注意 oid 声明):
{
"nbf": xxx,
"exp": xxx,
"iss": "https://localhost:3000",
"aud": "xxx-spa-test",
"iat": xxx,
"at_hash": "",
"s_hash": "",
"sid": "",
"sub": "guid",
"auth_time": 1620026953,
"idp": "AzureAD",
"display_name": "Test User",
"oid": "guid",
"role": [
"Staff",
],
"name": "test@azureaddomain",
"amr": [
"external"
]
}
SPA 应用程序中收到的访问令牌(注意缺少的 oid 声明):
{
"nbf": xxx,
"exp": xxx,
"iss": "https://localhost:3000",
"aud": [
"https://localhost:3000/resources",
"xxx-api-test-scope"
],
"client_id": "xxx-spa-test",
"sub": "guid",
"auth_time": 1620026953,
"idp": "AzureAD",
"role": [
"Staff",
],
"name": "test@azureaddomain",
"scope": [
"openid",
"profile",
"xxx-api-test-scope"
],
"amr": [
"external"
]
}
为了在访问令牌中结束声明,您需要添加一个 ApiScope 并向其中添加 Userclaim 名称。或者,添加一个 ApiScope 和一个包含 UserClaim 的 ApiResource。
喜欢
var apiresource1 = new ApiResource()
{
Name = "apiresource1", //This is the name of the API
ApiSecrets = new List<Secret>
{
new Secret("myapisecret".Sha256())
},
Description = "This is the order Api-resource description",
Enabled = true,
DisplayName = "Orders API Service",
Scopes = new List<string> { "apiscope1"},
UserClaims = new List<string>
{
//Custom user claims that should be provided when requesting access to this API.
//These claims will be added to the access token, not the ID-token!
"apiresource1-userclaim3",
}
};
查看我的回答