Caching Claims in .net core 2.0

狂风中的少年 提交于 2019-11-30 15:21:17

You can inject the IMemoryCache service in your ClaimsTransformer constructor.

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

I am not doing the exact same thing, but I am using cookie Authentication/Authorization. Most of what I learned comes from this microsoft doc but as you said the documentation doesn't seem to take you all the way there. Here is what is working for me:

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

And then in your controller that handles authentication:

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

I am unsure if you can use cookies with windows authentication. However if you can authenticate and assign loggedIn the result of your authentication request, you should be able to store some sort of claim(s) in the cookie. You can then recall that claim in a controller that might be doing authorization/recalling values using the following:

    [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);
        }
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!