Update the RemoteAuthenticationHandler error handling

1. Exeption will be still thrown from CreateTicketAsync to avoid breaking
change.
2. OAuthHandler won't try to capture the exception.
3. OAuthHandler will check if the AuthenticateTicket is null.
4. RemoteAuthenticationHandler's error handling flow is improved to cover
the exception thrown from HandleRemoteAuthenticateAsync. The exeption
thrown from it will go throw the user error handling logic, too.
This commit is contained in:
Troy Dai 2016-07-25 22:02:42 -07:00
parent 988bcc81ee
commit 5de4816f59
5 changed files with 41 additions and 19 deletions

View File

@ -38,8 +38,7 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
var response = await Backchannel.GetAsync(endpoint, Context.RequestAborted); var response = await Backchannel.GetAsync(endpoint, Context.RequestAborted);
if (!response.IsSuccessStatusCode) if (!response.IsSuccessStatusCode)
{ {
var errorMessage = $"Failed to retrived Facebook user information ({response.StatusCode}) Please check if the authentication information is correct and the corresponding Google API is enabled."; throw new HttpRequestException($"Failed to retrived Facebook user information ({response.StatusCode}) Please check if the authentication information is correct and the corresponding Facebook API is enabled.");
throw new InvalidOperationException(errorMessage);
} }
var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); var payload = JObject.Parse(await response.Content.ReadAsStringAsync());

View File

@ -34,8 +34,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
var response = await Backchannel.SendAsync(request, Context.RequestAborted); var response = await Backchannel.SendAsync(request, Context.RequestAborted);
if (!response.IsSuccessStatusCode) if (!response.IsSuccessStatusCode)
{ {
var errorMessage = $"Failed to retrived Google user information ({response.StatusCode}) Please check if the authentication information is correct and the corresponding Google API is enabled."; throw new HttpRequestException($"An error occurred when retrieving user information ({response.StatusCode}). Please check if the authentication information is correct and the corresponding Google API is enabled.");
throw new InvalidOperationException(errorMessage);
} }
var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); var payload = JObject.Parse(await response.Content.ReadAsStringAsync());

View File

@ -28,8 +28,7 @@ namespace Microsoft.AspNetCore.Authentication.MicrosoftAccount
var response = await Backchannel.SendAsync(request, Context.RequestAborted); var response = await Backchannel.SendAsync(request, Context.RequestAborted);
if (!response.IsSuccessStatusCode) if (!response.IsSuccessStatusCode)
{ {
var errorMessage = $"Failed to retrived Microsoft user information ({response.StatusCode}) Please check if the authentication information is correct and the corresponding Google API is enabled."; throw new HttpRequestException($"Failed to retrived Microsoft user information ({response.StatusCode}) Please check if the authentication information is correct and the corresponding Microsoft API is enabled.");
throw new InvalidOperationException(errorMessage);
} }
var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); var payload = JObject.Parse(await response.Content.ReadAsStringAsync());

View File

@ -15,6 +15,7 @@ using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Http.Features.Authentication; using Microsoft.AspNetCore.Http.Features.Authentication;
using Microsoft.Extensions.Primitives; using Microsoft.Extensions.Primitives;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using System.Threading;
namespace Microsoft.AspNetCore.Authentication.OAuth namespace Microsoft.AspNetCore.Authentication.OAuth
{ {
@ -119,14 +120,14 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
properties.StoreTokens(authTokens); properties.StoreTokens(authTokens);
} }
try var ticket = await CreateTicketAsync(identity, properties, tokens);
if (ticket != null)
{ {
var ticket = await CreateTicketAsync(identity, properties, tokens);
return AuthenticateResult.Success(ticket); return AuthenticateResult.Success(ticket);
} }
catch (Exception ex) else
{ {
return AuthenticateResult.Fail(ex); return AuthenticateResult.Fail("Failed to retrieve user information from remote server.");
} }
} }

View File

@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features.Authentication; using Microsoft.AspNetCore.Http.Features.Authentication;
using Microsoft.AspNetCore.Http.Authentication; using Microsoft.AspNetCore.Http.Authentication;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Net.Http;
namespace Microsoft.AspNetCore.Authentication namespace Microsoft.AspNetCore.Authentication
{ {
@ -31,26 +32,49 @@ namespace Microsoft.AspNetCore.Authentication
protected virtual async Task<bool> HandleRemoteCallbackAsync() protected virtual async Task<bool> HandleRemoteCallbackAsync()
{ {
var authResult = await HandleRemoteAuthenticateAsync(); AuthenticateResult authResult = null;
if (authResult != null && authResult.Skipped) Exception exception = null;
try
{ {
return false; authResult = await HandleRemoteAuthenticateAsync();
if (authResult != null && authResult.Skipped == true)
{
return false;
}
else if (authResult == null)
{
exception = new InvalidOperationException("Invalide return state, unable to redirect.");
}
else if (!authResult.Succeeded)
{
exception = authResult?.Failure ??
new InvalidOperationException("Invalide return state, unable to redirect.");
}
} }
if (authResult == null || !authResult.Succeeded) catch (Exception ex)
{ {
var errorContext = new FailureContext(Context, authResult?.Failure ?? new Exception("Invalid return state, unable to redirect.")); exception = ex;
Logger.RemoteAuthenticationError(errorContext.Failure.Message); }
if (exception != null)
{
Logger.RemoteAuthenticationError(exception.Message);
var errorContext = new FailureContext(Context, exception);
await Options.Events.RemoteFailure(errorContext); await Options.Events.RemoteFailure(errorContext);
if (errorContext.HandledResponse) if (errorContext.HandledResponse)
{ {
return true; return true;
} }
if (errorContext.Skipped) else if (errorContext.Skipped)
{ {
return false; return false;
} }
else
throw new AggregateException("Unhandled remote failure.", errorContext.Failure); {
throw new AggregateException("Unhandled remote failure.", exception);
}
} }
// We have a ticket if we get here // We have a ticket if we get here