/// <summary> /// Handles the <see cref="MsalUiRequiredException"/>. /// </summary> /// <param name="context">Context provided by ASP.NET Core.</param> public override void OnException(ExceptionContext context) { if (context != null) { MsalUiRequiredException?msalUiRequiredException = FindMsalUiRequiredExceptionIfAny(context.Exception); if (msalUiRequiredException != null && IncrementalConsentAndConditionalAccessHelper.CanBeSolvedByReSignInOfUser(msalUiRequiredException)) { // the users cannot provide both scopes and ScopeKeySection at the same time if (!string.IsNullOrWhiteSpace(ScopeKeySection) && Scopes != null && Scopes.Length > 0) { throw new InvalidOperationException( string.Format( CultureInfo.InvariantCulture, IDWebErrorMessage.ProvideEitherScopeKeySectionOrScopes, nameof(ScopeKeySection), nameof(Scopes))); } // Do not re-use the property Scopes. For more info: https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/issues/273 string[]? incrementalConsentScopes; // If the user wishes us to pick the Scopes from a particular config setting. if (!string.IsNullOrWhiteSpace(ScopeKeySection)) { // Load the injected IConfiguration IConfiguration configuration = context.HttpContext.RequestServices.GetRequiredService <IConfiguration>(); if (configuration == null) { throw new InvalidOperationException( string.Format( CultureInfo.InvariantCulture, IDWebErrorMessage.ScopeKeySectionIsProvidedButNotPresentInTheServicesCollection, nameof(ScopeKeySection))); } incrementalConsentScopes = new string[] { configuration.GetValue <string>(ScopeKeySection) }; if (Scopes != null && Scopes.Length > 0 && incrementalConsentScopes.Length > 0) { throw new InvalidOperationException(IDWebErrorMessage.NoScopesProvided); } } else { incrementalConsentScopes = Scopes; } AuthenticationProperties properties = IncrementalConsentAndConditionalAccessHelper.BuildAuthenticationProperties( incrementalConsentScopes, msalUiRequiredException, context.HttpContext.User, UserFlow); context.Result = new ChallengeResult(properties); } } base.OnException(context); }
/// <summary> /// For Blazor/Razor pages to process the exception from /// a user challenge. /// </summary> /// <param name="exception">Exception.</param> public void HandleException(Exception exception) { MicrosoftIdentityWebChallengeUserException?microsoftIdentityWebChallengeUserException = exception as MicrosoftIdentityWebChallengeUserException; if (microsoftIdentityWebChallengeUserException == null) { #pragma warning disable CA1062 // Validate arguments of public methods microsoftIdentityWebChallengeUserException = exception.InnerException as MicrosoftIdentityWebChallengeUserException; #pragma warning restore CA1062 // Validate arguments of public methods } if (microsoftIdentityWebChallengeUserException != null && IncrementalConsentAndConditionalAccessHelper.CanBeSolvedByReSignInOfUser(microsoftIdentityWebChallengeUserException.MsalUiRequiredException)) { var properties = IncrementalConsentAndConditionalAccessHelper.BuildAuthenticationProperties( microsoftIdentityWebChallengeUserException.Scopes, microsoftIdentityWebChallengeUserException.MsalUiRequiredException, User, microsoftIdentityWebChallengeUserException.Userflow); List <string> scopes = properties.Parameters.ContainsKey(Constants.Scope) ? (List <string>)properties.Parameters[Constants.Scope] ! : new List <string>(); string claims = properties.Parameters.ContainsKey(Constants.Claims) ? (string)properties.Parameters[Constants.Claims] ! : string.Empty; string userflow = properties.Items.ContainsKey(OidcConstants.PolicyKey) ? properties.Items[OidcConstants.PolicyKey] ! : string.Empty; ChallengeUser( scopes.ToArray(), claims, userflow); } else { throw exception; } }
/// <summary> /// For Blazor/Razor pages to process the exception from /// a user challenge. /// </summary> /// <param name="exception">Exception.</param> public void HandleException(Exception exception) { MicrosoftIdentityWebChallengeUserException?microsoftIdentityWebChallengeUserException = exception as MicrosoftIdentityWebChallengeUserException; if (microsoftIdentityWebChallengeUserException == null) { #pragma warning disable CA1062 // Validate arguments of public methods microsoftIdentityWebChallengeUserException = exception.InnerException as MicrosoftIdentityWebChallengeUserException; #pragma warning restore CA1062 // Validate arguments of public methods } if (microsoftIdentityWebChallengeUserException != null && IncrementalConsentAndConditionalAccessHelper.CanBeSolvedByReSignInOfUser(microsoftIdentityWebChallengeUserException.MsalUiRequiredException)) { var properties = IncrementalConsentAndConditionalAccessHelper.BuildAuthenticationProperties( microsoftIdentityWebChallengeUserException.Scopes, microsoftIdentityWebChallengeUserException.MsalUiRequiredException, User); string redirectUri; if (IsBlazorServer) { redirectUri = NavigationManager.Uri; } else { var request = _httpContextAccessor.HttpContext.Request; redirectUri = string.Format( CultureInfo.InvariantCulture, "{0}{1}", CreateBaseUri(request), request.Path.ToString()); } List <string> scope = properties.Parameters.ContainsKey(Constants.Scope) ? (List <string>)properties.Parameters[Constants.Scope] ! : new List <string>(); string loginHint = properties.Parameters.ContainsKey(Constants.LoginHint) ? (string)properties.Parameters[Constants.LoginHint] ! : string.Empty; string domainHint = properties.Parameters.ContainsKey(Constants.DomainHint) ? (string)properties.Parameters[Constants.DomainHint] ! : string.Empty; string claims = properties.Parameters.ContainsKey(Constants.Claims) ? (string)properties.Parameters[Constants.Claims] ! : string.Empty; string url = $"{BaseUri}{Constants.BlazorChallengeUri}{redirectUri}" + $"&{Constants.Scope}={string.Join(" ", scope!)}&{Constants.LoginHint}={loginHint}" + $"&{Constants.DomainHint}={domainHint}&{Constants.Claims}={claims}"; if (IsBlazorServer) { NavigationManager.NavigateTo(url, true); } else { _httpContextAccessor.HttpContext.Response.Redirect(url); } } else { throw exception; } }
/// <summary> /// For Blazor/Razor pages to process the exception from /// a user challenge. /// </summary> /// <param name="exception">Exception.</param> public void HandleException(Exception exception) { MicrosoftIdentityWebChallengeUserException?microsoftIdentityWebChallengeUserException = exception as MicrosoftIdentityWebChallengeUserException; if (microsoftIdentityWebChallengeUserException == null) { #pragma warning disable CA1062 // Validate arguments of public methods microsoftIdentityWebChallengeUserException = exception.InnerException as MicrosoftIdentityWebChallengeUserException; #pragma warning restore CA1062 // Validate arguments of public methods } if (microsoftIdentityWebChallengeUserException != null && IncrementalConsentAndConditionalAccessHelper.CanBeSolvedByReSignInOfUser(microsoftIdentityWebChallengeUserException.MsalUiRequiredException)) { var properties = IncrementalConsentAndConditionalAccessHelper.BuildAuthenticationProperties( microsoftIdentityWebChallengeUserException.Scopes, microsoftIdentityWebChallengeUserException.MsalUiRequiredException, User); string redirectUri = NavigationManager.Uri; List <string> scope = properties.Parameters.ContainsKey(Constants.Scope) ? (List <string>)properties.Parameters[Constants.Scope] : new List <string>(); string loginHint = properties.Parameters.ContainsKey(Constants.LoginHint) ? (string)properties.Parameters[Constants.LoginHint] : string.Empty; string domainHint = properties.Parameters.ContainsKey(Constants.DomainHint) ? (string)properties.Parameters[Constants.DomainHint] : string.Empty; string claims = properties.Parameters.ContainsKey(Constants.Claims) ? (string)properties.Parameters[Constants.Claims] : string.Empty; string url = $"{NavigationManager.BaseUri}{Constants.BlazorChallengeUri}{redirectUri}" + $"&{Constants.Scope}={string.Join(" ", scope)}&{Constants.LoginHint}={loginHint}" + $"&{Constants.DomainHint}={domainHint}&{Constants.Claims}={claims}"; NavigationManager.NavigateTo(url, true); } else { throw exception; } }
/// <summary> /// Handles the <see cref="MsalUiRequiredException"/>. /// </summary> /// <param name="context">Context provided by ASP.NET Core.</param> public override void OnException(ExceptionContext context) { if (context != null) { MsalUiRequiredException?msalUiRequiredException = FindMsalUiRequiredExceptionIfAny(context.Exception); if (msalUiRequiredException != null && IncrementalConsentAndConditionalAccessHelper.CanBeSolvedByReSignInOfUser(msalUiRequiredException)) { // the users cannot provide both scopes and ScopeKeySection at the same time if (!string.IsNullOrWhiteSpace(ScopeKeySection) && Scopes != null && Scopes.Length > 0) { throw new InvalidOperationException( string.Format( CultureInfo.InvariantCulture, IDWebErrorMessage.ProvideEitherScopeKeySectionOrScopes, nameof(ScopeKeySection), nameof(Scopes))); } // Do not re-use the property Scopes. For more info: https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/issues/273 string[]? incrementalConsentScopes; // If the user wishes us to pick the Scopes from a particular config setting. if (!string.IsNullOrWhiteSpace(ScopeKeySection)) { // Load the injected IConfiguration IConfiguration?configuration = context.HttpContext.RequestServices.GetService <IConfiguration>(); if (configuration == null) { throw new InvalidOperationException( string.Format( CultureInfo.InvariantCulture, IDWebErrorMessage.ScopeKeySectionIsProvidedButNotPresentInTheServicesCollection, nameof(ScopeKeySection))); } incrementalConsentScopes = new string[] { configuration.GetValue <string>(ScopeKeySection) }; if (Scopes != null && Scopes.Length > 0 && incrementalConsentScopes.Length > 0) { throw new InvalidOperationException(IDWebErrorMessage.NoScopesProvided); } } else { incrementalConsentScopes = Scopes; } HttpRequest httpRequest; ClaimsPrincipal user; HttpContext httpContext = context.HttpContext; lock (httpContext) { httpRequest = httpContext.Request; user = httpContext.User; } AuthenticationProperties properties = IncrementalConsentAndConditionalAccessHelper.BuildAuthenticationProperties( incrementalConsentScopes, msalUiRequiredException, user, UserFlow); if (IsAjaxRequest(httpRequest) && (!string.IsNullOrEmpty(httpRequest.Headers[Constants.XReturnUrl]) || !string.IsNullOrEmpty(httpRequest.Query[Constants.XReturnUrl]))) { string redirectUri = !string.IsNullOrEmpty(httpRequest.Headers[Constants.XReturnUrl]) ? httpRequest.Headers[Constants.XReturnUrl] : httpRequest.Query[Constants.XReturnUrl]; UrlHelper urlHelper = new UrlHelper(context); if (urlHelper.IsLocalUrl(redirectUri)) { properties.RedirectUri = redirectUri; } } if (AuthenticationScheme != null) { context.Result = new ChallengeResult(AuthenticationScheme, properties); } else { context.Result = new ChallengeResult(properties); } } } base.OnException(context); }