/// <summary> /// 一句配置Session和登陆Cookie /// 需在Configure中加入 app.UseAuthentication() 以使得登陆配置生效 /// </summary> /// <param name="services"></param> /// <param name="sessionTimeOutHours">Session过期回收时间(默认2小时)</param> /// <param name="loginPath">用户登陆路径</param> /// <param name="accessDeniedPath">禁止访问路径,不设置则回到登陆页</param> /// <param name="returnUrlParameter">上一页面地址回传参数</param> /// <param name="cookieDomain">Cookie作用域</param> /// <param name="securePolicy">Cookie安全策略</param> /// <returns></returns> public static IServiceCollection AddSessionAndCookie(this IServiceCollection services, double sessionTimeOutHours = 2, string loginPath = "/Account/Login", string accessDeniedPath = null, string returnUrlParameter = "ReturnUrl", string cookieDomain = null, CookieSecurePolicy securePolicy = CookieSecurePolicy.SameAsRequest) { services.AddMemoryCache(); services .AddSession(options => { var cookie = options.Cookie; cookie.HttpOnly = true; cookie.SecurePolicy = securePolicy; options.IdleTimeout = TimeSpan.FromHours(sessionTimeOutHours); }) .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options => { options.LoginPath = new PathString(loginPath); options.ReturnUrlParameter = returnUrlParameter; options.AccessDeniedPath = new PathString(accessDeniedPath ?? loginPath); options.Cookie.HttpOnly = true; options.Cookie.SecurePolicy = securePolicy; options.Cookie.Domain = cookieDomain; }); return(services); }
public static CookieAuthenticationOptions SetupOtherCookies( this IApplicationBuilder app, string scheme, bool useRelatedSitesMode, SiteContext tenant, CookieSecurePolicy cookieSecure = CookieSecurePolicy.None ) { var options = new CookieAuthenticationOptions(); if (useRelatedSitesMode) { options.AuthenticationScheme = scheme; options.CookieName = scheme; options.CookiePath = "/"; } else { //options.AuthenticationScheme = $"{scheme}-{tenant.SiteFolderName}"; options.AuthenticationScheme = scheme; options.CookieName = $"{scheme}-{tenant.SiteFolderName}"; options.CookiePath = "/" + tenant.SiteFolderName; } options.AutomaticAuthenticate = false; if (cookieSecure != CookieSecurePolicy.None) { options.CookieSecure = cookieSecure; } return(options); }
public async Task SecureSessionBasedOnHttpsAndSecurePolicy( CookieSecurePolicy cookieSecurePolicy, string requestUri, bool shouldBeSecureOnly) { using var host = new HostBuilder() .ConfigureWebHost(webHostBuilder => { webHostBuilder .UseTestServer() .Configure(app => { app.UseSession(new SessionOptions { Cookie = { Name = "TestCookie", SecurePolicy = cookieSecurePolicy } }); app.Run(context => { Assert.Null(context.Session.GetString("Key")); context.Session.SetString("Key", "Value"); Assert.Equal("Value", context.Session.GetString("Key")); return(Task.FromResult(0)); }); }) .ConfigureServices(services => { services.AddDistributedMemoryCache(); services.AddSession(); }); }).Build(); await host.StartAsync(); using (var server = host.GetTestServer()) { var client = server.CreateClient(); var response = await client.GetAsync(requestUri); response.EnsureSuccessStatusCode(); Assert.True(response.Headers.TryGetValues("Set-Cookie", out var values)); Assert.Single(values); if (shouldBeSecureOnly) { Assert.Contains("; secure", values.First()); } else { Assert.DoesNotContain("; secure", values.First()); } } }
public static IApplicationBuilder UseCloudscribeCoreDefaultAuthentication( this IApplicationBuilder builder, ILoggerFactory loggerFactory, MultiTenantOptions multiTenantOptions, SiteContext tenant, CookieSecurePolicy applicationCookieSecure = CookieSecurePolicy.SameAsRequest ) { var useFolder = !multiTenantOptions.UseRelatedSitesMode && multiTenantOptions.Mode == cloudscribe.Core.Models.MultiTenantMode.FolderName && tenant.SiteFolderName.Length > 0; var externalCookieOptions = builder.SetupOtherCookies( AuthenticationScheme.External, multiTenantOptions.UseRelatedSitesMode, tenant); builder.UseCookieAuthentication(externalCookieOptions); var twoFactorRememberMeCookieOptions = builder.SetupOtherCookies( AuthenticationScheme.TwoFactorRememberMe, multiTenantOptions.UseRelatedSitesMode, tenant); builder.UseCookieAuthentication(twoFactorRememberMeCookieOptions); var twoFactorUserIdCookie = builder.SetupOtherCookies( AuthenticationScheme.TwoFactorUserId, multiTenantOptions.UseRelatedSitesMode, tenant); builder.UseCookieAuthentication(twoFactorUserIdCookie); //var cookieEvents = new CookieAuthenticationEvents(); var logger = loggerFactory.CreateLogger <SiteAuthCookieValidator>(); var cookieValidator = new SiteAuthCookieValidator(logger); var appCookieOptions = builder.SetupAppCookie( cookieValidator, AuthenticationScheme.Application, multiTenantOptions.UseRelatedSitesMode, tenant, applicationCookieSecure ); builder.UseCookieAuthentication(appCookieOptions); // known issue here is if a site is updated to populate the // social auth keys, it currently requires a restart so that the middleware gets registered // in order for it to work or for the social auth buttons to appear builder.UseSocialAuth(tenant, externalCookieOptions, useFolder); return(builder); }
/// <summary> /// this overload is deprecated, the ILoggerFactory is not used or needed here /// </summary> /// <param name="app"></param> /// <param name="loggerFactory"></param> /// <param name="multiTenantOptions"></param> /// <param name="sslIsAvailable"></param> /// <param name="applicationCookieSecure"></param> /// <returns></returns> public static IApplicationBuilder UseCloudscribeCore( this IApplicationBuilder app, ILoggerFactory loggerFactory, MultiTenantOptions multiTenantOptions, bool sslIsAvailable = false, CookieSecurePolicy applicationCookieSecure = CookieSecurePolicy.SameAsRequest ) { app.UseCloudscribeCore(multiTenantOptions, sslIsAvailable, applicationCookieSecure); return(app); }
public static IApplicationBuilder UseCloudscribeCoreDefaultAuthentication( this IApplicationBuilder builder, ILoggerFactory loggerFactory, MultiTenantOptions multiTenantOptions, SiteContext tenant, bool sslIsAvailable = true, CookieSecurePolicy applicationCookieSecure = CookieSecurePolicy.SameAsRequest ) { var useFolder = !multiTenantOptions.UseRelatedSitesMode && multiTenantOptions.Mode == cloudscribe.Core.Models.MultiTenantMode.FolderName && tenant.SiteFolderName.Length > 0; var externalCookieOptions = builder.SetupOtherCookies( AuthenticationScheme.External, multiTenantOptions.UseRelatedSitesMode, tenant); builder.UseCookieAuthentication(externalCookieOptions); var twoFactorRememberMeCookieOptions = builder.SetupOtherCookies( AuthenticationScheme.TwoFactorRememberMe, multiTenantOptions.UseRelatedSitesMode, tenant); builder.UseCookieAuthentication(twoFactorRememberMeCookieOptions); var twoFactorUserIdCookie = builder.SetupOtherCookies( AuthenticationScheme.TwoFactorUserId, multiTenantOptions.UseRelatedSitesMode, tenant); builder.UseCookieAuthentication(twoFactorUserIdCookie); //var cookieEvents = new CookieAuthenticationEvents(); var logger = loggerFactory.CreateLogger <SiteAuthCookieValidator>(); var cookieValidator = new SiteAuthCookieValidator(logger); var appCookieOptions = builder.SetupAppCookie( cookieValidator, AuthenticationScheme.Application, multiTenantOptions.UseRelatedSitesMode, tenant, applicationCookieSecure ); builder.UseCookieAuthentication(appCookieOptions); builder.UseSocialAuth(tenant, externalCookieOptions, useFolder, sslIsAvailable); return(builder); }
public void ConfiguresSecurePolicy(CookieSecurePolicy policy, bool requestIsHttps, bool secure) { var builder = new CookieBuilder { SecurePolicy = policy }; var context = new DefaultHttpContext(); context.Request.IsHttps = requestIsHttps; var options = builder.Build(context); Assert.Equal(secure, options.Secure); }
public static IApplicationBuilder UseCloudscribeCoreDefaultAuthentication( this IApplicationBuilder builder, ILoggerFactory loggerFactory, MultiTenantOptions multiTenantOptions, SiteContext tenant, CookieSecurePolicy applicationCookieSecure = CookieSecurePolicy.SameAsRequest ) { var useFolder = !multiTenantOptions.UseRelatedSitesMode && multiTenantOptions.Mode == cloudscribe.Core.Models.MultiTenantMode.FolderName && tenant.SiteFolderName.Length > 0; var externalCookieOptions = builder.SetupOtherCookies( AuthenticationScheme.External, multiTenantOptions.UseRelatedSitesMode, tenant); builder.UseCookieAuthentication(externalCookieOptions); var twoFactorRememberMeCookieOptions = builder.SetupOtherCookies( AuthenticationScheme.TwoFactorRememberMe, multiTenantOptions.UseRelatedSitesMode, tenant); builder.UseCookieAuthentication(twoFactorRememberMeCookieOptions); var twoFactorUserIdCookie = builder.SetupOtherCookies( AuthenticationScheme.TwoFactorUserId, multiTenantOptions.UseRelatedSitesMode, tenant); builder.UseCookieAuthentication(twoFactorUserIdCookie); //var cookieEvents = new CookieAuthenticationEvents(); var logger = loggerFactory.CreateLogger<SiteAuthCookieValidator>(); var cookieValidator = new SiteAuthCookieValidator(logger); var appCookieOptions = builder.SetupAppCookie( cookieValidator, AuthenticationScheme.Application, multiTenantOptions.UseRelatedSitesMode, tenant, applicationCookieSecure ); builder.UseCookieAuthentication(appCookieOptions); // known issue here is if a site is updated to populate the // social auth keys, it currently requires a restart so that the middleware gets registered // in order for it to work or for the social auth buttons to appear builder.UseSocialAuth(tenant, externalCookieOptions, useFolder); return builder; }
public static IApplicationBuilder UseCloudscribeCore( this IApplicationBuilder app, CookieSecurePolicy applicationCookieSecure = CookieSecurePolicy.SameAsRequest ) { var multiTenantOptionsAccessor = app.ApplicationServices.GetRequiredService <IOptions <cloudscribe.Core.Models.MultiTenantOptions> >(); var config = app.ApplicationServices.GetRequiredService <IConfiguration>(); var sslIsAvailable = config.GetValue <bool>("AppSettings:UseSsl"); var multiTenantOptions = multiTenantOptionsAccessor.Value; app.UseCloudscribeCore(multiTenantOptions, sslIsAvailable, applicationCookieSecure); return(app); }
public static IApplicationBuilder UseCloudscribeCore( this IApplicationBuilder app, ILoggerFactory loggerFactory, MultiTenantOptions multiTenantOptions, bool sslIsAvailable = false, CookieSecurePolicy applicationCookieSecure = CookieSecurePolicy.SameAsRequest ) { app.UseCloudscribeCommonStaticFiles(); app.UseMultitenancy <cloudscribe.Core.Models.SiteContext>(); app.UsePerTenant <cloudscribe.Core.Models.SiteContext>((ctx, builder) => { if (!string.IsNullOrWhiteSpace(ctx.Tenant.ForcedCulture) && !string.IsNullOrWhiteSpace(ctx.Tenant.ForcedUICulture)) { var tenantLocalization = new RequestLocalizationOptions(); tenantLocalization.DefaultRequestCulture = new RequestCulture(culture: ctx.Tenant.ForcedCulture, uiCulture: ctx.Tenant.ForcedUICulture); tenantLocalization.SupportedCultures = new[] { new CultureInfo(ctx.Tenant.ForcedCulture) }; tenantLocalization.SupportedUICultures = new[] { new CultureInfo(ctx.Tenant.ForcedUICulture) }; builder.UseRequestLocalization(tenantLocalization); } // custom 404 and error page - this preserves the status code (ie 404) if (multiTenantOptions.Mode != cloudscribe.Core.Models.MultiTenantMode.FolderName || string.IsNullOrEmpty(ctx.Tenant.SiteFolderName)) { builder.UseStatusCodePagesWithReExecute("/oops/error/{0}"); } else { builder.UseStatusCodePagesWithReExecute("/" + ctx.Tenant.SiteFolderName + "/oops/error/{0}"); } // resolve static files from wwwroot folders within themes and within sitefiles builder.UseSiteAndThemeStaticFiles(loggerFactory, multiTenantOptions, ctx.Tenant); //builder.UseAuthentication(); }); app.UseCloudscribeEnforceSiteRulesMiddleware(); app.UseAuthentication(); return(app); }
public async Task SecureSessionBasedOnHttpsAndSecurePolicy( CookieSecurePolicy cookieSecurePolicy, string requestUri, bool shouldBeSecureOnly) { var builder = new WebHostBuilder() .Configure(app => { app.UseSession(new SessionOptions { CookieName = "TestCookie", CookieSecure = cookieSecurePolicy }); app.Run(context => { Assert.Null(context.Session.GetString("Key")); context.Session.SetString("Key", "Value"); Assert.Equal("Value", context.Session.GetString("Key")); return(Task.FromResult(0)); }); }) .ConfigureServices(services => { services.AddSingleton <IDistributedCache>(new FauxCouchbaseCache()); services.AddCouchbaseSession(); }); using (var server = new TestServer(builder)) { var client = server.CreateClient(); var response = await client.GetAsync(requestUri); response.EnsureSuccessStatusCode(); IEnumerable <string> values; Assert.True(response.Headers.TryGetValues("Set-Cookie", out values)); Assert.Equal(1, values.Count()); if (shouldBeSecureOnly) { Assert.Contains("; secure", values.First()); } else { Assert.DoesNotContain("; secure", values.First()); } } }
public void SaveTempData_HonorsCookieSecurePolicy_OnOptions( bool isRequestSecure, CookieSecurePolicy cookieSecurePolicy, bool expectedSecureFlag) { // Arrange var values = new Dictionary <string, object>(); values.Add("int", 10); var tempDataProviderStore = new TempDataSerializer(); var expectedDataToProtect = tempDataProviderStore.Serialize(values); var expectedDataInCookie = WebEncoders.Base64UrlEncode(expectedDataToProtect); var dataProtector = new PassThroughDataProtector(); var options = new CookieTempDataProviderOptions(); options.Cookie.SecurePolicy = cookieSecurePolicy; var tempDataProvider = GetProvider(dataProtector, options); var responseCookies = new MockResponseCookieCollection(); var httpContext = new Mock <HttpContext>(); httpContext .SetupGet(hc => hc.Request.PathBase) .Returns("/"); httpContext .SetupGet(hc => hc.Request.IsHttps) .Returns(isRequestSecure); httpContext .Setup(hc => hc.Response.Cookies) .Returns(responseCookies); // Act tempDataProvider.SaveTempData(httpContext.Object, values); // Assert Assert.Equal(1, responseCookies.Count); var cookieInfo = responseCookies[CookieTempDataProvider.CookieName]; Assert.NotNull(cookieInfo); Assert.Equal(expectedDataInCookie, cookieInfo.Value); Assert.Equal(expectedDataToProtect, dataProtector.PlainTextToProtect); Assert.Equal("/", cookieInfo.Options.Path); Assert.Equal(expectedSecureFlag, cookieInfo.Options.Secure); Assert.True(cookieInfo.Options.HttpOnly); Assert.Null(cookieInfo.Options.Expires); Assert.Null(cookieInfo.Options.Domain); }
public void SaveCookieToken_HonorsCookieSecurePolicy_OnOptions( bool isRequestSecure, CookieSecurePolicy policy, bool?expectedCookieSecureFlag) { // Arrange var token = "serialized-value"; bool defaultCookieSecureValue = expectedCookieSecureFlag ?? false; // pulled from config; set by ctor var cookies = new MockResponseCookieCollection(); var httpContext = new Mock <HttpContext>(); httpContext .Setup(hc => hc.Request.IsHttps) .Returns(isRequestSecure); httpContext .Setup(o => o.Response.Cookies) .Returns(cookies); httpContext .SetupGet(hc => hc.Request.PathBase) .Returns("/"); var options = new AntiforgeryOptions() { Cookie = { Name = _cookieName, SecurePolicy = policy }, }; var tokenStore = new DefaultAntiforgeryTokenStore(new TestOptionsManager(options)); // Act tokenStore.SaveCookieToken(httpContext.Object, token); // Assert Assert.Equal(1, cookies.Count); Assert.NotNull(cookies); Assert.Equal(_cookieName, cookies.Key); Assert.Equal("serialized-value", cookies.Value); Assert.True(cookies.Options !.HttpOnly); Assert.Equal(defaultCookieSecureValue, cookies.Options.Secure); }
public static CookieAuthenticationOptions SetupAppCookie( this IApplicationBuilder app, SiteAuthCookieValidator siteValidator, string scheme, bool useRelatedSitesMode, SiteContext tenant, CookieSecurePolicy cookieSecure = CookieSecurePolicy.SameAsRequest ) { var cookieEvents = new CookieAuthenticationEvents(); var options = new CookieAuthenticationOptions(); if (useRelatedSitesMode) { options.AuthenticationScheme = scheme; options.CookieName = scheme; options.CookiePath = "/"; } else { //options.AuthenticationScheme = $"{scheme}-{tenant.SiteFolderName}"; options.AuthenticationScheme = scheme; options.CookieName = $"{scheme}-{tenant.SiteFolderName}"; options.CookiePath = "/" + tenant.SiteFolderName; cookieEvents.OnValidatePrincipal = siteValidator.ValidatePrincipal; } var tenantPathBase = string.IsNullOrEmpty(tenant.SiteFolderName) ? PathString.Empty : new PathString("/" + tenant.SiteFolderName); options.LoginPath = tenantPathBase + "/account/login"; options.LogoutPath = tenantPathBase + "/account/logoff"; options.AccessDeniedPath = tenantPathBase + "/account/accessdenied"; options.Events = cookieEvents; options.AutomaticAuthenticate = true; options.AutomaticChallenge = false; options.CookieSecure = cookieSecure; return(options); }
/// <summary> /// Add SAML 2.0 configuration. /// </summary> /// <param name="loginPath">Redirection target used by the handler.</param> /// <param name="slidingExpiration">If set to true the handler re-issue a new cookie with a new expiration time any time it processes a request which is more than halfway through the expiration window.</param> /// <param name="accessDeniedPath">If configured, access denied redirection target used by the handler.</param> /// <param name="sessionStore">Allow configuration of a custom ITicketStore.</param> /// <param name="cookieSameSite">The SameSite attribute of the cookie. The default value is Microsoft.AspNetCore.Http.SameSiteMode.Lax</param> /// <param name="cookieDomain">If configured, the domain to associate the cookie with.</param> /// <param name="cookieSecurePolicy">The cookie policy. The default value is Microsoft.AspNetCore.Http.CookieSecurePolicy.SameAsRequest.</param> public static IServiceCollection AddSaml2(this IServiceCollection services, string loginPath = "/Auth/Login", bool slidingExpiration = false, string accessDeniedPath = null, ITicketStore sessionStore = null, SameSiteMode cookieSameSite = SameSiteMode.Lax, string cookieDomain = null, CookieSecurePolicy cookieSecurePolicy = CookieSecurePolicy.SameAsRequest) { services.AddAuthentication(Saml2Constants.AuthenticationScheme) .AddCookie(Saml2Constants.AuthenticationScheme, o => { o.LoginPath = new PathString(loginPath); o.SlidingExpiration = slidingExpiration; if (!string.IsNullOrEmpty(accessDeniedPath)) { o.AccessDeniedPath = new PathString(accessDeniedPath); } if (sessionStore != null) { o.SessionStore = sessionStore; } o.Cookie.SameSite = cookieSameSite; o.Cookie.SecurePolicy = cookieSecurePolicy; if (!string.IsNullOrEmpty(cookieDomain)) { o.Cookie.Domain = cookieDomain; } }); return(services); }
public async Task SecureSignInCausesSecureOnlyCookieByDefault( CookieSecurePolicy cookieSecurePolicy, string requestUri, bool shouldBeSecureOnly) { var server = CreateServer(new CookieAuthenticationOptions { LoginPath = new PathString("/login"), CookieName = "TestCookie", CookieSecure = cookieSecurePolicy }, SignInAsAlice); var transaction = await SendAsync(server, requestUri); var setCookie = transaction.SetCookie; if (shouldBeSecureOnly) { Assert.Contains("; secure", setCookie); } else { Assert.DoesNotContain("; secure", setCookie); } }
public static CookieAuthenticationOptions SetupAppCookie( this IApplicationBuilder app, SiteAuthCookieValidator siteValidator, string scheme, bool useRelatedSitesMode, SiteContext tenant, CookieSecurePolicy cookieSecure = CookieSecurePolicy.SameAsRequest ) { var cookieEvents = new CookieAuthenticationEvents(); var options = new CookieAuthenticationOptions(); if (useRelatedSitesMode) { options.AuthenticationScheme = scheme; options.CookieName = scheme; options.CookiePath = "/"; } else { //options.AuthenticationScheme = $"{scheme}-{tenant.SiteFolderName}"; options.AuthenticationScheme = scheme; options.CookieName = $"{scheme}-{tenant.SiteFolderName}"; options.CookiePath = "/" + tenant.SiteFolderName; cookieEvents.OnValidatePrincipal = siteValidator.ValidatePrincipal; } var tenantPathBase = string.IsNullOrEmpty(tenant.SiteFolderName) ? PathString.Empty : new PathString("/" + tenant.SiteFolderName); options.LoginPath = tenantPathBase + "/account/login"; options.LogoutPath = tenantPathBase + "/account/logoff"; options.AccessDeniedPath = tenantPathBase + "/account/accessdenied"; options.Events = cookieEvents; options.AutomaticAuthenticate = true; options.AutomaticChallenge = false; options.CookieSecure = cookieSecure; return options; }
public AnonymousIdCookieOptionsBuilder SetCustomCookieSecurePolicy(CookieSecurePolicy cookieSecurePolicy) { this.cookieSecurePolicy = cookieSecurePolicy; return(this); }
public static CookieAuthenticationOptions SetupOtherCookies( this IApplicationBuilder app, string scheme, bool useRelatedSitesMode, SiteContext tenant, CookieSecurePolicy cookieSecure = CookieSecurePolicy.None ) { var options = new CookieAuthenticationOptions(); if (useRelatedSitesMode) { options.AuthenticationScheme = scheme; options.CookieName = scheme; options.CookiePath = "/"; } else { //options.AuthenticationScheme = $"{scheme}-{tenant.SiteFolderName}"; options.AuthenticationScheme = scheme; options.CookieName = $"{scheme}-{tenant.SiteFolderName}"; options.CookiePath = "/" + tenant.SiteFolderName; } options.AutomaticAuthenticate = false; if (cookieSecure != CookieSecurePolicy.None) { options.CookieSecure = cookieSecure; } return options; }
public static IApplicationBuilder UseCloudscribeCore( this IApplicationBuilder app, ILoggerFactory loggerFactory, MultiTenantOptions multiTenantOptions, bool sslIsAvailable = false, Func <IApplicationBuilder, ISiteContext, bool> identityServerInvoker = null, CookieSecurePolicy applicationCookieSecure = CookieSecurePolicy.SameAsRequest ) { app.UseCloudscribeCommonStaticFiles(); app.UseMultitenancy <cloudscribe.Core.Models.SiteContext>(); app.UsePerTenant <cloudscribe.Core.Models.SiteContext>((ctx, builder) => { //var locOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>(); if (!string.IsNullOrWhiteSpace(ctx.Tenant.ForcedCulture) && !string.IsNullOrWhiteSpace(ctx.Tenant.ForcedUICulture)) { var tenantLocalization = new RequestLocalizationOptions(); tenantLocalization.DefaultRequestCulture = new RequestCulture(culture: ctx.Tenant.ForcedCulture, uiCulture: ctx.Tenant.ForcedUICulture); tenantLocalization.SupportedCultures = new[] { new CultureInfo(ctx.Tenant.ForcedCulture) }; tenantLocalization.SupportedUICultures = new[] { new CultureInfo(ctx.Tenant.ForcedUICulture) }; builder.UseRequestLocalization(tenantLocalization); } // custom 404 and error page - this preserves the status code (ie 404) if (multiTenantOptions.Mode != cloudscribe.Core.Models.MultiTenantMode.FolderName || string.IsNullOrEmpty(ctx.Tenant.SiteFolderName)) { builder.UseStatusCodePagesWithReExecute("/oops/error/{0}"); } else { builder.UseStatusCodePagesWithReExecute("/" + ctx.Tenant.SiteFolderName + "/oops/error/{0}"); } // resolve static files from wwwroot folders within themes and within sitefiles builder.UseSiteAndThemeStaticFiles(loggerFactory, multiTenantOptions, ctx.Tenant); builder.UseCloudscribeCoreDefaultAuthentication( loggerFactory, multiTenantOptions, ctx.Tenant, sslIsAvailable); // to make this multi tenant for folders we are // using a fork of IdentityServer4 and hoping to get changes so we don't need a fork // https://github.com/IdentityServer/IdentityServer4/issues/19 if (identityServerInvoker != null) { var addedIdentityServer = identityServerInvoker(builder, ctx.Tenant); } //builder.UseIdentityServer(); //// this sets up the authentication for apis within this application endpoint //// ie apis that are hosted in the same web app endpoint with the authority server //// this is not needed here if you are only using separate api endpoints //// it is needed in the startup of those separate endpoints //// note that with both cookie auth and jwt auth middleware the principal is merged from both the cookie and the jwt token if it is passed //builder.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions //{ // Authority = "https://localhost:44399", // // using the site aliasid as the scope so each tenant has a different scope // // you can view the aliasid from site settings // // clients must be configured with the scope to have access to the apis for the tenant // ApiName = ctx.Tenant.AliasId, // //RoleClaimType = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role", // //AuthenticationScheme = AuthenticationScheme.Application, // RequireHttpsMetadata = true //}); }); app.UseCloudscribeEnforceSiteRulesMiddleware(); return(app); }
public static AuthenticationBuilder AddCookieAuthentication(this IServiceCollection services, CookieSecurePolicy cookieSecurePolicy) => services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddCookie(cfg => { cfg.Cookie.SecurePolicy = cookieSecurePolicy; cfg.Events = new CookieAuthenticationEvents { OnValidatePrincipal = async context => { var userSession = context.HttpContext.RequestServices.GetRequiredService <IUserRepository>(); try { var userId = context.Principal.GetId(); var user = await userSession.GetByIdAsync(userId); var claimRoles = context.Principal.Claims.Where(c => c.Type == ClaimTypes.Role) .Select(c => c.Value); if (!(claimRoles.Except(user.Roles).Count() == 0 && user.Roles.Except(claimRoles).Count() == 0)) { await context.HttpContext.SignOutAsync(); context.RejectPrincipal(); } } catch (Exception e) when(e is FormatException || e is EntityNotFoundException) { context.RejectPrincipal(); } }, OnRedirectToAccessDenied = context => { context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; return(Task.CompletedTask); }, OnRedirectToLogin = context => { context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized; return(Task.CompletedTask); }, }; });