【问题标题】:Provider claims in IProfileServiceIProfileService 中的提供者声明
【发布时间】:2019-01-24 19:26:43
【问题描述】:

当我使用 oidc 进行身份验证时,我会收到一堆声明。如果我不添加我的自定义 IProfileService 所有这些声明都在身份服务器发出的 id_token 中传递。如果我提供自己的 ProfileService,则主题上的声明列表是从 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"
    };
});

还有我的 ProfileService:

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 列表中不可用。

我的目标是从作为 base64 编码的 guid 的 idp 中获取“ObjectGUID”声明,并将其转换为十六进制字符串,并将其作为来自身份服务器的“UserId”声明传递。

我什至不确定这是最好的方法。我也尝试通过ClaimActions 对其进行转换,但我的操作从未执行(我使用随机 guid 进行了测试以确保它与转换无关):

o.ClaimActions.MapCustomJson("UserId", obj => {
    return Guid.NewGuid().ToString();
});

这是更好的方法吗?为什么不执行?

【问题讨论】:

  • 请注意该服务可以被多个端点调用。您可以通过检查 context.caller 来确定端点。另请注意,应包含已配置的声明(使用 context.RequestedClaimTypes),然后应添加其他声明(claims.Add())。例如,请在此处查看我的答案:stackoverflow.com/questions/48006060/…

标签: c# asp.net-core-2.0 identityserver4 openid-connect claims-based-identity


【解决方案1】:

尝试:

  • 确保您的主题不包含 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;
            }};
    

(您可以在此处检查确切的传入票证并保留日志以备将来使用)

【讨论】:

  • 我使用与此类似的 StringBuilder 记录了所有声明。这就是我发现 ProfileService 获得过滤列表的方式。在 ExternalController.ProcessLoginCallbackForOidc 方法中,我得到了完整的声明列表
  • 是的,就是这样。这就是您保留身份的地方(如果需要,在进行一些转换之后)您的身份稍后将用作上下文中的主题。您能否将该方法的要点添加到问题中?此外,您默认使用哪个 ProfileService?至少有两种实现:一种带有 IdSrv 本身,另一种带有 ASP.NET Identity 的扩展。不应该有任何魔法,只是一些简单明了的东西......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 2020-02-24
  • 1970-01-01
  • 2015-02-23
  • 2016-11-28
  • 2020-05-28
  • 1970-01-01
相关资源
最近更新 更多