簡體   English   中英

ASP.NET Core Jwt實現Signinmanager聲明

[英]ASP.NET Core Jwt implement signinmanager claims

我已經實現了Jwt作為驗證用戶身份的方法。 但是,我對如何在應用程序上執行某些角色方面的工作感到困惑。 目前,我的Jwt令牌包含用戶的電子郵件,電話,ID和他們具有的角色列表。

我對該令牌所做的操作如下:

[TypeFilter(typeof(ValidateRolesFilter), Arguments = new object[] {
        ApplicationGlobals.ApplicationSecretKey, RoleGlobals.SystemAdministrator
})]
public IActionResult Index()
{
    return View();
}

我的Typefilter包含一個rest請求,該請求將令牌發送到另一個應用程序以驗證我的用戶是否可以訪問該Function。 但是,當涉及到視圖時,我陷入了困境。 我想對某些容器進行細分,以允許具有特定角色的某些用戶查看它們。

我有一個想法,如果我像非jwt應用程序一樣將用戶聲明添加到signinmanager中,則可以從httpcontext中獲得聲明。 但是,我不知道我擁有的東西是否可以與使用jwt的應用程序一起使用。

public async Task SignInUserAsync(TIdentityUser user, bool isPersistent, IEnumerable<Claim> customClaims)
{
    var claimsPrincipal = await _signInManager.CreateUserPrincipalAsync(user);
    var identity = claimsPrincipal.Identity as ClaimsIdentity;
    var claims = (from c in claimsPrincipal.Claims select c).ToList();
    var savedClaims = claims;
    foreach (var item in claims)
    {
        identity.RemoveClaim(item);
    }
    if (customClaims != null)
    {
        identity.AddClaim(savedClaims[0]);
        identity.AddClaim(savedClaims[1]);
        identity.AddClaim(savedClaims[2]);
        identity.AddClaims(customClaims);
    }
    await _signInManager.Context.SignInAsync(IdentityConstants.ApplicationScheme,
        claimsPrincipal,
        new AuthenticationProperties { IsPersistent = isPersistent });
}

我最近在JWT上做一個合作項目。 我編寫了一個中間件,當用戶向api請求時,它就會由身份驗證中間件檢查。 我從db中讀取了userRole並將其放在我共享中間件代碼的身份原則中。

在這里,我閱讀了JWT中間部分以提取用戶信息

public class AuthenticationMiddleware
{
    private readonly RequestDelegate _next;

    // Dependency Injection
    public AuthenticationMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        string authHeader = context.Request.Headers["Authorization"];

        if (authHeader != null)
        {              
            int startPoint = authHeader.IndexOf(".") + 1;               
            int endPoint = authHeader.LastIndexOf(".");

            var tokenString = authHeader.Substring(startPoint, endPoint - startPoint).Split(".");
            var token = tokenString[0].ToString()+"==";

            var credentialString = Encoding.UTF8
                .GetString(Convert.FromBase64String(token));

            // Splitting the data from Jwt
            var credentials = credentialString.Split(new char[] { ':',',' });

            // Trim this string.
            var userRule = credentials[5].Replace("\"", ""); 
            var userName = credentials[3].Replace("\"", "");

             // Identity Principal
            var claims = new[]
            {
                new Claim("name", userName),
                new Claim(ClaimTypes.Role, userRule),

            };
            var identity = new ClaimsIdentity(claims, "basic");
            context.User = new ClaimsPrincipal(identity);
        }
        await _next(context);
    }


}

在startup.cs中,您需要在configure method調用此中間件

 app.UseMiddleware<AuthenticationMiddleware>();

在控制器中

 [HttpGet("GetUsers")]
  [Authorize(Roles = "admin")]
    public ActionResult GetUsers()
    {
        var users = _authRepository.GetUsers();
        return Ok(users);
    }

如果您需要任何幫助,請發表評論。 這個實現確實對我有用。 檢查我關於此主題的存儲庫: https : //github.com/hidayatarg/Asp.net-Core-2.1-Jwt-Authentication-Middleware https://github.com/hidayatarg/Decode-JWT-Token

JSON Web令牌由以點(。)分隔的三部分組成:Header,Payload,Signature。因此,JWT通常看起來像xxxxx.yyyyy.zzzzz。令牌的第二部分是有效負載,其中包含聲明。 。

您可以解碼訪問令牌以獲得與您的角色有關的聲明:

如何解碼JWT令牌?

使用System.IdentityModel.Tokens.Jwt解碼和驗證JWT令牌

如果您使用Owin OpenID Connect中間件從身份提供者(如Azure AD,Idenity服務器4 ...)對用戶進行身份驗證,則可以在OnTokenValidated事件下向主體添加其他聲明。

編輯:

您還可以在登錄前將聲明(解碼並獲得聲明)添加到用戶上下文中:

 var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme, ClaimTypes.Name, ClaimTypes.Role);
 identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, loginData.Username));
 identity.AddClaim(new Claim(ClaimTypes.Name, loginData.Username));
 //add your custom claims 
 ....

 var principal = new ClaimsPrincipal(identity);
 await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal, new AuthenticationProperties { IsPersistent = loginData.RememberMe });

參考: http : //future-shock.net/blog/post/creating-a-simple-login-in-asp.net-core-2-using-authentication-and-authorization-not-identity

然后,您可以在視圖中訪問聲明,例如:

@foreach (var item in Context.User.Claims)
{
    <p>@item.Value</p> 
}; 

暫無
暫無

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

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