IProfileService 中的提供者声明
Provider claims in IProfileService
当我使用 oidc 进行授权时,我得到了一堆声明。如果我不添加我的自定义 IProfileService,所有这些声明都会在身份服务器发出的 id_token 中传递。如果我提供自己的 ProfileService,Subject 的声明列表是从 idp 返回的内容的子集。有没有办法在个人资料服务中获取完整列表?
这里是来自Startup.cs的相关信息:
var builder = services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
}).AddProfileService<ProfileService>();
services.AddAuthentication()
.AddOpenIdConnect("Name", "Name", o =>
{
o.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
o.SignOutScheme = IdentityServerConstants.SignoutScheme;
o.Authority = "https://sub.domain.com/adfs/";
o.ClientId = "00000000-0000-0000-0000-000000000000";
o.ClientSecret = "secret";
o.ResponseType = "id_token";
o.SaveTokens = true;
o.CallbackPath = "/signin-adfs";
o.SignedOutCallbackPath = "/signout-callback-adfs";
o.RemoteSignOutPath = "/signout-adfs";
o.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role"
};
});
和我的配置文件服务:
public class ProfileService : IProfileService
{
public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var objectGuidClaim = context.Subject.Claims.FirstOrDefault(x => x.Type == "ObjectGUID");
if (objectGuidClaim != null)
{
var userId = new Guid(Convert.FromBase64String(objectGuidClaim.Value));
context.IssuedClaims.Add(new Claim("UserId", userId.ToString()));
}
return Task.CompletedTask;
}
public Task IsActiveAsync(IsActiveContext context)
{
context.IsActive = true;
return Task.CompletedTask;
}
}
所以在我的例子中,没有 ProfileService 然后 ObjectGUID
被传递,但是使用 ProfileService,它在 context.Subject.Claims
列表中不可用。
我的目标是从 idp 获取 "ObjectGUID" 声明,这是一个 base64 编码的 guid,并将其转换为十六进制字符串,并将其作为来自身份服务器的 "UserId" 声明传递。
我什至不确定这是最好的方法。我也尝试通过 ClaimActions
转换它,但我的操作从未执行(我使用随机 guid 进行测试以确保它与转换无关):
o.ClaimActions.MapCustomJson("UserId", obj => {
return Guid.NewGuid().ToString();
});
这是更好的方法吗?为什么不执行?
尝试:
- 确保您的主题不包含
http://schemas.company.com/identity/claims/objectguid
而不仅仅是 ObjectGUID
- 扩展你的
OpenIdConnect 配置:
o.GetClaimsFromUserInfoEndpoint =
true;
和 o.ClaimActions.MapUniqueJsonKey("ObjectGUID", "ObjectGUID");
或 o.ClaimActions.MapUniqueJsonKey("http://schemas.company.com/identity/claims/objectguid", "ObjectGUID");
如果之前没有任何帮助,请尝试:
o.Events = new OpenIdConnectEvents
{
OnTicketReceived = context =>
{
var identity = context.Principal.Identity as ClaimsIdentity;
StringBuilder builder = new StringBuilder();
var claims = identity?.Claims.Select(x => $"{x.Type}:{x.Value};");
if (claims != null)
builder.AppendJoin(", ", claims);
Logger.LogInformation($"Ticket received: [Claims:{builder}]");
identity?.AddClaim(new Claim("userId", Guid.NewGuid().ToString()));
//you can embed your transformer here if you like
return Task.CompletedTask;
}};
(您可以在此处检查确切的传入票证并保留日志记录以备将来使用)
当我使用 oidc 进行授权时,我得到了一堆声明。如果我不添加我的自定义 IProfileService,所有这些声明都会在身份服务器发出的 id_token 中传递。如果我提供自己的 ProfileService,Subject 的声明列表是从 idp 返回的内容的子集。有没有办法在个人资料服务中获取完整列表?
这里是来自Startup.cs的相关信息:
var builder = services.AddIdentityServer(options =>
{
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
}).AddProfileService<ProfileService>();
services.AddAuthentication()
.AddOpenIdConnect("Name", "Name", o =>
{
o.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
o.SignOutScheme = IdentityServerConstants.SignoutScheme;
o.Authority = "https://sub.domain.com/adfs/";
o.ClientId = "00000000-0000-0000-0000-000000000000";
o.ClientSecret = "secret";
o.ResponseType = "id_token";
o.SaveTokens = true;
o.CallbackPath = "/signin-adfs";
o.SignedOutCallbackPath = "/signout-callback-adfs";
o.RemoteSignOutPath = "/signout-adfs";
o.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role"
};
});
和我的配置文件服务:
public class ProfileService : IProfileService
{
public Task GetProfileDataAsync(ProfileDataRequestContext context)
{
var objectGuidClaim = context.Subject.Claims.FirstOrDefault(x => x.Type == "ObjectGUID");
if (objectGuidClaim != null)
{
var userId = new Guid(Convert.FromBase64String(objectGuidClaim.Value));
context.IssuedClaims.Add(new Claim("UserId", userId.ToString()));
}
return Task.CompletedTask;
}
public Task IsActiveAsync(IsActiveContext context)
{
context.IsActive = true;
return Task.CompletedTask;
}
}
所以在我的例子中,没有 ProfileService 然后 ObjectGUID
被传递,但是使用 ProfileService,它在 context.Subject.Claims
列表中不可用。
我的目标是从 idp 获取 "ObjectGUID" 声明,这是一个 base64 编码的 guid,并将其转换为十六进制字符串,并将其作为来自身份服务器的 "UserId" 声明传递。
我什至不确定这是最好的方法。我也尝试通过 ClaimActions
转换它,但我的操作从未执行(我使用随机 guid 进行测试以确保它与转换无关):
o.ClaimActions.MapCustomJson("UserId", obj => {
return Guid.NewGuid().ToString();
});
这是更好的方法吗?为什么不执行?
尝试:
- 确保您的主题不包含
http://schemas.company.com/identity/claims/objectguid
而不仅仅是ObjectGUID
- 扩展你的
OpenIdConnect 配置:
o.GetClaimsFromUserInfoEndpoint = true;
和o.ClaimActions.MapUniqueJsonKey("ObjectGUID", "ObjectGUID");
或o.ClaimActions.MapUniqueJsonKey("http://schemas.company.com/identity/claims/objectguid", "ObjectGUID");
如果之前没有任何帮助,请尝试:
o.Events = new OpenIdConnectEvents { OnTicketReceived = context => { var identity = context.Principal.Identity as ClaimsIdentity; StringBuilder builder = new StringBuilder(); var claims = identity?.Claims.Select(x => $"{x.Type}:{x.Value};"); if (claims != null) builder.AppendJoin(", ", claims); Logger.LogInformation($"Ticket received: [Claims:{builder}]"); identity?.AddClaim(new Claim("userId", Guid.NewGuid().ToString())); //you can embed your transformer here if you like return Task.CompletedTask; }};
(您可以在此处检查确切的传入票证并保留日志记录以备将来使用)