我有一个由 JWT 保护并启用授权的 ASP.NET Core Web API。 Blazor 客户端应用程序正在使用该 API。我正在使用基于 REFIT 的服务从客户端调用 API。授权基于角色且运作良好。但是,我想添加一个中间服务,让我可以根据登录的用户角色在调用 API 之前过滤 API 请求/路由。
换句话说,我想添加第二个安全层,并在不允许此类角色的路由时阻止请求 API,并在到达 API 之前短路请求。我的灵感来自 paths/web.php 中使用的 Laravel 框架中间件概念,其中每个路由都在此文件中声明和命名,并且中间件基于用户角色,防止未经授权的用户访问 API。我知道在 .NET Core 中,API 已经很好地管理了授权,但是因为会有很多请求,所以如果特定角色不允许路由,我想防止不必要地调用 API。
我尝试添加一个
ActionFilter
,但是先调用API,然后调用过滤器,这不是我想要的行为。我在中间件中尝试过,但得到了相同的结果。
是否有任何方法可以实现全局服务(作为 API 或 Blazor 客户端应用程序的入口点)来检查记录的用户角色并在到达 API 之前返回未经授权的状态代码?一种基于路由角色的过滤器?
您可以尝试实现一个自定义中间件来在 webapi 中进行身份验证之前解码 accesstoken。
public class CustomMiddleware
{
private readonly RequestDelegate _next;
public CustomMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
string accessToken = httpContext.Request.Headers["Authorization"].FirstOrDefault()?.Split(' ')[1];
if (accessToken != null)
{
var handler = new JwtSecurityTokenHandler();
var jsonToken = handler.ReadToken(accessToken) as JwtSecurityToken;
var roleClaim = jsonToken.Claims.FirstOrDefault(x => x.Type == ClaimTypes.Role);
if ((roleClaim!= null)&&(roleClaim.Value== "Admin"))
{
}
else
{
httpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
await httpContext.Response.WriteAsync("Role invalid");
}
}
else
{
httpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
await httpContext.Response.WriteAsync("Authorization header missing");
}
await _next(httpContext);
}
}
然后在program.cs中在路由之前使用它。
app.UseMiddleware<CustomMiddleware>();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();