簡體   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