在ASP.NET Core 2.1中,基于角色的权限控制与JWT(JSON Web Token)确实存在兼容性问题。这是因为在2.1版本中,ASP.NET Core使用了新的策略授权系统,而JWT默认只支持基于声明的授权。
为了解决这个问题,可以使用自定义的ClamsTransformer来将JWT中的角色声明转换为策略声明。以下是示例代码:
首先,创建一个自定义的ClaimsTransformer类,继承自ClaimsAuthenticationManager:
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
public class CustomClaimsTransformer : IClaimsTransformation
{
public Task TransformAsync(ClaimsPrincipal principal)
{
((ClaimsIdentity)principal.Identity).AddClaims(TransformRolesToClaims(principal));
return Task.FromResult(principal);
}
private static IEnumerable TransformRolesToClaims(ClaimsPrincipal principal)
{
var roleClaims = principal.FindAll(ClaimTypes.Role);
var transformedClaims = new List();
foreach (var roleClaim in roleClaims)
{
var claim = new Claim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", roleClaim.Value);
transformedClaims.Add(claim);
}
return transformedClaims;
}
}
然后,在Startup.cs中的ConfigureServices方法中注册自定义的ClaimsTransformer:
public void ConfigureServices(IServiceCollection services)
{
// 省略其他代码
services.AddTransient();
}
最后,在控制器中使用Authorize标记来限制访问:
[Authorize(Roles = "Admin")]
public class AdminController : Controller
{
// 控制器代码
}
这样,当用户使用JWT进行身份验证时,角色声明将会被转换为策略声明,并在授权过程中起作用。只有具有"Admin"角色的用户才能访问AdminController中的动作方法。
注意:以上代码仅适用于ASP.NET Core 2.1版本。在其他版本中可能需要进行一些调整。