簡體   English   中英

ASP.NET CORE中的自定義身份驗證和更新聲明

[英]Custom Authentication & Update Claims in ASP.NET CORE

我正在使用ASP.NET CORE開發網站,該網站使用Claims for User Authentication和User Id以及其他信息保存在Claims中,這是安全性嗎?

ClaimsIdentity identity = new ClaimsIdentity(
                new[]
                {
                    new Claim(ClaimTypes.Name, userInfo.Name),
                    new Claim(ClaimTypes.Surname, userInfo.Surname),
                    new Claim("Image", userInfo.Image),
                    new Claim(ClaimTypes.NameIdentifier,result.Id.ToString()),
                    new Claim(ClaimTypes.IsPersistent, loginViewModel.RememberMe.ToString())
                },
                CookieName.User);
            HttpContext.SignOutAsync(CookieName.User).Wait();
            HttpContext.SignInAsync(CookieName.User, new ClaimsPrincipal(identity),
                new AuthenticationProperties
                {
                    IsPersistent = loginViewModel.RememberMe,
                    AllowRefresh = true
                }).Wait();

有時我需要更改用戶信息,並且使用它。 這是安全的方法嗎?

//Get 
int id = int.Parse(new ClaimsCookie(HttpContext).GetValue(CookieName.User, KeyName.Id));

//Set Update
new ClaimsCookie(HttpContext).SetValue(CookieName.User, new[] { KeyName.Name, KeyName.Surname }, new[] { model.Name, model.Surname });

類:

namespace ...
{
    public class ClaimsCookie
    {
        private readonly HttpContext _httpContext;
        public ClaimsCookie(HttpContext httpContext)
        {
            _httpContext = httpContext;
        }

        public string GetValue(string cookieName, string keyName)
        {
            var principal = _httpContext.User;
            var cp = principal.Identities.First(i => i.AuthenticationType == cookieName.ToString());
            return cp.FindFirst(keyName).Value;
        }
        public async void SetValue(string cookieName, string[] keyName, string[] value)
        {
            if (keyName.Length != value.Length)
            {
                return;
            }
            if (_httpContext == null)
                return;
            var principal = _httpContext.User;
            var cp = principal.Identities.First(i => i.AuthenticationType == cookieName.ToString());
            for (int i = 0; i < keyName.Length; i++)
            {
                if (cp.FindFirst(keyName[i]) != null)
                {
                    cp.RemoveClaim(cp.FindFirst(keyName[i]));
                    cp.AddClaim(new Claim(keyName[i], value[i]));
                }

            }
            await _httpContext.SignOutAsync(cookieName);
            await _httpContext.SignInAsync(cookieName, new ClaimsPrincipal(cp),
                new AuthenticationProperties
                {
                    IsPersistent = bool.Parse(cp.FindFirst(KeyName.IsPersistent).Value),
                    AllowRefresh = true
                });
        }
        public async void SetValue(string cookieName, string keyName, string value)
        {
            var principal = _httpContext.User;
            var cp = principal.Identities.First(i => i.AuthenticationType == cookieName.ToString());

            if (cp.FindFirst(keyName) != null)
            {
                cp.RemoveClaim(cp.FindFirst(keyName));
                cp.AddClaim(new Claim(keyName, value));
            }
            await _httpContext.SignOutAsync(cookieName);
            await _httpContext.SignInAsync(cookieName, new ClaimsPrincipal(cp),
                new AuthenticationProperties
                {
                    IsPersistent = bool.Parse(cp.FindFirst(KeyName.IsPersistent).Value),
                    AllowRefresh = true
                });
        }
    }
    public static class CookieName
    {
        public static string Company => "CompanyUserProfilCookie";
        public static string User => "UserProfilCookie";
        public static string Admin => "AdminPanelCookie";
    }

    public static class KeyName
    {
        public static string Id => ClaimTypes.NameIdentifier;
        public static string Name => ClaimTypes.Name;
        public static string Surname => ClaimTypes.Surname;
        public static string IsPersistent => ClaimTypes.IsPersistent;
        public static string Image => "Image";
    }
}

我從任何Controller都將HttpContext設置為此類。 有什么辦法靜態HttpContext,我不想從Controller設置嗎?

一種選擇是從DI注入IHttpContextAccessor從中訪問HttpContext

更改ClaimsCookie構造函數以反映以下內容:

private readonly HttpContext _httpContext;
public ClaimCookie(IHttpContextAccessor contextAccessor)
{
    _httpContext = contextAccessor.HttpContext;
}

接下來,您需要在Startup.ConfigureServices中注冊IHttpContextAccessor和ClaimCookie:

public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpContextAccessor();
    services.AddTransient<ClaimCookie>();
    ...rest of code ommited...
}

然后注入您的類,使用時無需自己提供HttpContext:

public class SomeController : Controller
{
    private readonly ClaimCookie _claimCookie;

    public SomeController(ClaimCookie claimCookie)
    {
        _claimCookie = claimCookie;
    }

    public async Task<IActionResult> SomeAction()
    {
        int id = int.Parse(_claimCookie.GetValue(CookieName.User, KeyName.Id));
        await _claimCookie.SetValue(CookieName.User, new[] { KeyName.Name, KeyName.Surname }, new[] { model.Name, model.Surname });
        ...
    }

還請閱讀msdn在異步編程中的最佳實踐,為什么不應該使用async void
關於安全性(不是專家),您也不應在Cookie中存儲敏感數據,如果需要,則應存儲加密數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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