使用外部身份验证缓存用户配置文件 .NET Core IdentityServer4
Cache user profile with external authentication .NET Core IdentityServer4
整个身份概念的新手,但我进行了几次 Google 搜索,但没有找到我认为合适的回复。
我将 .NET Core 1.0.0 与 EF Core 和 IdentityServer 4 (ID4) 结合使用。
ID4 在单独的服务器上,我在客户端获得的唯一信息是声明。我想访问完整的(扩展的)用户配置文件,最好来自 User.Identity.
那么我该如何设置,以便在 User.Identity 中填充 ApplicationUser 模型上的所有属性,而无需每次都发送数据库请求?我希望在会话结束前将信息存储在缓存中进行身份验证。
我不想做的是在每个控制器中设置查询以获取附加信息。客户端上的所有控制器都将继承自一个基本控制器,这意味着如果有必要,我可以 DI 一些服务。
提前致谢。
客户端
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "Cookies"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
AuthenticationScheme = "oidc",
SignInScheme = "Cookies",
Authority = Configuration.GetSection("IdentityServer").GetValue<string>("Authority"),
RequireHttpsMetadata = false,
ClientId = "RateAdminApp"
});
ID4
app.UseIdentity();
app.UseIdentityServer();
services.AddDeveloperIdentityServer()
.AddOperationalStore(builder => builder.UseSqlServer("Server=localhost;Database=Identities;MultipleActiveResultSets=true;Integrated Security=true", options => options.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name)))
.AddConfigurationStore(builder => builder.UseSqlServer("Server=localhost;Database=Identities;MultipleActiveResultSets=true;Integrated Security=true", options => options.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name)))
.AddAspNetIdentity<ApplicationUser>();
应用程序用户模型
public class ApplicationUser : IdentityUser
{
[Column(TypeName = "varchar(100)")]
public string FirstName { get; set; }
[Column(TypeName = "varchar(100)")]
public string LastName { get; set; }
[Column(TypeName = "nvarchar(max)")]
public string ProfilePictureBase64 { get; set; }
}
如果您想转换身份服务器上的声明,对于您的情况(您使用 aspnet 身份)覆盖 UserClaimsPrincipalFactory
是一个解决方案(参见 Store data in cookie with asp.net core identity)。
public class AppClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser, IdentityRole>
{
public AppClaimsPrincipalFactory(
UserManager<ApplicationUser> userManager,
RoleManager<IdentityRole> roleManager,
IOptions<IdentityOptions> optionsAccessor) : base(userManager, roleManager, optionsAccessor)
{
}
public async override Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
{
var principal = await base.CreateAsync(user);
((ClaimsIdentity)principal.Identity).AddClaims(new[] {
new Claim("FirstName", user.FirstName)
});
return principal;
}
}
// register it
services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, AppClaimsPrincipalFactory>();
您也可以使用事件(在客户端应用程序上)向 cookie 添加额外的声明,它会提供声明直到用户注销。
有两个(可能更多)选项:
首先使用OnTicketReceived
的openidconnect认证:
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
AuthenticationScheme = "oidc",
SignInScheme = "Cookies",
Authority = Configuration.GetSection("IdentityServer").GetValue<string>("Authority"),
RequireHttpsMetadata = false,
ClientId = "RateAdminApp",
Events = new OpenIdConnectEvents
{
OnTicketReceived = e =>
{
// get claims from user profile
// add claims into e.Ticket.Principal
e.Ticket = new AuthenticationTicket(e.Ticket.Principal, e.Ticket.Properties, e.Ticket.AuthenticationScheme);
return Task.CompletedTask;
}
}
});
或者使用OnSigningIn
cookie认证事件
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "Cookies",
Events = new CookieAuthenticationEvents()
{
OnSigningIn = async (context) =>
{
ClaimsIdentity identity = (ClaimsIdentity)context.Principal.Identity;
// get claims from user profile
// add these claims into identity
}
}
});
有关客户端应用程序的解决方案,请参阅类似问题:
整个身份概念的新手,但我进行了几次 Google 搜索,但没有找到我认为合适的回复。
我将 .NET Core 1.0.0 与 EF Core 和 IdentityServer 4 (ID4) 结合使用。 ID4 在单独的服务器上,我在客户端获得的唯一信息是声明。我想访问完整的(扩展的)用户配置文件,最好来自 User.Identity.
那么我该如何设置,以便在 User.Identity 中填充 ApplicationUser 模型上的所有属性,而无需每次都发送数据库请求?我希望在会话结束前将信息存储在缓存中进行身份验证。
我不想做的是在每个控制器中设置查询以获取附加信息。客户端上的所有控制器都将继承自一个基本控制器,这意味着如果有必要,我可以 DI 一些服务。
提前致谢。
客户端
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "Cookies"
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
AuthenticationScheme = "oidc",
SignInScheme = "Cookies",
Authority = Configuration.GetSection("IdentityServer").GetValue<string>("Authority"),
RequireHttpsMetadata = false,
ClientId = "RateAdminApp"
});
ID4
app.UseIdentity();
app.UseIdentityServer();
services.AddDeveloperIdentityServer()
.AddOperationalStore(builder => builder.UseSqlServer("Server=localhost;Database=Identities;MultipleActiveResultSets=true;Integrated Security=true", options => options.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name)))
.AddConfigurationStore(builder => builder.UseSqlServer("Server=localhost;Database=Identities;MultipleActiveResultSets=true;Integrated Security=true", options => options.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name)))
.AddAspNetIdentity<ApplicationUser>();
应用程序用户模型
public class ApplicationUser : IdentityUser
{
[Column(TypeName = "varchar(100)")]
public string FirstName { get; set; }
[Column(TypeName = "varchar(100)")]
public string LastName { get; set; }
[Column(TypeName = "nvarchar(max)")]
public string ProfilePictureBase64 { get; set; }
}
如果您想转换身份服务器上的声明,对于您的情况(您使用 aspnet 身份)覆盖 UserClaimsPrincipalFactory
是一个解决方案(参见 Store data in cookie with asp.net core identity)。
public class AppClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser, IdentityRole>
{
public AppClaimsPrincipalFactory(
UserManager<ApplicationUser> userManager,
RoleManager<IdentityRole> roleManager,
IOptions<IdentityOptions> optionsAccessor) : base(userManager, roleManager, optionsAccessor)
{
}
public async override Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
{
var principal = await base.CreateAsync(user);
((ClaimsIdentity)principal.Identity).AddClaims(new[] {
new Claim("FirstName", user.FirstName)
});
return principal;
}
}
// register it
services.AddScoped<IUserClaimsPrincipalFactory<ApplicationUser>, AppClaimsPrincipalFactory>();
您也可以使用事件(在客户端应用程序上)向 cookie 添加额外的声明,它会提供声明直到用户注销。
有两个(可能更多)选项:
首先使用OnTicketReceived
的openidconnect认证:
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
AuthenticationScheme = "oidc",
SignInScheme = "Cookies",
Authority = Configuration.GetSection("IdentityServer").GetValue<string>("Authority"),
RequireHttpsMetadata = false,
ClientId = "RateAdminApp",
Events = new OpenIdConnectEvents
{
OnTicketReceived = e =>
{
// get claims from user profile
// add claims into e.Ticket.Principal
e.Ticket = new AuthenticationTicket(e.Ticket.Principal, e.Ticket.Properties, e.Ticket.AuthenticationScheme);
return Task.CompletedTask;
}
}
});
或者使用OnSigningIn
cookie认证事件
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "Cookies",
Events = new CookieAuthenticationEvents()
{
OnSigningIn = async (context) =>
{
ClaimsIdentity identity = (ClaimsIdentity)context.Principal.Identity;
// get claims from user profile
// add these claims into identity
}
}
});
有关客户端应用程序的解决方案,请参阅类似问题: