在 .net core 2.0 中缓存声明
Caching Claims in .net core 2.0
到处查找,但看起来我现在被卡住了。我在我的应用程序中使用 Windows Active Directory 进行身份验证。
对于授权,我正在使用声明。在有限的 .net 核心文档中搜索后,这就是我的代码的样子。
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IPrincipal>(
provider => provider.GetService<IHttpContextAccessor>().HttpContext.User);
services.AddTransient<IClaimsTransformation, ClaimsTransformer>();
services.AddAuthentication(IISDefaults.AuthenticationScheme);
}
ClaimsTransformer.cs
class ClaimsTransformer : IClaimsTransformation
{
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
// call to database to get more claims based on user id ClaimsIdentity.Name
((ClaimsIdentity)principal.Identity).AddClaim(new Claim("now",DateTime.Now.ToString()));
return Task.FromResult(principal);
}
}
但问题是,每次请求都会调用此代码,并且每次都从数据库加载声明,这是绝对错误的。有什么办法可以缓存它吗?我能够创建一个声明 cookie 并将该 cookie 用于 .net 4.0 中的任何进一步调用。我似乎无法在核心中找到方法。我检查的任何文档都不完整或没有涵盖我的场景。我可以在我的申请中进一步声明文档在此处的说法:https://docs.microsoft.com/en-us/aspnet/core/security/authorization/claims
但是没有提到缓存声明。
有人在同一条船上吗?或者知道出路吗?
我没有做完全相同的事情,但我正在使用 cookie Authentication/Authorization。我学到的大部分内容来自 this microsoft doc,但正如您所说,文档似乎并没有带您一路走来。这是对我有用的:
在startup.cs
public void ConfigureServices(IServiceCollection services)
{
...
services.AddAuthentication("tanushCookie")
.AddCookie("tanushCookie", options => {
options.AccessDeniedPath = "/api/Auth/Forbidden";
options.LoginPath = "/";
options.Cookie.Expiration = new TimeSpan(7,0,0,0);
});
}
public void Configure(IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
...
app.UseAuthentication();
}
然后在处理身份验证的控制器中:
[HttpPost()]
[Route("api/[Controller]/[Action]/")]
public async Task<JsonResult> Login([FromBody]Dictionary<string, string> loginData)
{
try
{
var loggedIn = true;
if (loggedIn)
{
var claims = new List<Claim> {
new Claim(ClaimTypes.Name, "tanush")
};
var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
identity.AddClaims(claims);
ClaimsPrincipal principal = new ClaimsPrincipal(identity);
await HttpContext.SignInAsync(
"tanushCookie",
principal,
new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTime.UtcNow.AddDays(7)
});
}
return new JsonResult(logRtn);
}
catch (Exception ex)
{
return new JsonResult(ex.Message);
}
}
我不确定您是否可以使用带有 windows 身份验证的 cookie。但是,如果您可以对身份验证请求的结果进行身份验证和分配 loggedIn,则您应该能够在 cookie 中存储某种声明。然后,您可以使用以下命令在可能正在执行 authorization/recalling 值的控制器中调用该声明:
[HttpGet("[Action]", Name = "GetSomething")]
[Route("[Action]")]
public JsonResult something()
{
try
{
var loggedInUser = HttpContext.User;
var claym = loggedInUser.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Name);
if (claym != null)
{
return new JsonResult(claym.Value);
// returns "tanush"
}
else
{
return new JsonResult("");
}
}
catch (Exception ex)
{
return new JsonResult(ex.Message);
}
}
您可以在 ClaimsTransformer
构造函数中注入 IMemoryCache
服务。
using Microsoft.Extensions.Caching.Memory;
public class ClaimsTransformer : IClaimsTransformation
{
private readonly IMemoryCache _cache;
public ClaimsTransformer(IMemoryCache cache)
{
_cache = cache;
}
public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var cacheKey = principal.FindFirstValue(ClaimTypes.NameIdentifier);
if (_cache.TryGetValue(cacheKey, out List<Claim> claims)
{
((ClaimsIdentity)principal.Identity).AddClaims(claims);
}
else
{
claims = new List<Claim>();
// call to database to get more claims based on user id ClaimsIdentity.Name
_cache.Set(cacheKey, claims);
}
return principal;
}
}
到处查找,但看起来我现在被卡住了。我在我的应用程序中使用 Windows Active Directory 进行身份验证。 对于授权,我正在使用声明。在有限的 .net 核心文档中搜索后,这就是我的代码的样子。
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IPrincipal>(
provider => provider.GetService<IHttpContextAccessor>().HttpContext.User);
services.AddTransient<IClaimsTransformation, ClaimsTransformer>();
services.AddAuthentication(IISDefaults.AuthenticationScheme);
}
ClaimsTransformer.cs
class ClaimsTransformer : IClaimsTransformation
{
public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
// call to database to get more claims based on user id ClaimsIdentity.Name
((ClaimsIdentity)principal.Identity).AddClaim(new Claim("now",DateTime.Now.ToString()));
return Task.FromResult(principal);
}
}
但问题是,每次请求都会调用此代码,并且每次都从数据库加载声明,这是绝对错误的。有什么办法可以缓存它吗?我能够创建一个声明 cookie 并将该 cookie 用于 .net 4.0 中的任何进一步调用。我似乎无法在核心中找到方法。我检查的任何文档都不完整或没有涵盖我的场景。我可以在我的申请中进一步声明文档在此处的说法:https://docs.microsoft.com/en-us/aspnet/core/security/authorization/claims
但是没有提到缓存声明。
有人在同一条船上吗?或者知道出路吗?
我没有做完全相同的事情,但我正在使用 cookie Authentication/Authorization。我学到的大部分内容来自 this microsoft doc,但正如您所说,文档似乎并没有带您一路走来。这是对我有用的:
在startup.cs
public void ConfigureServices(IServiceCollection services)
{
...
services.AddAuthentication("tanushCookie")
.AddCookie("tanushCookie", options => {
options.AccessDeniedPath = "/api/Auth/Forbidden";
options.LoginPath = "/";
options.Cookie.Expiration = new TimeSpan(7,0,0,0);
});
}
public void Configure(IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
...
app.UseAuthentication();
}
然后在处理身份验证的控制器中:
[HttpPost()]
[Route("api/[Controller]/[Action]/")]
public async Task<JsonResult> Login([FromBody]Dictionary<string, string> loginData)
{
try
{
var loggedIn = true;
if (loggedIn)
{
var claims = new List<Claim> {
new Claim(ClaimTypes.Name, "tanush")
};
var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
identity.AddClaims(claims);
ClaimsPrincipal principal = new ClaimsPrincipal(identity);
await HttpContext.SignInAsync(
"tanushCookie",
principal,
new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTime.UtcNow.AddDays(7)
});
}
return new JsonResult(logRtn);
}
catch (Exception ex)
{
return new JsonResult(ex.Message);
}
}
我不确定您是否可以使用带有 windows 身份验证的 cookie。但是,如果您可以对身份验证请求的结果进行身份验证和分配 loggedIn,则您应该能够在 cookie 中存储某种声明。然后,您可以使用以下命令在可能正在执行 authorization/recalling 值的控制器中调用该声明:
[HttpGet("[Action]", Name = "GetSomething")]
[Route("[Action]")]
public JsonResult something()
{
try
{
var loggedInUser = HttpContext.User;
var claym = loggedInUser.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Name);
if (claym != null)
{
return new JsonResult(claym.Value);
// returns "tanush"
}
else
{
return new JsonResult("");
}
}
catch (Exception ex)
{
return new JsonResult(ex.Message);
}
}
您可以在 ClaimsTransformer
构造函数中注入 IMemoryCache
服务。
using Microsoft.Extensions.Caching.Memory;
public class ClaimsTransformer : IClaimsTransformation
{
private readonly IMemoryCache _cache;
public ClaimsTransformer(IMemoryCache cache)
{
_cache = cache;
}
public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
{
var cacheKey = principal.FindFirstValue(ClaimTypes.NameIdentifier);
if (_cache.TryGetValue(cacheKey, out List<Claim> claims)
{
((ClaimsIdentity)principal.Identity).AddClaims(claims);
}
else
{
claims = new List<Claim>();
// call to database to get more claims based on user id ClaimsIdentity.Name
_cache.Set(cacheKey, claims);
}
return principal;
}
}