簡體   English   中英

將自定義 AuthenticationHandler 添加到外部登錄提供程序列表

[英]Adding a custom AuthenticationHandler to a list of external login providers

我使用的是 ASP.NET Core 3.1,並且配置了多個外部登錄提供程序:

services.AddAuthentication()
    .AddDeviantArt(d => {
        d.Scope.Add("feed");
        d.ClientId = Configuration["Authentication:DeviantArt:ClientId"];
        d.ClientSecret = Configuration["Authentication:DeviantArt:ClientSecret"];
        d.SaveTokens = true;
    })
    .AddTwitter(t => {
        t.ConsumerKey = Configuration["Authentication:Twitter:ConsumerKey"];
        t.ConsumerSecret = Configuration["Authentication:Twitter:ConsumerSecret"];
        t.SaveTokens = true;
    });

我想創建一個自定義AuthenticationProvider ,而不是重定向到另一個網站,而是要求該網站的“API 密鑰”並將其視為訪問令牌。 (有問題的網站不支持任何版本的 OAuth。)

在實際連接之前,我想測試一下我是否可以讓自定義的AuthenticationProvider工作,所以我找到了一個實現 HTTP Basic 身份驗證的:

public class CustomAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions> {
    public CustomAuthenticationHandler(
        IOptionsMonitor<AuthenticationSchemeOptions> options,
        ILoggerFactory logger,
        UrlEncoder encoder,
        ISystemClock clock)
        : base(options, logger, encoder, clock) { }

    protected override async Task<AuthenticateResult> HandleAuthenticateAsync() {
        if (!Request.Headers.ContainsKey("Authorization")) {
            return AuthenticateResult.NoResult();
        }

        if (!AuthenticationHeaderValue.TryParse(Request.Headers["Authorization"], out AuthenticationHeaderValue headerValue)) {
            return AuthenticateResult.NoResult();
        }

        if (!"Basic".Equals(headerValue.Scheme, StringComparison.OrdinalIgnoreCase)) {
            return AuthenticateResult.NoResult();
        }

        byte[] headerValueBytes = Convert.FromBase64String(headerValue.Parameter);
        string userAndPassword = Encoding.UTF8.GetString(headerValueBytes);
        string[] parts = userAndPassword.Split(':');
        if (parts.Length != 2) {
            return AuthenticateResult.Fail("Invalid Basic authentication header");
        }
        string user = parts[0];
        string password = parts[1];

        bool isValidUser = true;

        if (!isValidUser) {
            return AuthenticateResult.Fail("Invalid username or password");
        }
        var claims = new[] { new Claim(ClaimTypes.Name, user) };
        var identity = new ClaimsIdentity(claims, Scheme.Name);
        var principal = new ClaimsPrincipal(identity);
        var ticket = new AuthenticationTicket(principal, Scheme.Name);
        return AuthenticateResult.Success(ticket);
    }

    protected override async Task HandleChallengeAsync(AuthenticationProperties properties) {
        Response.Headers["WWW-Authenticate"] = $"Basic realm=\"Custom realm name here\", charset=\"UTF-8\"";
        await base.HandleChallengeAsync(properties);
    }
}

我將此添加到 Startup.cs:

.AddScheme<AuthenticationSchemeOptions, CustomAuthenticationHandler>("Test", "Testing", o => { })

問題是從不調用HandleAuthenticateAsync方法。 我找到的解決此問題的其他解決方案通常說您需要將其設為“默認”身份驗證方案,但我不希望這會干擾其他外部登錄提供程序的設置方式。

有沒有一種方法可以在不更改默認身份驗證方案或向控制器或操作添加其他屬性的情況下使其正常工作?

添加AddAuthentication時需要添加默認 Scheme

services.AddAuthentication("Test")

暫無
暫無

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

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