我正在编写一个aspnet核心1应用程序。
使用承载令牌认证我在控制器内具有正确标识的User属性。但是我似乎无法像使用ClaimPrincipal.Current
静态之前那样找到一种获取身份的方法。
目前最好的做法是将这些数据放在BL层中而不传递ClaimPrincipal对象?
答案 0 :(得分:18)
进一步调查此问题我发现可以使用原生DI容器在需要的地方注入ClaimsPrincipal
:
services.AddTransient<ClaimsPrincipal>(s =>
s.GetService<IHttpContextAccessor>().HttpContext.User);
这种注入方式有点奇怪,但它比将其存储在CallContext
更好。
答案 1 :(得分:4)
以下是dotnet core 2.0和更高版本的更好答案:Simon Shine
基本上将IHttpContextAccessor作为Singleton添加到服务:
#bash/bin
OLDIFS=$IFS; IFS=$'\0' # change IFS for avoid issue with spaces
read -a sentence -p "Enter a sentence: "
IFS=$OLDIFS # IFS old value
char="k"
grep -o '.' <<< "$sentence" | grep "$char" | wc -l # first grep explode string characters, second grab character, wc count occurrences
要消耗注入IHttpContextAccessor到您的类中:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddHttpContextAccessor();
}
并在您的方法中访问_httpContextAccessor.HttpContext。
答案 2 :(得分:1)
我们知道你的问题是什么,但我们有一些经验,我看到使用参数或模型参数的每个地方(公司)用这个解决方案将用户数据发送到其他层。当你谈到安全性时,你知道安全性是主层(Web API或其他)的一部分,因为身份验证就是这一层。当你想在业务逻辑或其他层输入用户信息时,你应该传递带有方法重载的用户数据或者你想做的事情,最后这是这样做的解决方案你可以改变它并给出一个解决你的问题的模式。即使你可以使用属性来解决你的问题,并将这个属性放在你的web API层的行动中,并从用户那里获取你的数据。
扩展类(仅用于某些操作,您不需要使用它,您可以从其他方式使用),这里是..
public static class Extension
{
public static string GetUserName(this IPrincipal user)
{
var identity = (ClaimsIdentity)user.Identity;
IEnumerable<Claim> claims = identity.Claims;
return claims.FirstOrDefault(s => s.Type == "preferred_username")?.Value;
}
}
以及如何在控制器中调用它(例如API控制器)。
[HttpGet]
public async Task<UserDto> FillLocalStorage()
{
return await personBussiness.GetPersonByUserName(User.GetUserName());
}
最后我想说上面的例子只是一个解决方案。