将声明映射到自定义ApplicationUser的属性

时间:2018-05-29 16:35:35

标签: c# asp.net-core asp.net-identity

我正在尝试了解如何将自定义ApplicationUser类添加到我的ASP.NET Core MVC应用程序,该应用程序向外部系统(另一个使用IdentityServer 4的MVC项目)进行身份验证。 我在IdentityServer 4应用程序中自定义了IProfileService,以向用户的配置文件添加自定义声明,例如“avatarUrl”,其中url作为声明的值。 现在,在我的客户端应用程序中,我创建了自定义ApplicationUser:

public class ApplicationUser : IdentityUser
{
    public string AvatarUrl { get; set; }
}

如何自定义ASP.NET Identity框架,以便在登录到外部IdSrv后,HttpContext中的User公开此属性(而非通过声明)?我希望能够在控制器方法中执行此操作:

this.HttpContext.User.Identity.AvatarUrl

我是否需要创建一个派生自ClaimsPrincipal的类?我需要覆盖哪一个方法,以便将我的CustomClaimsPrincipal分配给HttpContext?

编辑: 我试图注入一个自定义的AppSignInManager,但我注意到它没有被使用。 看起来,由于应用程序通过OpenIdConnect调用IdentityServer进行身份验证,因此SignInManager不会参与此过程。 在ConfigureServices中,我有一个带有外部Identity Server的auth的标准代码:

services
    .AddAuthentication(options =>
    {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = "oidc";
    })
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddOpenIdConnect("oidc", options =>
    {
        #region Oidc events
        options.Events.OnUserInformationReceived = context =>
        {
            // For debugging
            return Task.CompletedTask;
        };
        #endregion

        options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.Authority = Configuration.GetSection("IdentityServer:Authority").Value;
        options.RequireHttpsMetadata = false;

        options.ClientId = "myapp";
        options.SaveTokens = true;
        // TODO: provide a real client secret
        options.ClientSecret = "secret";
        options.ResponseType = "code id_token";
        options.SaveTokens = true;
        options.GetClaimsFromUserInfoEndpoint = true;
        foreach (var scope in "openid profile email".Split(' ', StringSplitOptions.RemoveEmptyEntries))
        {
            options.Scope.Add(scope);
        }

        options.ClaimActions.Remove("name");
        options.ClaimActions.Remove("email");
        options.ClaimActions.MapUniqueJsonKey(ClaimTypes.Name, "name");
        options.ClaimActions.MapUniqueJsonKey(ClaimTypes.Email, "email");
        options.ClaimActions.MapUniqueJsonKey("avatarUrl", "avatarUrl");
    });

所以现在我想知道...因为没有调用SignInManager,在使用Oidc进行身份验证后,创建ClaimsPrincipal对象的代码在哪里?我需要覆盖哪种方法?

0 个答案:

没有答案