簡體   English   中英

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

但問題是,每次請求都會調用此代碼,並且每次都會從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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM