[英]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);
}
}
但問題是,每次請求都會調用此代碼,並且每次都會從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<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;
}
}
我沒有做同樣的事情,但我正在使用cookie身份驗證/授權。 我學到的大部分內容來自這個微軟文檔,但正如你所說的那樣,文檔似乎並沒有把你帶到那里。 這是為我工作的:
在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。 但是,如果您可以對身份驗證請求的結果進行身份驗證和分配,則應該能夠在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);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.