public static AuthenticationBuilder AddAzureAd(this AuthenticationBuilder builder, Action <AzureAdOptions> configureOptions)
 {
     builder.Services.Configure(configureOptions);
     builder.Services.AddSingleton <IConfigureOptions <OpenIdConnectOptions>, ConfigureAzureOptions>();
     builder.AddOpenIdConnect(options =>
     {
         options.Events = new OpenIdConnectEvents
         {
             OnTokenValidated = async context =>
             {
                 await Task.Run(() =>
                 {
                     var claimStore = new ClaimStore();
                     var claims     = claimStore.GetClaimsForUser(context.Principal?.FindFirstValue("name"));
                     var identity   = new ClaimsIdentity(claims);
                     context.Principal.AddIdentity(identity);
                 });
             }
         };
     });
     return(builder);
 }
        /// <summary>
        /// Authentication extension to register an Azure AD
        /// external provider.
        /// </summary>
        /// <param name="authenticationBuilder"></param>
        /// <param name="azureADOptions"></param>
        /// <returns></returns>
        public static AuthenticationBuilder AddAADProvider(this AuthenticationBuilder authenticationBuilder, Action <AzureADOptions> azureADOptions)
        {
            var provider = new AzureADOptions();

            azureADOptions(provider);

            authenticationBuilder
            .AddOpenIdConnect(provider.ProviderName, provider.ProviderName, options =>
            {
                options.SignInScheme                  = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                options.SignOutScheme                 = IdentityServerConstants.SignoutScheme;
                options.Authority                     = provider.Authority;
                options.ClientId                      = provider.ClientId;
                options.ResponseType                  = provider.ResponseType;
                options.CallbackPath                  = provider.CallbackPath;
                options.SignedOutCallbackPath         = provider.SignedOutCallbackPath;
                options.RemoteSignOutPath             = provider.RemoteSignOutPath;
                options.RequireHttpsMetadata          = provider.RequireHttpsMetadata;
                options.GetClaimsFromUserInfoEndpoint = provider.GetClaimsFromUserInfoEndpoint;
            });

            return(authenticationBuilder);
        }
        /// <summary>
        /// Authentication extension to register multiple Azure AD
        /// external providers from configuration.
        /// </summary>
        /// <param name="authenticationBuilder"></param>
        /// <param name="configuration"></param>
        /// <returns></returns>
        public static AuthenticationBuilder AddAADProvidersFromConfig(this AuthenticationBuilder authenticationBuilder, IConfiguration configuration)
        {
            var azureADProviders = configuration.GetSection("AAD").Get <List <AzureADOptions> >();

            azureADProviders?.ForEach(provider =>
            {
                authenticationBuilder
                .AddOpenIdConnect(provider.ProviderName, provider.ProviderName, options =>
                {
                    options.SignInScheme                  = IdentityServerConstants.ExternalCookieAuthenticationScheme;
                    options.SignOutScheme                 = IdentityServerConstants.SignoutScheme;
                    options.Authority                     = provider.Authority;
                    options.ClientId                      = provider.ClientId;
                    options.ResponseType                  = provider.ResponseType;
                    options.CallbackPath                  = provider.CallbackPath;
                    options.SignedOutCallbackPath         = provider.SignedOutCallbackPath;
                    options.RemoteSignOutPath             = provider.RemoteSignOutPath;
                    options.RequireHttpsMetadata          = provider.RequireHttpsMetadata;
                    options.GetClaimsFromUserInfoEndpoint = provider.GetClaimsFromUserInfoEndpoint;
                });
            });

            return(authenticationBuilder);
        }
Beispiel #4
0
        public static AuthenticationBuilder AddAzureAd(this AuthenticationBuilder builder, Action <AzureAdOptions> configureOptions)
        {
            builder.Services.Configure(configureOptions);
            builder.Services.AddSingleton <IConfigureOptions <OpenIdConnectOptions>, ConfigureAzureOptions>();
            builder.AddOpenIdConnect(options =>
            {
                options.Events = new OpenIdConnectEvents
                {
                    OnRemoteFailure = async context =>
                    {
                        // If any of the auth handshaking causes an error/exception, the methods below will log the exception.
                        // here, we still catch the failure Event, log and gracefully handle
                        if (context != null && context.Failure != null)
                        {
                            var telemetryService = context.HttpContext.RequestServices.GetService <ITelemetryService>();
                            telemetryService.TrackException(context.Failure);
                        }
                    },
                    OnTokenValidated = async context =>
                    {
                        var claimIdentity   = (ClaimsIdentity)context.Principal.Identity;
                        var claimsPrincipal = context.Principal.Identity;

                        // Store login event
                        var eventService = context?.HttpContext?.RequestServices?.GetService <IEventService>();

                        if (eventService == null)
                        {
                            throw new Exception("EventService not found. Terminating.");
                        }

                        string accessIpAddress = string.Empty;
                        if (context.HttpContext != null)
                        {
                            accessIpAddress = context?.HttpContext?.Connection?.RemoteIpAddress?.ToString();
                        }

                        var telemetryService = context?.HttpContext?.RequestServices?.GetService <ITelemetryService>();
                        telemetryService.TraceEvent("Login success", "login", claimsPrincipal.Name);

                        await eventService.LogLoginEventAsync(claimIdentity, accessIpAddress);
                    }
                    ,
                    OnAuthorizationCodeReceived = async context =>
                    {
                        var claimIdentity = context.Principal.Claims;
                        var graphService  = context.HttpContext.RequestServices.GetService <IGraphService>();

                        var code = context.ProtocolMessage.Code; // null check
                        // Can't find the object identifier enum, using string
                        // TODO null check here! -> extract to helper?
                        var identifier = context.Principal.Claims.First(item => item.Type == "http://schemas.microsoft.com/identity/claims/objectidentifier").Value;

                        var redirectHost = context.Request.Scheme + "://" + context.Request.Host.Value;

                        var result = await graphService.GetTokenByAuthorizationCodeAsync(identifier, code, redirectHost);

                        if (result != null)
                        {
                            context.HandleCodeRedemption(result.AccessToken, result.IdToken);
                        }
                        else
                        {
                            var telemetryService = context.HttpContext.RequestServices.GetService <ITelemetryService>();
                            telemetryService.TraceEvent(
                                "Client Secret Error",
                                "GraphServiceError",
                                "Token was not received from the Graph Service. Check App Insights exceptions, or the directory configuration in appsettings.json.");
                        }
                    }
                };

                options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
            });
            return(builder);
        }