/// <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);
        }
示例#2
0
        /// <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;
            }
        }
示例#3
0
        /// <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;
            }
        }
示例#4
0
        /// <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);
        }