示例#1
0
 public OpenIdConnectMiddlewareDiagnosticsTests()
 {
     _customEventWasRaised = false;
     _httpContext          = HttpContextUtilities.CreateHttpContext();
     _logger            = Substitute.For <ILogger <OpenIdConnectMiddlewareDiagnostics> >();
     _openIdDiagnostics = new OpenIdConnectMiddlewareDiagnostics(new LoggerMock <OpenIdConnectMiddlewareDiagnostics>(_logger));
     _openIdOptions     = new OpenIdConnectOptions();
     _openIdEvents      = new OpenIdConnectEvents();
     _authProperties    = new AuthenticationProperties();
     _authScheme        = new AuthenticationScheme(OpenIdConnectDefaults.AuthenticationScheme, OpenIdConnectDefaults.AuthenticationScheme, typeof(OpenIdConnectHandler));
     _eventHandler      = (context) => {
         _customEventWasRaised = true;
         return(Task.CompletedTask);
     };
 }
示例#2
0
        /// <summary>
        /// Add authentication with Microsoft identity platform.
        /// This method expects the configuration file will have a section named "AzureAd" with the necessary settings to initialize authentication options.
        /// </summary>
        /// <param name="services">Service collection to which to add this authentication scheme</param>
        /// <param name="configuration">The Configuration object</param>
        /// <param name="subscribeToOpenIdConnectMiddlewareDiagnosticsEvents">
        /// Set to true if you want to debug, or just understand the OpenIdConnect events.
        /// </param>
        /// <returns></returns>
        public static IServiceCollection AddMicrosoftIdentityPlatformAuthentication(
            this IServiceCollection services,
            IConfiguration configuration,
            string configSectionName = "AzureAd",
            bool subscribeToOpenIdConnectMiddlewareDiagnosticsEvents = false)
        {
            services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
            .AddAzureAD(options => configuration.Bind(configSectionName, options));
            services.Configure <AzureADOptions>(options => configuration.Bind(configSectionName, options));

            services.Configure <OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
            {
                // Per the code below, this application signs in users in any Work and School
                // accounts and any Microsoft Personal Accounts.
                // If you want to direct Azure AD to restrict the users that can sign-in, change
                // the tenant value of the appsettings.json file in the following way:
                // - only Work and School accounts => 'organizations'
                // - only Microsoft Personal accounts => 'consumers'
                // - Work and School and Personal accounts => 'common'
                // If you want to restrict the users that can sign-in to only one tenant
                // set the tenant value in the appsettings.json file to the tenant ID
                // or domain of this organization
                options.Authority = options.Authority + "/v2.0/";

                // If you want to restrict the users that can sign-in to several organizations
                // Set the tenant value in the appsettings.json file to 'organizations', and add the
                // issuers you want to accept to options.TokenValidationParameters.ValidIssuers collection
                options.TokenValidationParameters.IssuerValidator = AadIssuerValidator.GetIssuerValidator(options.Authority).Validate;

                // Set the nameClaimType to be preferred_username.
                // This change is needed because certain token claims from Azure AD V1 endpoint
                // (on which the original .NET core template is based) are different than Microsoft identity platform endpoint.
                // For more details see [ID Tokens](https://docs.microsoft.com/azure/active-directory/develop/id-tokens)
                // and [Access Tokens](https://docs.microsoft.com/azure/active-directory/develop/access-tokens)
                options.TokenValidationParameters.NameClaimType = "preferred_username";

                // Avoids having users being presented the select account dialog when they are already signed-in
                // for instance when going through incremental consent
                options.Events.OnRedirectToIdentityProvider = context =>
                {
                    var login = context.Properties.GetParameter <string>(OpenIdConnectParameterNames.LoginHint);
                    if (!string.IsNullOrWhiteSpace(login))
                    {
                        context.ProtocolMessage.LoginHint  = login;
                        context.ProtocolMessage.DomainHint = context.Properties.GetParameter <string>(
                            OpenIdConnectParameterNames.DomainHint);

                        // delete the login_hint and domainHint from the Properties when we are done otherwise
                        // it will take up extra space in the cookie.
                        context.Properties.Parameters.Remove(OpenIdConnectParameterNames.LoginHint);
                        context.Properties.Parameters.Remove(OpenIdConnectParameterNames.DomainHint);
                    }

                    // Additional claims
                    if (context.Properties.Items.ContainsKey(OidcConstants.AdditionalClaims))
                    {
                        context.ProtocolMessage.SetParameter(
                            OidcConstants.AdditionalClaims,
                            context.Properties.Items[OidcConstants.AdditionalClaims]);
                    }

                    return(Task.FromResult(0));
                };

                if (subscribeToOpenIdConnectMiddlewareDiagnosticsEvents)
                {
                    OpenIdConnectMiddlewareDiagnostics.Subscribe(options.Events);
                }
            });
            return(services);
        }
        /// <summary>
        /// Add authentication with Microsoft identity platform.
        /// This method expects the configuration file will have a section, named "AzureAd" as default, with the necessary settings to initialize authentication options.
        /// </summary>
        /// <param name="builder">AuthenticationBuilder to which to add this configuration</param>
        /// <param name="configSectionName">The configuration section with the necessary settings to initialize authentication options</param>
        /// <param name="configuration">The IConfiguration object</param>
        /// <param name="configureOptions">An action to configure OpenIdConnectOptions</param>
        /// <param name="openIdConnectScheme">The OpenIdConnect scheme name to be used. By default it uses "OpenIdConnect"</param>
        /// <param name="cookieScheme">The Cookies scheme name to be used. By default it uses "Cookies"</param>
        /// <param name="subscribeToOpenIdConnectMiddlewareDiagnosticsEvents">
        /// Set to true if you want to debug, or just understand the OpenIdConnect events.
        /// </param>
        /// <returns></returns>
        public static AuthenticationBuilder AddSignIn(
            this AuthenticationBuilder builder,
            string configSectionName,
            IConfiguration configuration,
            string openIdConnectScheme,
            string cookieScheme,
            Action <OpenIdConnectOptions> configureOptions,
            bool subscribeToOpenIdConnectMiddlewareDiagnosticsEvents = false)
        {
            builder.Services.Configure(openIdConnectScheme, configureOptions);
            builder.Services.Configure <MicrosoftIdentityOptions>(options => configuration.Bind(configSectionName, options));

            var microsoftIdentityOptions = configuration.GetSection(configSectionName).Get <MicrosoftIdentityOptions>();
            var b2COidcHandlers          = new AzureADB2COpenIDConnectEventHandlers(openIdConnectScheme, microsoftIdentityOptions);

            builder.AddCookie(cookieScheme);
            builder.AddOpenIdConnect(openIdConnectScheme, options =>
            {
                options.SignInScheme = cookieScheme;

                if (string.IsNullOrWhiteSpace(options.Authority))
                {
                    options.Authority = AuthorityHelpers.BuildAuthority(microsoftIdentityOptions);
                }

                if (!AuthorityHelpers.IsV2Authority(options.Authority))
                {
                    options.Authority += "/v2.0";
                }

                // B2C doesn't have preferred_username claims
                if (microsoftIdentityOptions.IsB2C)
                {
                    options.TokenValidationParameters.NameClaimType = "name";
                }
                else
                {
                    options.TokenValidationParameters.NameClaimType = "preferred_username";
                }

                // If the developer registered an IssuerValidator, do not overwrite it
                if (options.TokenValidationParameters.IssuerValidator == null)
                {
                    // If you want to restrict the users that can sign-in to several organizations
                    // Set the tenant value in the appsettings.json file to 'organizations', and add the
                    // issuers you want to accept to options.TokenValidationParameters.ValidIssuers collection
                    options.TokenValidationParameters.IssuerValidator = AadIssuerValidator.GetIssuerValidator(options.Authority).Validate;
                }

                // Avoids having users being presented the select account dialog when they are already signed-in
                // for instance when going through incremental consent
                var redirectToIdpHandler = options.Events.OnRedirectToIdentityProvider;
                options.Events.OnRedirectToIdentityProvider = async context =>
                {
                    var login = context.Properties.GetParameter <string>(OpenIdConnectParameterNames.LoginHint);
                    if (!string.IsNullOrWhiteSpace(login))
                    {
                        context.ProtocolMessage.LoginHint  = login;
                        context.ProtocolMessage.DomainHint = context.Properties.GetParameter <string>(
                            OpenIdConnectParameterNames.DomainHint);

                        // delete the login_hint and domainHint from the Properties when we are done otherwise
                        // it will take up extra space in the cookie.
                        context.Properties.Parameters.Remove(OpenIdConnectParameterNames.LoginHint);
                        context.Properties.Parameters.Remove(OpenIdConnectParameterNames.DomainHint);
                    }

                    // Additional claims
                    if (context.Properties.Items.ContainsKey(OidcConstants.AdditionalClaims))
                    {
                        context.ProtocolMessage.SetParameter(
                            OidcConstants.AdditionalClaims,
                            context.Properties.Items[OidcConstants.AdditionalClaims]);
                    }

                    if (microsoftIdentityOptions.IsB2C)
                    {
                        context.ProtocolMessage.SetParameter("client_info", "1");
                        // When a new Challenge is returned using any B2C user flow different than susi, we must change
                        // the ProtocolMessage.IssuerAddress to the desired user flow otherwise the redirect would use the susi user flow
                        await b2COidcHandlers.OnRedirectToIdentityProvider(context);
                    }

                    await redirectToIdpHandler(context).ConfigureAwait(false);
                };

                if (microsoftIdentityOptions.IsB2C)
                {
                    var remoteFailureHandler       = options.Events.OnRemoteFailure;
                    options.Events.OnRemoteFailure = async context =>
                    {
                        // Handles the error when a user cancels an action on the Azure Active Directory B2C UI.
                        // Handle the error code that Azure Active Directory B2C throws when trying to reset a password from the login page
                        // because password reset is not supported by a "sign-up or sign-in user flow".
                        await b2COidcHandlers.OnRemoteFailure(context);

                        await remoteFailureHandler(context).ConfigureAwait(false);
                    };
                }

                if (subscribeToOpenIdConnectMiddlewareDiagnosticsEvents)
                {
                    OpenIdConnectMiddlewareDiagnostics.Subscribe(options.Events);
                }
            });

            return(builder);
        }