簡體   English   中英

ASP.NET Core Web API身份驗證允許未經授權的訪問

[英]ASP.NET Core Web API Authentication allowing unauthorized access

我正在為ASP.NET Core API創建身份驗證方案。

它會調用我的處理程序,並且可以很好地達到斷點,但是即使授權失敗,API調用仍會返回結果。

protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
{
    if (!Request.Headers.ContainsKey(AuthorizationHeaderName))
    {
        //Authorization header not in request
        return AuthenticateResult.Fail("Missing Authorization header");
    }

以我的幼稚理解,如果身份驗證失敗,它不應返回數據。

我想念什么?

細節

我在Startup.ConfigureServices中注冊了這樣的方案

services.AddAuthentication(options => {
    // This (options.Default..Scheme) causes the default authentication scheme to be set.
    // Without this, the Authorization header is not checked and
    // you'll get no results. 
   options.DefaultAuthenticateScheme = BasicAuthenticationDefaults.AuthenticationScheme;
}).AddScheme<BasicAuthenticationOptions, BasicAuthenticationHandler>("Basic", null);

Startup.Config調用

 app.UseAuthentication();
 app.UseHttpsRedirection();
 app.UseMvc();

其余代碼如下所示:

using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;

namespace WebAPI.Authentication
{
    public interface IBasicAuthenticationService
    {
        Task<AuthenticateResult> HandleAuthenticateAsync();
    }

    public static class BasicAuthenticationDefaults
    {
        public const string AuthenticationScheme = "Basic";
    }

    public class BasicAuthenticationOptions : AuthenticationSchemeOptions
    { }

    public class BasicAuthenticationHandler : AuthenticationHandler<BasicAuthenticationOptions>
    {
        private const string AuthorizationHeaderName = "Authorization";
        private const string BasicSchemeName = "Basic";

        public BasicAuthenticationHandler(
            IOptionsMonitor<BasicAuthenticationOptions> options,
            ILoggerFactory logger,
            UrlEncoder encoder,
            ISystemClock clock)
            : base(options, logger, encoder, clock)
        {
        }

        protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            if (!Request.Headers.ContainsKey(AuthorizationHeaderName))
            {  // Rejected here. Should fail.
                //Authorization header not in request
                return AuthenticateResult.Fail("Missing Authorization header");
            }

            if ....  // never gets this far
            }

            return AuthenticateResult.Success(ticket);
        }
    }
}

這是不正確返回結果的控制器。

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;

namespace TMAWebAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        // GET api/values
        [HttpGet]
        public ActionResult<IEnumerable<string>> Get()
        {
            return new string[] { "value1", "value2" };
        }
    } 
}

所有這些代碼行都在調試器中被擊中,因此該部分似乎正常工作。

但是,即使驗證失敗,API調用仍會返回結果。

更新:
向Controller添加AuthenticationScheme屬性會使它失敗。
像這樣:

[Route("api/[controller]")]
[ApiController]
[Authorize(AuthenticationSchemes = "Basic")]
public class ValuesController : ControllerBase

不好 默認情況下它將失敗,而不必將其添加到每個控制器。

更新2:

向services.AddMvc添加一個過濾器看起來很有希望,但這也不起作用。 文檔聲稱由於包含了它們,因此您不必實施授權過濾器。 不是我能找到。

我繼承了AuthorizeAttribute,並使用了Matti Price和AddMvc所需的IFilterMetadata的思想。 可以編譯,但仍允許未經授權的訪問。

public class BasicAuthorizeAttribute : AuthorizeAttribute, IFilterMetadata { }       

services.AddMvc(options => {
    options.Filters.Add(typeof(BasicAuthorizeAttribute));
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

更新3:
試着

policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser()

按照Matti的建議,但是又回來了

InvalidOperationException: No authenticationScheme was specified, and there was no DefaultChallengeScheme found.

我對重定向到API的不存在的登錄頁面沒有任何興趣,因此我嘗試了

policy = new AuthorizationPolicyBuilder().AddAuthenticationSchemes(new[] {BasicAuthenticationDefaults.AuthenticationScheme })

編譯但引發異常

InvalidOperationException Message=AuthorizationPolicy must have at least one requirement.

您需要將[Authorize]屬性添加到控制器,以使授權實際上對其結果執行任何操作。 您可以像這樣在全局添加它:

services.AddMvc(config =>
{
    var policy = new AuthorizationPolicyBuilder()
                 .RequireAuthenticatedUser()
                 .Build();
    config.Filters.Add(new AuthorizeFilter(policy));
});

最終解決方案使用AddMVC。 解決方案是,除了添加方案之外,該方案還需要一個要求。

這行得通。 如果我不發送任何身份驗證標頭,它將返回一個空白頁。 如果我發送了一個過期的標頭,則它發送500。應該是401。但是它不返回任何值,而這正是我所關心的。

public class TokenAuthorizationRequirement: IAuthorizationRequirement {}

services.AddMvc(config => {
   var policy = new AuthorizationPolicyBuilder()
      .AddAuthenticationSchemes(new[] {BasicAuthenticationDefaults.AuthenticationScheme })
      .AddRequirements(new BasicAuthorizationRequirement())
      .Build();
   config.Filters.Add(new AuthorizeFilter(policy));
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM