ASP.NET Web Api 使用 OWIN - 自定义身份验证

ASP.NET Web Api with OWIN - Custom authentication

我正在尝试创建一个新的 API 密钥自定义身份验证提供程序以插入我的 OWIN 管道。 我也在使用 Cookie、OAuth 和 ADFS 提供程序。 我实现的代码几乎是这样的:

public static class ApiKeyAuthenticationExtension
{
    public static IAppBuilder UseApiKeyAuthentication(this IAppBuilder appBuilder, ApiKeyAuthenticationOptions options = null)
    {
        appBuilder.Use<ApiKeyAuthenticationMiddleware>(options ?? new ApiKeyAuthenticationOptions("ApiKey"));
        appBuilder.UseStageMarker(PipelineStage.Authenticate);

        return appBuilder;
    }
}

public class ApiKeyAuthenticationMiddleware : AuthenticationMiddleware<AuthenticationOptions>
{
    public ApiKeyAuthenticationMiddleware(OwinMiddleware next, AuthenticationOptions options) : base(next, options)
    {
    }

    protected override AuthenticationHandler<AuthenticationOptions> CreateHandler()
    {
        return new ApiKeyAuthenticationHandler();
    }
}

public class ApiKeyAuthenticationHandler : AuthenticationHandler<AuthenticationOptions>
{
    private const string ApiKey = ".....";

    protected override Task<AuthenticationTicket> AuthenticateCoreAsync()
    {
        string apiKey = Context.Request.Headers["ApiKey"];
        if (!string.IsNullOrEmpty(apiKey) && ApiKey.Equals(apiKey))
        {
            var identity = new ClaimsIdentity(Options.AuthenticationType);
            identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "Id", null, Options.AuthenticationType));
            identity.AddClaim(new Claim(ClaimTypes.Name, "Name"));
            identity.AddClaim(new Claim(ClaimTypes.Email, "bla@blu.com"));

            return new Task<AuthenticationTicket>(() => new AuthenticationTicket(identity, new AuthenticationProperties()));
        }

        return Task.FromResult(null as AuthenticationTicket);
    }
}

public class ApiKeyAuthenticationOptions : AuthenticationOptions
{
    public ApiKeyAuthenticationOptions(string authenticationType) : base(authenticationType)
    {
    }
}

我的 Startup.Auth 看起来像这样:

app.UseCookieAuthentication(...
app.UseActiveDirectoryFederationServicesBearerAuthentication(...
app.UseOAuthAuthorizationServer(...
app.UseOAuthBearerAuthentication(...

最后

app.UseApiKeyAuthentication(...

当执行进入 AuthenticateCoreAsync 并且我 return 和身份验证票证时,浏览器只是挂起并且执行似乎无处可去。之后什么也没有发生。

我在这里错过了什么?

我认为您创建的任务从未完成甚至开始。 您可能还想在那里使用 Task.FromResult 或者只是将其更改为异步方法。

    protected override Task<AuthenticationTicket> AuthenticateCoreAsync()
{
    string apiKey = Context.Request.Headers["ApiKey"];
    if (!string.IsNullOrEmpty(apiKey) && ApiKey.Equals(apiKey))
    {
        var identity = new ClaimsIdentity(Options.AuthenticationType);
        identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "Id", null, Options.AuthenticationType));
        identity.AddClaim(new Claim(ClaimTypes.Name, "Name"));
        identity.AddClaim(new Claim(ClaimTypes.Email, "bla@blu.com"));

        return Task.FromResult(new AuthenticationTicket(identity, new AuthenticationProperties()));
    }

    return Task.FromResult(null as AuthenticationTicket);
}