Exemple #1
0
        // Creates FloatAd instance.
        public FloatAd(string adAppId, string adUnitId, GameObject gameObject, AdOptions adOptions)
        {
            client = AtmosplayAdsClientFactory.BuildFloatAdClient(adAppId, adUnitId, gameObject);

            if (adOptions == null)
            {
                adOptions = new AdOptionsBuilder().build();
            }
            client.SetChannelId(adOptions.mChannelId);
            client.SetAutoloadNext(adOptions.isAutoLoad);
            client.LoadAd(adUnitId);

            client.OnAdLoaded += (sender, args) =>
            {
                if (OnAdLoaded != null)
                {
                    OnAdLoaded(this, args);
                }
            };

            client.OnAdFailedToLoad += (sender, args) =>
            {
                if (OnAdFailedToLoad != null)
                {
                    OnAdFailedToLoad(this, args);
                }
            };

            client.OnAdStarted += (sender, args) =>
            {
                if (OnAdStarted != null)
                {
                    OnAdStarted(this, args);
                }
            };

            client.OnAdClicked += (sender, args) =>
            {
                if (OnAdClicked != null)
                {
                    OnAdClicked(this, args);
                }
            };

            client.OnAdRewarded += (sender, args) =>
            {
                if (OnAdRewarded != null)
                {
                    OnAdRewarded(this, args);
                }
            };

            client.OnAdClosed += (sender, args) =>
            {
                if (OnAdClosed != null)
                {
                    OnAdClosed(this, args);
                }
            };
        }
 public AzureAdDirectoryServiceFactory(
     IOptions <AdOptions> AdSettings,
     IOptions <AzureAdOptions> AzureAdSettings)
 {
     _azureAdSettings = AzureAdSettings.Value;
     _adSettings      = AdSettings.Value;
 }
Exemple #3
0
        public AdDirectoryService(LdapSettings settings, AdOptions adOptions)
        {
            // TODO NTBS-1672 run a DNS query that does the foollwing:
            // dig +short -t srv _ldap._tcp.SP4-0JG._sites.dc._msdcs.phe.gov.uk
            // dig +short -t srv _ldap._tcp.dc._msdcs.caduceus.local
            // and pick a dc to request
            _settings   = settings;
            _adOptions  = adOptions;
            _connection = new LdapConnection();
            Log.Information($"Connecting to AD: {settings.AdAddressName}:{settings.Port}");
            _connection.Connect(settings.AdAddressName, settings.Port);
            var withOrWithout = string.IsNullOrEmpty(settings.Password) ? "without" : "with";

            Log.Information($"Binding: {settings.UserIdentifier} {withOrWithout} a password");
            _connection.Bind(GetDistinguishedName(settings.UserIdentifier), settings.Password);
            if (_connection.Bound)
            {
                Log.Information("Bind completed");
            }
            else
            {
                var bindingException = new ApplicationException("Binding to LDAP failed");
                Log.Error(bindingException, "Aborting LDAP connection");
                throw bindingException;
            }
        }
        /// <summary>
        /// Request a banner
        /// </summary>
        private void RequestBanner(BannerPosition position)
        {
            bannerUsed = true;
            if (string.IsNullOrEmpty(bannerZoneId))
            {
                return;
            }
            if (debug)
            {
                Debug.Log(this + " Request Banner");
                ScreenWriter.Write(this + " Request banner");
            }
            AdOptions adOptions = new AdOptions();

            adOptions.ShowPrePopup  = false;
            adOptions.ShowPostPopup = false;
            if (position == BannerPosition.BOTTOM)
            {
                Ads.RequestAdView(bannerZoneId, AdSize.Banner, AdPosition.Bottom, null);
            }
            else
            {
                Ads.RequestAdView(bannerZoneId, AdSize.Banner, AdPosition.Top, null);
            }
        }
 public AdDirectoryServiceFactory(
     IOptions <LdapSettings> LdapSettings,
     IOptions <AdOptions> adfsOptions)
 {
     _ldapSettings = LdapSettings.Value;
     _adOptions    = adfsOptions.Value;
 }
        // Creates RewardVideoAd instance.
        public RewardVideoAd(string adAppId, string adUnitId, AdOptions adOptions)
        {
            client = ZPLAYAdsClientFactory.BuildRewardVideoClient(adAppId, adUnitId);

            if (adOptions == null)
            {
                adOptions = new AdOptionsBuilder().build();
            }
            client.SetChannelId(adOptions.mChannelId);
            client.SetAutoloadNext(adOptions.isAutoLoad);

            client.OnAdLoaded += (sender, args) =>
            {
                if (OnAdLoaded != null)
                {
                    OnAdLoaded(this, args);
                }
            };

            client.OnAdFailedToLoad += (sender, args) =>
            {
                if (OnAdFailedToLoad != null)
                {
                    OnAdFailedToLoad(this, args);
                }
            };

            client.OnAdStarted += (sender, args) =>
            {
                if (OnAdStarted != null)
                {
                    OnAdStarted(this, args);
                }
            };

            client.OnAdClicked += (sender, args) =>
            {
                if (OnAdClicked != null)
                {
                    OnAdClicked(this, args);
                }
            };

            client.OnAdRewarded += (sender, args) =>
            {
                if (OnAdRewarded != null)
                {
                    OnAdRewarded(this, args);
                }
            };

            client.OnAdClosed += (sender, args) =>
            {
                if (OnAdClosed != null)
                {
                    OnAdClosed(this, args);
                }
            };
        }
Exemple #7
0
 public UserService(
     IReferenceDataRepository referenceDataRepository,
     IUserRepository userRepository,
     IOptionsMonitor <AdOptions> options)
 {
     _referenceDataRepository = referenceDataRepository;
     _userRepository          = userRepository;
     _config = options.CurrentValue;
 }
 public UserAuthentication(
     ITestUser user,
     IOptionsMonitor <AdOptions> adOptions,
     IOptionsMonitor <AuthenticationSchemeOptions> options,
     ILoggerFactory logger,
     UrlEncoder encoder,
     ISystemClock clock)
     : base(options, logger, encoder, clock)
 {
     this.user      = user;
     this.adOptions = adOptions.CurrentValue;
 }
Exemple #9
0
        private void LoadBannerAd(AdPlacement placement, BannerAdPosition position, BannerAdSize size)
        {
            #if EM_ADCOLONY
            string id = placement == AdPlacement.Default ?
                        mAdSettings.DefaultBannerAdId.Id : FindIdForPlacement(mAdSettings.CustomBannerAdIds, placement);

            AdColony.AdPosition bannerPosition = AdPosition.Bottom;
            switch (position)
            {
            case BannerAdPosition.Top:
                bannerPosition = AdPosition.Top;
                break;

            case BannerAdPosition.Bottom:
                bannerPosition = AdPosition.Bottom;
                break;

            case BannerAdPosition.TopLeft:
                bannerPosition = AdPosition.TopLeft;
                break;

            case BannerAdPosition.TopRight:
                bannerPosition = AdPosition.TopRight;
                break;

            case BannerAdPosition.BottomLeft:
                bannerPosition = AdPosition.BottomLeft;
                break;

            case BannerAdPosition.BottomRight:
                bannerPosition = AdPosition.BottomRight;
                break;

            default:
                break;
            }
            var adOptions = new AdOptions()
            {
                ShowPrePopup  = mAdSettings.EnableRewardedAdPrePopup,
                ShowPostPopup = mAdSettings.EnableRewardedAdPostPopup
            };

            if (!string.IsNullOrEmpty(id))
            {
                AdColony.Ads.RequestAdView(id, AdColony.AdSize.Banner, bannerPosition, adOptions);
            }
            else
            {
                Debug.Log("Attempting to load AdColony banner ad with an undefined ID at placement " + AdPlacement.GetPrintableName(placement));
            }
            #endif
        }
    private static void UseAdfsAuthentication(IServiceCollection services, AdOptions adOptions, AdfsOptions adfsOptions)
    {
        var authSetup = services
                        .AddAuthentication(sharedOptions =>
        {
            sharedOptions.DefaultScheme          = CookieAuthenticationDefaults.AuthenticationScheme;
            sharedOptions.DefaultSignInScheme    = CookieAuthenticationDefaults.AuthenticationScheme;
            sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
        })
                        .AddWsFederation(options =>
        {
            options.CallbackPath             = "/Index";
            options.SkipUnrecognizedRequests = true;
            options.MetadataAddress          = adfsOptions.AdfsUrl + "/FederationMetadata/2007-06/FederationMetadata.xml";
            options.Wtrealm = adfsOptions.Wtrealm;
            options.CorrelationCookie.SameSite     = SameSiteMode.None;
            options.CorrelationCookie.SecurePolicy = CookieSecurePolicy.Always;

            /*
             * Below event handler is to prevent stale logins from showing a 500 error screen, instead to force
             * back to the landing page - and cause a re-challenge or continue if already authenticated.
             * https://community.auth0.com/t/asp-net-core-2-intermittent-correlation-failed-errors/11918/14
             */
            options.Events.OnRemoteFailure += context =>
            {
                if (context.Failure.Message == "Correlation failed.")
                {
                    context.HandleResponse();
                    context.Response.Redirect("/");
                }

                return(Task.CompletedTask);
            };

            options.Events.OnSecurityTokenValidated += async context =>
            {
                var username = context.Principal.Username();
                if (username != null)
                {
                    var userService = context.HttpContext.RequestServices.GetRequiredService <IUserService>();
                    await userService.RecordUserLoginAsync(username);
                }
            };
        })
                        .AddCookie(options =>
        {
            options.ForwardAuthenticate = null;
            options.SlidingExpiration   = false;
            options.ExpireTimeSpan      = TimeSpan.FromMinutes(adOptions.MaxSessionCookieLifetimeInMinutes);
        });
    }
    private static void UseHttpBasicAuth(IServiceCollection services,
                                         IConfigurationSection httpBasicAuthConfig,
                                         AdOptions adOptions)
    {
        services
        .AddAuthentication(BasicAuthenticationDefaults.AuthenticationScheme)
        .AddBasicAuthentication(
            options =>
        {
            options.Realm  = "Basic Realm";
            options.Events = new BasicAuthenticationEvents
            {
                OnValidatePrincipal = context =>
                {
                    if ((context.UserName.ToLower() == httpBasicAuthConfig["Username"].ToLower()) &&
                        (context.Password == httpBasicAuthConfig["Password"]))
                    {
                        var groupAdmin = adOptions.AdminUserGroup;
                        var groupDev   = adOptions.DevGroup ?? adOptions.NationalTeamAdGroup;
                        var claims     = new List <Claim>
                        {
                            new Claim(ClaimTypes.Name,
                                      context.UserName,
                                      context.Options.ClaimsIssuer),
                            new Claim(ClaimTypes.Role, adOptions.BaseUserGroup, ClaimValueTypes.String),
                            new Claim(ClaimTypes.Role, groupAdmin, ClaimValueTypes.String),
                            new Claim(ClaimTypes.Role, groupDev, ClaimValueTypes.String)
                        };

                        var claimsPrincipal = new ClaimsPrincipal(new ClaimsIdentity(
                                                                      claims,
                                                                      BasicAuthenticationDefaults.AuthenticationScheme));
                        var ticket = new AuthenticationTicket(
                            claimsPrincipal,
                            new AuthenticationProperties(),
                            BasicAuthenticationDefaults.AuthenticationScheme);

                        context.Principal = claimsPrincipal;

                        // Returning the ticket, though it doesn't seem to be used (at least in the initial
                        // logic) - hence setting the Principal above, too.
                        return(Task.FromResult(AuthenticateResult.Success(ticket)));
                    }

                    return(Task.FromResult(AuthenticateResult.Fail("Authentication  really failed.")));
                }
            };
        });
    }
        /// <summary>
        /// Request a rewarded video
        /// </summary>
        private void RequestRewarded()
        {
            if (string.IsNullOrEmpty(rewardedZoneId))
            {
                return;
            }
            if (debug)
            {
                Debug.Log(this + " Request Rewarded");
                ScreenWriter.Write(this + " Request Rewarded");
            }

            AdOptions adOptions = new AdOptions();

            adOptions.ShowPrePopup  = false;
            adOptions.ShowPostPopup = false;
            Ads.RequestInterstitialAd(rewardedZoneId, adOptions);
        }
