代码之家  ›  专栏  ›  技术社区  ›  Rush Frisby

IProfileService中的提供程序声明

  •  0
  • Rush Frisby  · 技术社区  · 6 年前

    当我使用OIDC认证时,我得到了一堆声明。如果不添加自定义的IProfileService,那么所有这些声明都将通过Identity Server发出的ID_令牌传递。如果我提供自己的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"
        };
    });
    

    我的个人资料服务:

    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”声明从Identity Server传递。

    我甚至不确定这是最好的方法。我也试过把它转换成 ClaimActions 但我的操作从未执行(我使用随机的guid进行测试以确保它不是转换的内容):

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

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

    1 回复  |  直到 6 年前
        1
  •  1
  •   d_f    6 年前

    • http://schemas.company.com/identity/claims/objectguid ObjectGUID
    • 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;
              }};