ASP.NET Core Jwt实现签名管理器声明



我已经实现了Jwt作为对用户进行身份验证的一种方式。然而,我一直在思考如何在我的应用程序中完成与角色相关的某些事情。目前,我的Jwt令牌包含用户的电子邮件、电话、id和他们拥有的角色列表。

我用这个代币做的是这样的:

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

我的Typefilter包含一个rest请求,该请求将令牌发送到另一个应用程序,以验证我的用户是否可以访问该函数。然而当谈到景色时,我被卡住了。我想对某些容器进行分段,以允许具有特定角色的某些用户查看。

我有一个想法,如果我像非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时,它会被身份验证中间件检查。我从数据库中读取了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-Middlewarehttps://github.com/hidayatarg/Decode-JWT-Token

JSON Web令牌由三部分组成,用点(.(分隔,它们是:Header、Payload和Signature。因此,JWT通常看起来像xxxxx.yyyy.zzzzz。令牌的第二部分是有效载荷,其中包含声明。

您可以解码访问令牌以获得与您的角色相关的声明:

如何解码JWT代币。

使用System解码和验证JWT令牌。IdentityModel。代币。Jwt

如果您正在使用Owin OpenID Connect中间件对Azure AD、identity服务器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> 
}; 

最新更新