Exemple #13
0
        protected override void InternalLoadRewardedAd(AdPlacement placement)
        {
            #if EM_ADCOLONY
            var adOptions = new AdOptions()
            {
                ShowPrePopup  = mAdSettings.EnableRewardedAdPrePopup,
                ShowPostPopup = mAdSettings.EnableRewardedAdPostPopup
            };

            string id = placement == AdPlacement.Default ?
                        mAdSettings.DefaultRewardedAdId.Id : FindIdForPlacement(mAdSettings.CustomRewardedAdIds, placement);

            if (!string.IsNullOrEmpty(id))
            {
                Ads.RequestInterstitialAd(id, adOptions);
            }
            else
            {
                Debug.Log("Attempting to load AdColony rewarded ad with an undefined ID at placement " + AdPlacement.GetPrintableName(placement));
            }
            #endif
        }
Exemple #14
0
    private void RequestInterstitial()
    {
        AdOptions adOptions = new AdOptions();

        Ads.RequestInterstitialAd("vzc2600c4251094143b0", adOptions);
    }
 public UserRepository(NtbsContext context, IOptionsMonitor <AdOptions> adOptions)
 {
     _adOptions = adOptions.CurrentValue;
     _context   = context;
 }
        // Creates WindowAd instance.
        public WindowAd(string adAppId, string adUnitId, GameObject gameObject, AdOptions adOptions)
        {
            client = AtmosplayAdsClientFactory.BuildWindowAdClient(adAppId, adUnitId, gameObject);

            if (adOptions == null)
            {
                adOptions = new AdOptionsBuilder().build();
            }
            client.SetChannelId(adOptions.mChannelId);

            client.OnAdLoaded += (sender, args) =>
            {
                if (OnAdLoaded != null)
                {
                    OnAdLoaded(this, args);
                }
            };

            client.OnAdFailedToLoad += (sender, args) =>
            {
                if (OnAdFailedToLoad != null)
                {
                    OnAdFailedToLoad(this, args);
                }
            };

            client.OnAdStarted += (sender, args) =>
            {
                if (OnAdStarted != null)
                {
                    OnAdStarted(this, args);
                }
            };

            client.OnAdClicked += (sender, args) =>
            {
                if (OnAdClicked != null)
                {
                    OnAdClicked(this, args);
                }
            };

            client.OnAdFinished += (sender, args) =>
            {
                if (OnAdFinished != null)
                {
                    OnAdFinished(this, args);
                }
            };

            client.OnAdClosed += (sender, args) =>
            {
                if (OnAdClosed != null)
                {
                    OnAdClosed(this, args);
                }
            };

            client.OnAdFailToShow += (sender, args) =>
            {
                if (OnAdFailToShow != null)
                {
                    OnAdFailToShow(this, args);
                }
            };
        }
