如何在调用 API 之前按用户角色过滤 ASP.NET Core 中的请求

问题描述 投票:0回答:1

我有一个由 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 之前返回未经授权的状态代码?一种基于路由角色的过滤器?

.net-core blazor asp.net-core-webapi asp.net-authorization
1个回答
0
投票

您可以尝试实现一个自定义中间件来在 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();
© www.soinside.com 2019 - 2024. All rights reserved.