繁体   English   中英

来自不同服务器的令牌认证(身份服务器 4)通过中间件,但它会检查所有不需要授权的端点

[英]Token Authentication (Identity Server 4) from different server thru middleware, but it checks for all endpoints which doesn't needed to be authorized

我正在使用令牌验证中间件来验证用户,这会为此访问另一台服务器。 但问题是,即使不需要,它也会始终检查令牌,即在使用注册 API 或任何其他不需要任何验证的情况下。

这是我的 TokenValidationMiddleware.cs 文件。

public async Task Invoke(HttpContext httpContext, UserManager<ApplicationUser> userManager)
    {
        _userManager = userManager;

        // **>>>>>BELOW CHECK IS MANUAL, WHICH IS ALSO NOT CORRECT.<<<<<**
        if (!httpContext.Request.Path.StartsWithSegments("/api/Authentication/Login") && !httpContext.Request.Path.StartsWithSegments("/api/Authentication/Refresh"))
        {
            var headerKeys = httpContext.Request.Headers.Keys;

            // **issue comes here**
            // **it always discard the request which does not have any token.**
            if (headerKeys.Contains("Authorization"))
            {
                // validation code, which hits another server.                       
            }
            else
            {
                httpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                await httpContext.Response.WriteAsync("Unauthorized Access");
                return;
            }
        }

        await _next.Invoke(httpContext);
    }

这个中间件总是为每个提出的请求检查令牌验证。

我想为匿名请求或在控制器或特定端点之上没有任何 [Authorize] 属性的请求绕过此中间件。

一种解决方案是将所有匿名端点存储在某处并检查中间件,这根本不正确。

另一个是将所有安全端点的路由修改为“api/secure/[controller]”,但为此我必须修改后端和前端的所有端点。 这也不是一个好方法。

请为此提出解决方案。

提前致谢。

您可以在中间件中根据IAuthorizeData检查端点:

public async Task Invoke(HttpContext httpContext, UserManager<ApplicationUser> userManager)
{
    _userManager = userManager;


    // Check if endpoint has any authorize data, like [Authorize] attribute
    var endpoint = httpContext.GetEndpoint();
    var authorizeData = endpoint?.Metadata.GetOrderedMetadata<IAuthorizeData>();
    if (authorizeData != null && authorizeData.Any())
    {

        // If you need to depend on particular scheme ("Bearer" in my example):
        var scheme = authorizeData[0].AuthenticationSchemes;
        if (scheme == JwtBearerDefaults.AuthenticationScheme)
        {
            // Code only for "Bearer" auth scheme
        }


        var headerKeys = httpContext.Request.Headers.Keys;

        // **issue comes here**
        // **it always discard the request which does not have any token.**
        if (headerKeys.Contains("Authorization"))
        {
            // validation code, which hits another server.                       
        }
        else
        {
            httpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
            await httpContext.Response.WriteAsync("Unauthorized Access");
            return;
        }
    }

    await _next.Invoke(httpContext);
}

您还可以检查相反的情况:针对IAllowAnonymous ,如果端点具有[AllowAnonymous]属性。

if (endpoint?.Metadata.GetMetadata<IAllowAnonymous>() != null)

ps

您可以查看 ASP.NET Core Authorization MiddleWare 源代码以获取灵感。

中间件就像 .net 处理程序。 当您不需要控制器特定数据时将使用它们: asp.net 核心中间件 vs 过滤器

另一方面,您可以使用这样的自定义策略提供程序: https : //docs.microsoft.com/en-us/aspnet/core/security/authorization/iauthorizationpolicyprovider?view=aspnetcore-3.1

使用外部服务提供策略评估。

使用大量策略(例如,针对不同的房间号或年龄),因此通过 AuthorizationOptions.AddPolicy 调用添加每个单独的授权策略是没有意义的。

根据外部数据源(如数据库)中的信息在运行时创建策略或通过另一种机制动态确定授权要求。

因此,您可以使用像BypassAuth这样的属性,它将为特定操作调用非授权,并让所有其余操作通过另一个将设置为默认值的属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM