Reputation: 2258
I'm trying to create a new API Key custom authentication provider to plug into my OWIN pipeline. I'm using Cookie, OAuth and ADFS providers as well. The code I've implemented is pretty much this:
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, "[email protected]"));
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)
{
}
}
My Startup.Auth looks like this:
app.UseCookieAuthentication(...
app.UseActiveDirectoryFederationServicesBearerAuthentication(...
app.UseOAuthAuthorizationServer(...
app.UseOAuthBearerAuthentication(...
and at the end
app.UseApiKeyAuthentication(...
When the execution goes into AuthenticateCoreAsync and I return and authentication ticket, the browser just hangs and execution seems to go nowhere. nothing happens after that.
What am I missing here?
Upvotes: 3
Views: 2026
Reputation: 826
I think the task you created is never finishing or even starting. You might want to use Task.FromResult there as well or just change it to an async method.
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, "[email protected]"));
return Task.FromResult(new AuthenticationTicket(identity, new AuthenticationProperties()));
}
return Task.FromResult(null as AuthenticationTicket);
}
Upvotes: 3