简体   繁体   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

I am using token validation middleware to authenticate user, which hits another server for this.我正在使用令牌验证中间件来验证用户,这会为此访问另一台服务器。 But the issue is, it will always checks the token even if not required, ie while using Register API or any other which doesn't need any validation.但问题是,即使不需要,它也会始终检查令牌,即在使用注册 API 或任何其他不需要任何验证的情况下。

This is my TokenValidationMiddleware.cs file.这是我的 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);
    }

This middleware always checks token validation for every request raised.这个中间件总是为每个提出的请求检查令牌验证。

I want to bypass this middleware for the anonymous requests, or the requests which does not have any [Authorize] attribute above controller or specific endpoint.我想为匿名请求或在控制器或特定端点之上没有任何 [Authorize] 属性的请求绕过此中间件。

One solution is to store all the anonymous endpoints somewhere and put a check on middleware, which is not correct at all.一种解决方案是将所有匿名端点存储在某处并检查中间件,这根本不正确。

Other is to modify the routes of all the secure endpoints as 'api/secure/[controller]', but for that I have to modify all the endpoints in backend as well as frontend.另一个是将所有安全端点的路由修改为“api/secure/[controller]”,但为此我必须修改后端和前端的所有端点。 Which is also not a good approach.这也不是一个好方法。

Kindly suggest a solution for this.请为此提出解决方案。

Thanks in advance.提前致谢。

You could check endpoint against IAuthorizeData in your middleware:您可以在中间件中根据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);
}

You could also check the opposite: against IAllowAnonymous , if endpoint has [AllowAnonymous] attribute.您还可以检查相反的情况:针对IAllowAnonymous ,如果端点具有[AllowAnonymous]属性。

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

Ps ps

You may check the ASP.NET Core Authorization MiddleWare source code for the inspiration.您可以查看 ASP.NET Core Authorization MiddleWare 源代码以获取灵感。

Middlewares are like .net Handlers.中间件就像 .net 处理程序。 They are to be used when you don't need Controller specific data: asp.net core middleware vs filters当您不需要控制器特定数据时将使用它们: asp.net 核心中间件 vs 过滤器

On the other hand, you can use custom policy providers like this: https://docs.microsoft.com/en-us/aspnet/core/security/authorization/iauthorizationpolicyprovider?view=aspnetcore-3.1另一方面,您可以使用这样的自定义策略提供程序: https : //docs.microsoft.com/en-us/aspnet/core/security/authorization/iauthorizationpolicyprovider?view=aspnetcore-3.1

Using an external service to provide policy evaluation.使用外部服务提供策略评估。

Using a large range of policies (for different room numbers or ages, for example), so it doesn't make sense to add each individual authorization policy with an AuthorizationOptions.AddPolicy call.使用大量策略(例如,针对不同的房间号或年龄),因此通过 AuthorizationOptions.AddPolicy 调用添加每个单独的授权策略是没有意义的。

Creating policies at runtime based on information in an external data source (like a database) or determining authorization requirements dynamically through another mechanism.根据外部数据源(如数据库)中的信息在运行时创建策略或通过另一种机制动态确定授权要求。

Thus, you can use an attribute like BypassAuth which will invoke the non authorization for specific actions and let all the rest go through another which will be set as default.因此,您可以使用像BypassAuth这样的属性,它将为特定操作调用非授权,并让所有其余操作通过另一个将设置为默认值的属性。

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

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