Reputation: 1050
I want to cause oAuth to fail during the OnCreatingTicket event. I can call .Fail but it doesn't seem to do anything. Is it too late in the workflow? Am I missing some additional code to actually process the failure?
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie().AddOAuth("schemename", SetOAuthOptions);
private void SetOAuthOptions(OAuthOptions options)
{
options.ClientId = ...;
options.ClientSecret = ...;
options.CallbackPath = ...;
options.AuthorizationEndpoint = ...;
options.TokenEndpoint = ...;
options.Events = new OAuthEvents
{
OnCreatingTicket = async context => await AddIdentityClaimsAsync(context),
OnTicketReceived = ...
};
}
private async Task AddIdentityClaimsAsync(OAuthCreatingTicketContext context)
{
...
if(noAccess)
context.Fail("Sorry, you don't have access to the product.");
}
Upvotes: 4
Views: 1491
Reputation: 386
It seems that the OAuthCreatingTicketContext.Fail doesn't end up affecting the HandleRequestResult that is ultimately returned by the authentication call. What I ended up having to do was to throw a known exception from the OnCreatingTicket handler, override OAuthHandler.HandleRemoteAuthenticateAsync to catch it and from there call HandleRequestResult.Fail with the exception.
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie().AddOAuth("schemename", SetOAuthOptions);
private void SetOAuthOptions(OAuthOptions options)
{
options.ClientId = ...;
options.ClientSecret = ...;
options.CallbackPath = ...;
options.AuthorizationEndpoint = ...;
options.TokenEndpoint = ...;
options.Events = new OAuthEvents
{
OnCreatingTicket = async context => await AddIdentityClaimsAsync(context),
OnTicketReceived = ...
};
}
private async Task AddIdentityClaimsAsync(OAuthCreatingTicketContext context)
{
...
if(noAccess)
throw new MyCustomException("Sorry, you don't have access to the product.");
}
// In OAuthHandler<T>
protected override async Task<HandleRequestResult> HandleRemoteAuthenticateAsync()
{
try
{
return await base.HandleRemoteAuthenticateAsync();
}
catch (MyCustomException e)
{
return HandleRequestResult.Fail(e);
}
}
Hope this helps someone.
Upvotes: 4
Reputation: 1050
This is what I ended up with:
In startup, after AddOAuth:
.AddScheme<OAuthOptions, BearerAuthHandler>(BearerAuthHandler.DefaultSchemeName, ...);
This goes in your controller:
[Authorize(AuthenticationSchemes = BearerAuthHandler.DefaultSchemeName)]
This is the scheme class: https://dotnetfiddle.net/hujDtz
Upvotes: 0