Exemple #17
0
 public UserHelper(IOptionsMonitor <AdOptions> adOptions)
 {
     _adOptions = adOptions.CurrentValue;
 }
Exemple #18
0
 public AdService(ILogger <AdService> logger, IOptions <AdOptions> options, IMapper mapper) : base(logger)
 {
     _adOptions = options.Value;
     _mapper    = mapper;
 }
    public static void ConfigureServices(WebApplicationBuilder builder)
    {
        var services = builder.Services;

        // This was helpful for identifying issues with ADFS login - but shouldn't be on usually
        // IdentityModelEventSource.ShowPII = true;
        services.Configure <ForwardedHeadersOptions>(options =>
        {
            options.ForwardedHeaders = ForwardedHeaders.All;
            options.KnownNetworks.Clear();
            options.KnownProxies.Clear();
        });

        // Configuration
        services.Configure <CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded    = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddHsts(options =>
        {
            options.MaxAge = TimeSpan.FromSeconds(63072000); // Two years
        });

        var adConfig                  = builder.Configuration.GetSection("AdOptions");
        var adfsConfig                = builder.Configuration.GetSection("AdfsOptions");
        var azureAdConfig             = builder.Configuration.GetSection("AzureAdOptions");
        var applicationInsightsConfig = builder.Configuration.GetSection("ApplicationInsightsOptions");

        var adOptions                  = new AdOptions();
        var adfsOptions                = new AdfsOptions();
        var azureAdOptions             = new AzureAdOptions();
        var applicationInsightsOptions = new ApplicationInsightsOptions();

        adConfig.Bind(adOptions);
        adfsConfig.Bind(adfsOptions);
        azureAdConfig.Bind(azureAdOptions);
        applicationInsightsConfig.Bind(applicationInsightsOptions);

        services.Configure <AdOptions>(adConfig);
        services.Configure <AdfsOptions>(adfsConfig);
        services.Configure <AzureAdOptions>(azureAdConfig);
        services.Configure <LdapSettings>(builder.Configuration.GetSection("LdapSettings"));
        services.Configure <MigrationConfig>(builder.Configuration.GetSection("MigrationConfig"));

        // Plugin services
        if (builder.Environment.IsEnvironment("CI"))
        {
            services.AddDistributedMemoryCache();
        }
        else
        {
            services.AddDistributedSqlServerCache(options =>
            {
                options.ConnectionString = builder.Configuration.GetConnectionString("ntbsContext");
                options.SchemaName       = "dbo";
                options.TableName        = "SessionState";
            });
        }

        services.AddSession(options =>
        {
            options.Cookie.IsEssential  = true;
            options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
        });

        // select authentication method
        var httpBasicAuthConfig = builder.Configuration.GetSection("HttpBasicAuth");
        var basicAuthEnabled    = httpBasicAuthConfig.GetValue("Enabled", false);
        var azureAdAuthEnabled  = azureAdOptions.Enabled;

        Log.Information($"Basic Auth Enabled: {basicAuthEnabled}");
        Log.Information($"Azure Ad Auth Enabled: {azureAdAuthEnabled}");

        var baseUserGroupRole = adOptions.BaseUserGroup;

        if (adOptions.UseDummyAuth)
        {
            UseDummyAuth(services);
        }
        else if (basicAuthEnabled)
        {
            UseHttpBasicAuth(services, httpBasicAuthConfig, adOptions);
        }
        else if (azureAdAuthEnabled)
        {
            UseAzureAdAuthentication(services, adOptions, azureAdOptions);
        }
        else
        {
            UseAdfsAuthentication(services, adOptions, adfsOptions);
        }

        services.AddControllersWithViews(options =>
        {
            var policy = new AuthorizationPolicyBuilder()
                         .RequireAuthenticatedUser()
                         .RequireRole(baseUserGroupRole)
                         .Build();
            options.Filters.Add(new AuthorizeFilter(policy));
        }).AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
        });
        services.AddRazorPages(options =>
        {
            options.Conventions.AllowAnonymousToPage("/Account/AccessDenied");
            options.Conventions.AllowAnonymousToPage("/Logout");
            options.Conventions.AllowAnonymousToPage("/PostLogout");
        });

        services.AddAuthorization(options =>
        {
            options.AddPolicy("AdminOnly", policy =>
            {
                policy.RequireRole(builder.Configuration.GetSection("AdOptions")["AdminUserGroup"]);
            });
        });
        SetupHangfire(builder);

        var auditDbConnectionString = builder.Configuration.GetConnectionString("auditContext");

        if (!builder.Environment.IsEnvironment("CI"))
        {
            // DB Contexts
            services.AddDbContext <NtbsContext>(options =>
                                                options.UseSqlServer(builder.Configuration.GetConnectionString("ntbsContext"))
                                                );

            services.AddSingleton <NtbsContextDesignTimeFactory>();

            services.AddDbContext <AuditDatabaseContext>(options =>
                                                         options.UseSqlServer(auditDbConnectionString)
                                                         );

            // Add a DbContext for Data Protection key storage
            services.AddDbContext <KeysContext>(options =>
                                                options.UseSqlServer(builder.Configuration.GetConnectionString("keysContext")));
            services.AddDataProtection().PersistKeysToDbContext <KeysContext>();
        }

        // Repositories
        services.AddScoped <INotificationRepository, NotificationRepository>();
        services.AddScoped <IReferenceDataRepository, ReferenceDataRepository>();
        services.AddScoped <IAlertRepository, AlertRepository>();
        services.AddScoped <INotificationImportRepository, NotificationImportRepository>();
        services.AddScoped <IMigratedNotificationsMarker, MigratedNotificationsMarker>();
        services.AddScoped <INotificationImportHelper, NotificationImportHelper>();
        services.AddScoped <IMigrationRepository, MigrationRepository>();
        services.AddScoped <IItemRepository <ManualTestResult>, TestResultRepository>();
        services.AddScoped <IItemRepository <SocialContextVenue>, SocialContextVenueRepository>();
        services.AddScoped <IItemRepository <SocialContextAddress>, SocialContextAddressRepository>();
        services.AddScoped <ITreatmentEventRepository, TreatmentEventRepository>();
        services.AddScoped <IItemRepository <MBovisExposureToKnownCase>, MBovisExposureToKnownCaseRepository>();
        services
        .AddScoped <IItemRepository <MBovisUnpasteurisedMilkConsumption>,
                    MBovisUnpasteurisedMilkConsumptionRepository>();
        services.AddScoped <IItemRepository <MBovisOccupationExposure>, MBovisOccupationExposureRepository>();
        services.AddScoped <IItemRepository <MBovisAnimalExposure>, MBovisAnimalExposureRepository>();
        services.AddScoped <IUserRepository, UserRepository>();
        services.AddScoped <IDataQualityRepository, DataQualityRepository>();
        services.AddScoped <IDrugResistanceProfileRepository, DrugResistanceProfileRepository>();

        // Services
        services.AddScoped <INotificationService, NotificationService>();
        services.AddScoped <IAlertService, AlertService>();
        services.AddScoped <INotificationMapper, NotificationMapper>();
        services.AddScoped <IImportLogger, ImportLogger>();
        services.AddScoped <INotificationImportService, NotificationImportService>();
        services.AddScoped <IImportValidator, ImportValidator>();
        services.AddScoped <ISearchService, SearchService>();
        services.AddScoped <IAuditService, AuditService>();
        services.AddScoped <INotificationChangesService, NotificationChangesService>();
        services.AddScoped <IUserService, UserService>();
        services.AddScoped <IPostcodeService, PostcodeService>();
        services.AddScoped <ntbs_service.Services.IAuthorizationService, AuthorizationService>();
        services.AddScoped <ILegacySearchService, LegacySearchService>();
        services.AddScoped <IAdDirectoryServiceFactory, AdDirectoryServiceFactory>();
        services.AddScoped <IEnhancedSurveillanceAlertsService, EnhancedSurveillanceAlertsService>();
        services.AddScoped <IUserSearchService, UserSearchService>();
        services.AddScoped <IServiceDirectoryService, ServiceDirectoryService>();
        services.AddScoped <IClusterImportService, ClusterImportService>();
        services.AddScoped <ISpecimenImportService, SpecimenImportService>();
        services.AddScoped <ICaseManagerImportService, CaseManagerImportService>();
        services.AddScoped <IAdUserService, AdUserService>();
        services.AddScoped <IExternalLinksService, ExternalLinksService>();
        services.AddScoped <ITreatmentEventMapper, TreatmentEventMapper>();
        services.AddScoped <IUserHelper, UserHelper>();
        services.AddScoped <ILogService, LogService>();
        services.AddScoped <ITableCountsRepository, TableCountsRepository>();
        services.AddScoped <IExternalStoredProcedureRepository, ExternalStoredProcedureRepository>();

        AddAuditService(builder, auditDbConnectionString);
        AddReferenceLabResultServices(builder);
        AddNotificationClusterRepository(builder);
        AddReportingServices(builder);
        AddMicrosoftGraphServices(services, azureAdOptions);
        AddAdImportService(builder, azureAdOptions);
        AddApplicationInsightsMonitoring(services, applicationInsightsOptions);
    }
    private static void UseAzureAdAuthentication(IServiceCollection services, AdOptions adOptions,
                                                 AzureAdOptions azureAdOptions)
    {
        var authSetup = services
                        .AddAuthentication(sharedOptions =>
        {
            sharedOptions.DefaultScheme             = CookieAuthenticationDefaults.AuthenticationScheme;
            sharedOptions.DefaultAuthenticateScheme = OpenIdConnectDefaults.AuthenticationScheme;
            sharedOptions.DefaultChallengeScheme    = OpenIdConnectDefaults.AuthenticationScheme;
        })
                        .AddCookie(options =>
        {
            options.ForwardAuthenticate = null;
            options.SlidingExpiration   = false;
            options.ExpireTimeSpan      = TimeSpan.FromMinutes(adOptions.MaxSessionCookieLifetimeInMinutes);
        })
                        .AddOpenIdConnect(options =>
        {
            options.ClientId     = azureAdOptions.ClientId;
            options.ClientSecret = azureAdOptions.ClientSecret;
            options.Authority    = azureAdOptions.Authority;
            options.CallbackPath = azureAdOptions.CallbackPath;
            options.CorrelationCookie.SameSite     = SameSiteMode.None;
            options.CorrelationCookie.SecurePolicy = CookieSecurePolicy.Always;
            options.NonceCookie.SecurePolicy       = CookieSecurePolicy.Always;

            options.Events = new OpenIdConnectEvents();
            options.Events.OnTokenValidated += async context =>
            {
                var username = context.Principal.Username();
                if (username == null)
                {
                    username = context.Principal.FindFirstValue(ClaimTypes.Email);
                }

                // add group claims.
                if (username != null)
                {
                    var claims         = new List <Claim>();
                    var azureAdFactory = context.HttpContext.RequestServices
                                         .GetRequiredService <IAzureAdDirectoryServiceFactory>();
                    var azureAdDirectoryService = azureAdFactory.Create();

                    var groupClaims = await azureAdDirectoryService.BuildRoleClaimsForUser(username);
                    claims.AddRange(groupClaims);

                    var upnClaim = new Claim(ClaimTypes.Upn, username);
                    claims.Add(upnClaim);

                    var applicationClaimsIdentity = new ClaimsIdentity(claims);
                    context.Principal.AddIdentity(applicationClaimsIdentity);
                }

                if (username != null)
                {
                    var userService = context.HttpContext.RequestServices.GetRequiredService <IUserService>();
                    await userService.RecordUserLoginAsync(username);
                }
            };

            /*
             * Below event handler is to prevent stale logins from showing a 500 error screen, instead to force
             * back to the landing page - and cause a re-challenge or continue if already authenticated.
             * https://community.auth0.com/t/asp-net-core-2-intermittent-correlation-failed-errors/11918/14
             */
            options.Events.OnRemoteFailure += context =>
            {
                if (context.Failure.Message == "Correlation failed.")
                {
                    context.HandleResponse();
                    context.Response.Redirect("/");
                }

                return(Task.CompletedTask);
            };
        });
    }