在.net core 2.0中缓存声明

到处看,但看起来我现在被卡住了。 我在我的应用程序中使用Windows Active Directory进行身份validation。 对于授权,我正在使用索赔。 在搜索有限的.net核心文档后,这就是我的代码的样子。

Startup.cs

public void ConfigureServices(IServiceCollection services) { services.AddTransient( provider => provider.GetService().HttpContext.User); services.AddTransient(); services.AddAuthentication(IISDefaults.AuthenticationScheme); } 

ClaimsTransformer.cs

 class ClaimsTransformer : IClaimsTransformation { public Task 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); } } 

但问题是,每次请求都会调用此代码,并且每次从db加载声明都是绝对错误的。 有什么方法可以缓存它吗? 我能够创建一个声明的cookie,并使用该cookie进行.net 4.0中的任何进一步调用。 我似乎无法找到核心方式。 我检查的任何文档都不完整,或者不包括我的场景。 我可以在我的应用程序中进一步声明文档中的说明: https : //docs.microsoft.com/en-us/aspnet/core/security/authorization/claims

但是没有提到缓存声明。

在同一条船上的任何人? 还是知道出路呢?

您可以在ClaimsTransformer构造函数中注入IMemoryCache服务。

 using Microsoft.Extensions.Caching.Memory; public class ClaimsTransformer : IClaimsTransformation { private readonly IMemoryCache _cache; public ClaimsTransformer(IMemoryCache cache) { _cache = cache; } public async Task TransformAsync(ClaimsPrincipal principal) { var cacheKey = principal.FindFirstValue(ClaimTypes.NameIdentifier); if (_cache.TryGetValue(cacheKey, out List claims) { ((ClaimsIdentity)principal.Identity).AddClaims(claims); } else { claims = new List(); // call to database to get more claims based on user id ClaimsIdentity.Name _cache.Set(cacheKey, claims); } return principal; } } 

我没有做同样的事情,但我正在使用cookie身份validation/授权。 我学到的大部分内容来自这个微软文档,但正如你所说的那样,文档似乎并没有把你带到那里。 这是为我工作的:

在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(); } 

然后在处理身份validation的控制器中:

  [HttpPost()] [Route("api/[Controller]/[Action]/")] public async Task Login([FromBody]Dictionary loginData) { try { var loggedIn = true; if (loggedIn) { var claims = new List { 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身份validation的cookie。 但是,如果您可以对身份validation请求的结果进行身份validation和分配,则应该能够在cookie中存储某种声明。 然后,您可以使用以下内容在可能正在执行授权/调用值的控制器中调用该声明:

  [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); } }