我们目前在AspnetUsers
表中存储ClientId。我们使用它来识别客户端登录的用户,以及用于过滤此客户端的数据。
是否有更有效的方法来获取当前用户clientId,在每个控制器中不调用:await _manager.GetUserAsync(_httpContextAccessor.HttpContext.User);
在每个Controller中获取clientId?我们可以使用Singleton服务在登录时设置此属性,并将其注入我们的控制器吗?
谢谢,
答案 0 :(得分:4)
最好的解决方案是将clientid存储为声明,因此当用户登录时,它将被序列化到claimprincipal并包含在auth cookie中。
您可以从默认的Identity ClaimsPrincipalFactory继承并覆盖CreateAsync方法,调用基类来创建然后添加自定义声明。然后你注入你的自定义工厂,它将被使用。然后,您可以从User.Claims获取clientid,其中User是ClaimsPrincipal并且在控制器操作中可用。
通过执行此操作,您只需在登录时点击数据库即可将clientid添加为声明。之后,您可以在用户声明的每个请求上获得它,而无需点击数据库。
我在我的cloudscribe项目中有一个示例,您可以看到我的自定义ClaimsPrincipalFactory。
示例代码:
public override async Task<ClaimsPrincipal> CreateAsync(TUser user)
{
if (user == null)
{
throw new ArgumentNullException("user");
}
// base class takes care of all the default stuff like roles name id etc
var principal = await base.CreateAsync(user);
if (principal.Identity is ClaimsIdentity)
{
var identity = (ClaimsIdentity)principal.Identity;
// add logic to get the clientid
var clientId = yourmethod();
var clientIdClaim = new Claim("ClientId", clientId);
identity.AddClaim(clientIdClaim);
}
}
然后,您可以制作一个扩展方法,以便轻松获取客户端ID声明
public static string GetClientId(this ClaimsPrincipal principal)
{
if (principal == null)
{
throw new ArgumentNullException(nameof(principal));
}
var claim = principal.FindFirst("ClientId");
return claim != null ? claim.Value : null;
}
然后在控制器中你可以使用var cleintId = User.GetClientId();