/// <inheritdoc /> public async Task InvokeAsync(HttpContext context, RequestDelegate next) { if (_runtimeState.Level < RuntimeLevel.Run || context.Request.IsBackOfficeRequest() || !_basicAuthService.IsBasicAuthEnabled()) { await next(context); return; } IPAddress clientIPAddress = context.Connection.RemoteIpAddress; if (_basicAuthService.IsIpAllowListed(clientIPAddress)) { await next(context); return; } AuthenticateResult authenticateResult = await context.AuthenticateBackOfficeAsync(); if (authenticateResult.Succeeded) { await next(context); return; } if (context.TryGetBasicAuthCredentials(out var username, out var password)) { IBackOfficeSignInManager backOfficeSignInManager = context.RequestServices.GetService <IBackOfficeSignInManager>(); if (backOfficeSignInManager is not null) { SignInResult signInResult = await backOfficeSignInManager.PasswordSignInAsync(username, password, false, true); if (signInResult.Succeeded) { await next.Invoke(context); } else { SetUnauthorizedHeader(context); } } else { SetUnauthorizedHeader(context); } } else { // no authorization header SetUnauthorizedHeader(context); } }
public TestAuthHandler( IOptionsMonitor <AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock, IBackOfficeSignInManager backOfficeSignInManager, IUserService userService, IUmbracoMapper umbracoMapper) : base(options, logger, encoder, clock) { _backOfficeSignInManager = backOfficeSignInManager; var user = userService.GetUserById(Constants.Security.SuperUserId); _fakeUser = umbracoMapper.Map <IUser, BackOfficeIdentityUser>(user); _fakeUser.SecurityStamp = "Needed"; }
public AuthenticationController( IBackOfficeSecurityAccessor backofficeSecurityAccessor, IBackOfficeUserManager backOfficeUserManager, IBackOfficeSignInManager signInManager, IUserService userService, ILocalizedTextService textService, IUmbracoMapper umbracoMapper, IOptionsSnapshot <GlobalSettings> globalSettings, IOptionsSnapshot <SecuritySettings> securitySettings, ILogger <AuthenticationController> logger, IIpResolver ipResolver, IOptionsSnapshot <UserPasswordConfigurationSettings> passwordConfiguration, IEmailSender emailSender, ISmsSender smsSender, IHostingEnvironment hostingEnvironment, LinkGenerator linkGenerator, IBackOfficeExternalLoginProviders externalAuthenticationOptions, IBackOfficeTwoFactorOptions backOfficeTwoFactorOptions, IHttpContextAccessor httpContextAccessor, IOptions <WebRoutingSettings> webRoutingSettings, ITwoFactorLoginService twoFactorLoginService) { _backofficeSecurityAccessor = backofficeSecurityAccessor; _userManager = backOfficeUserManager; _signInManager = signInManager; _userService = userService; _textService = textService; _umbracoMapper = umbracoMapper; _globalSettings = globalSettings.Value; _securitySettings = securitySettings.Value; _logger = logger; _ipResolver = ipResolver; _passwordConfiguration = passwordConfiguration.Value; _emailSender = emailSender; _smsSender = smsSender; _hostingEnvironment = hostingEnvironment; _linkGenerator = linkGenerator; _externalAuthenticationOptions = externalAuthenticationOptions; _backOfficeTwoFactorOptions = backOfficeTwoFactorOptions; _httpContextAccessor = httpContextAccessor; _webRoutingSettings = webRoutingSettings.Value; _twoFactorLoginService = twoFactorLoginService; }
public AuthenticationController( IBackOfficeSecurityAccessor backofficeSecurityAccessor, IBackOfficeUserManager backOfficeUserManager, IBackOfficeSignInManager signInManager, IUserService userService, ILocalizedTextService textService, IUmbracoMapper umbracoMapper, IOptions <GlobalSettings> globalSettings, IOptions <SecuritySettings> securitySettings, ILogger <AuthenticationController> logger, IIpResolver ipResolver, IOptions <UserPasswordConfigurationSettings> passwordConfiguration, IEmailSender emailSender, ISmsSender smsSender, IHostingEnvironment hostingEnvironment, LinkGenerator linkGenerator, IBackOfficeExternalLoginProviders externalAuthenticationOptions, IBackOfficeTwoFactorOptions backOfficeTwoFactorOptions, IHttpContextAccessor httpContextAccessor, IOptions <WebRoutingSettings> webRoutingSettings) : this( backofficeSecurityAccessor, backOfficeUserManager, signInManager, userService, textService, umbracoMapper, globalSettings, securitySettings, logger, ipResolver, passwordConfiguration, emailSender, smsSender, hostingEnvironment, linkGenerator, externalAuthenticationOptions, backOfficeTwoFactorOptions, StaticServiceProvider.Instance.GetRequiredService <IHttpContextAccessor>(), StaticServiceProvider.Instance.GetRequiredService <IOptions <WebRoutingSettings> >(), StaticServiceProvider.Instance.GetRequiredService <ITwoFactorLoginService>()) { }
public TwoFactorLoginController( IBackOfficeSecurityAccessor backOfficeSecurityAccessor, ILogger <TwoFactorLoginController> logger, ITwoFactorLoginService twoFactorLoginService, IBackOfficeSignInManager backOfficeSignInManager, IBackOfficeUserManager backOfficeUserManager, IOptionsSnapshot <TwoFactorLoginViewOptions> twoFactorLoginViewOptions) { _backOfficeSecurityAccessor = backOfficeSecurityAccessor; _logger = logger; if (twoFactorLoginService is not ITwoFactorLoginService2 twoFactorLoginService2) { throw new ArgumentException("twoFactorLoginService needs to implement ITwoFactorLoginService2 until the interfaces are merged", nameof(twoFactorLoginService)); } _twoFactorLoginService = twoFactorLoginService2; _backOfficeSignInManager = backOfficeSignInManager; _backOfficeUserManager = backOfficeUserManager; _twoFactorLoginViewOptions = twoFactorLoginViewOptions; }
public BackOfficeController( IBackOfficeUserManager userManager, IRuntimeState runtimeState, IRuntimeMinifier runtimeMinifier, IOptionsSnapshot <GlobalSettings> globalSettings, IHostingEnvironment hostingEnvironment, ILocalizedTextService textService, IGridConfig gridConfig, BackOfficeServerVariables backOfficeServerVariables, AppCaches appCaches, IBackOfficeSignInManager signInManager, IBackOfficeSecurityAccessor backofficeSecurityAccessor, ILogger <BackOfficeController> logger, IJsonSerializer jsonSerializer, IBackOfficeExternalLoginProviders externalLogins, IHttpContextAccessor httpContextAccessor, IBackOfficeTwoFactorOptions backOfficeTwoFactorOptions, IManifestParser manifestParser, ServerVariablesParser serverVariables, IOptions <SecuritySettings> securitySettings) { _userManager = userManager; _runtimeState = runtimeState; _runtimeMinifier = runtimeMinifier; _globalSettings = globalSettings.Value; _hostingEnvironment = hostingEnvironment; _textService = textService; _gridConfig = gridConfig ?? throw new ArgumentNullException(nameof(gridConfig)); _backOfficeServerVariables = backOfficeServerVariables; _appCaches = appCaches; _signInManager = signInManager; _backofficeSecurityAccessor = backofficeSecurityAccessor; _logger = logger; _jsonSerializer = jsonSerializer; _externalLogins = externalLogins; _httpContextAccessor = httpContextAccessor; _backOfficeTwoFactorOptions = backOfficeTwoFactorOptions; _manifestParser = manifestParser; _serverVariables = serverVariables; _securitySettings = securitySettings; }
public BackOfficeController( IBackOfficeUserManager userManager, IRuntimeState runtimeState, IRuntimeMinifier runtimeMinifier, IOptions <GlobalSettings> globalSettings, IHostingEnvironment hostingEnvironment, ILocalizedTextService textService, IGridConfig gridConfig, BackOfficeServerVariables backOfficeServerVariables, AppCaches appCaches, IBackOfficeSignInManager signInManager, IBackOfficeSecurityAccessor backofficeSecurityAccessor, ILogger <BackOfficeController> logger, IJsonSerializer jsonSerializer, IBackOfficeExternalLoginProviders externalLogins, IHttpContextAccessor httpContextAccessor, IBackOfficeTwoFactorOptions backOfficeTwoFactorOptions, IManifestParser manifestParser, ServerVariablesParser serverVariables) : this(userManager, runtimeState, runtimeMinifier, globalSettings, hostingEnvironment, textService, gridConfig, backOfficeServerVariables, appCaches, signInManager, backofficeSecurityAccessor, logger, jsonSerializer, externalLogins, httpContextAccessor, backOfficeTwoFactorOptions, manifestParser, serverVariables, StaticServiceProvider.Instance.GetRequiredService <IOptions <SecuritySettings> >() ) { }
public InstallApiController( DatabaseBuilder databaseBuilder, IProfilingLogger proflog, ILogger <InstallApiController> logger, InstallHelper installHelper, InstallStepCollection installSteps, InstallStatusTracker installStatusTracker, IRuntime runtime, IBackOfficeUserManager backOfficeUserManager, IBackOfficeSignInManager backOfficeSignInManager) { _databaseBuilder = databaseBuilder ?? throw new ArgumentNullException(nameof(databaseBuilder)); _proflog = proflog ?? throw new ArgumentNullException(nameof(proflog)); _installSteps = installSteps; _installStatusTracker = installStatusTracker; _runtime = runtime; _backOfficeUserManager = backOfficeUserManager; _backOfficeSignInManager = backOfficeSignInManager; InstallHelper = installHelper; _logger = logger; }
public CheckIfUserTicketDataIsStaleFilter( IRequestCache requestCache, IUmbracoMapper umbracoMapper, IUserService userService, IEntityService entityService, ILocalizedTextService localizedTextService, IOptions <GlobalSettings> globalSettings, IBackOfficeSignInManager backOfficeSignInManager, IBackOfficeAntiforgery backOfficeAntiforgery, IScopeProvider scopeProvider, AppCaches appCaches) { _requestCache = requestCache; _umbracoMapper = umbracoMapper; _userService = userService; _entityService = entityService; _localizedTextService = localizedTextService; _globalSettings = globalSettings; _backOfficeSignInManager = backOfficeSignInManager; _backOfficeAntiforgery = backOfficeAntiforgery; _scopeProvider = scopeProvider; _appCaches = appCaches; }
/// <inheritdoc /> public void Configure(CookieAuthenticationOptions options) { options.SlidingExpiration = false; options.ExpireTimeSpan = _globalSettings.TimeOut; options.Cookie.Domain = _securitySettings.AuthCookieDomain; options.Cookie.Name = _securitySettings.AuthCookieName; options.Cookie.HttpOnly = true; options.Cookie.SecurePolicy = _globalSettings.UseHttps ? CookieSecurePolicy.Always : CookieSecurePolicy.SameAsRequest; options.Cookie.Path = "/"; // For any redirections that may occur for the back office, they all go to the same path var backOfficePath = _globalSettings.GetBackOfficePath(_hostingEnvironment); options.AccessDeniedPath = backOfficePath; options.LoginPath = backOfficePath; options.LogoutPath = backOfficePath; options.DataProtectionProvider = _dataProtection; // NOTE: This is borrowed directly from aspnetcore source // Note: the purpose for the data protector must remain fixed for interop to work. IDataProtector dataProtector = options.DataProtectionProvider.CreateProtector( "Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", Constants.Security.BackOfficeAuthenticationType, "v2"); var ticketDataFormat = new TicketDataFormat(dataProtector); options.TicketDataFormat = new BackOfficeSecureDataFormat(_globalSettings.TimeOut, ticketDataFormat); // Custom cookie manager so we can filter requests options.CookieManager = new BackOfficeCookieManager( _umbracoContextAccessor, _runtimeState, _umbracoRequestPaths, _basicAuthService); options.Events = new CookieAuthenticationEvents { // IMPORTANT! If you set any of OnRedirectToLogin, OnRedirectToAccessDenied, OnRedirectToLogout, OnRedirectToReturnUrl // you need to be aware that this will bypass the default behavior of returning the correct status codes for ajax requests and // not redirecting for non-ajax requests. This is because the default behavior is baked into this class here: // https://github.com/dotnet/aspnetcore/blob/master/src/Security/Authentication/Cookies/src/CookieAuthenticationEvents.cs#L58 // It would be possible to re-use the default behavior if any of these need to be set but that must be taken into account else // our back office requests will not function correctly. For now we don't need to set/configure any of these callbacks because // the defaults work fine with our setup. OnValidatePrincipal = async ctx => { // We need to resolve the BackOfficeSecurityStampValidator per request as a requirement (even in aspnetcore they do this) BackOfficeSecurityStampValidator securityStampValidator = ctx.HttpContext.RequestServices.GetRequiredService <BackOfficeSecurityStampValidator>(); // Same goes for the signinmanager IBackOfficeSignInManager signInManager = ctx.HttpContext.RequestServices.GetRequiredService <IBackOfficeSignInManager>(); ClaimsIdentity?backOfficeIdentity = ctx.Principal?.GetUmbracoIdentity(); if (backOfficeIdentity == null) { ctx.RejectPrincipal(); await signInManager.SignOutAsync(); } // ensure the thread culture is set backOfficeIdentity?.EnsureCulture(); EnsureTicketRenewalIfKeepUserLoggedIn(ctx); // add or update a claim to track when the cookie expires, we use this to track time remaining backOfficeIdentity?.AddOrUpdateClaim(new Claim( Constants.Security.TicketExpiresClaimType, ctx.Properties.ExpiresUtc !.Value.ToString("o"), ClaimValueTypes.DateTime, Constants.Security.BackOfficeAuthenticationType, Constants.Security.BackOfficeAuthenticationType, backOfficeIdentity)); await securityStampValidator.ValidateAsync(ctx); // This might have been called from GetRemainingTimeoutSeconds, in this case we don't want to ensure valid session // since that in it self will keep the session valid since we renew the lastVerified date. // Similarly don't renew the token if (IsRemainingSecondsRequest(ctx)) { return; } // This relies on IssuedUtc, so call it before updating it. await EnsureValidSessionId(ctx); // We have to manually specify Issued and Expires, // because the SecurityStampValidator refreshes the principal every 30 minutes, // When the principal is refreshed the Issued is update to time of refresh, however, the Expires remains unchanged // When we then try and renew, the difference of issued and expires effectively becomes the new ExpireTimeSpan // meaning we effectively lose 30 minutes of our ExpireTimeSpan for EVERY principal refresh if we don't // https://github.com/dotnet/aspnetcore/blob/main/src/Security/Authentication/Cookies/src/CookieAuthenticationHandler.cs#L115 ctx.Properties.IssuedUtc = _systemClock.UtcNow; ctx.Properties.ExpiresUtc = _systemClock.UtcNow.Add(_globalSettings.TimeOut); ctx.ShouldRenew = true; }, OnSigningIn = ctx => { // occurs when sign in is successful but before the ticket is written to the outbound cookie ClaimsIdentity?backOfficeIdentity = ctx.Principal?.GetUmbracoIdentity(); if (backOfficeIdentity != null) { // generate a session id and assign it // create a session token - if we are configured and not in an upgrade state then use the db, otherwise just generate one Guid session = _runtimeState.Level == RuntimeLevel.Run ? _userService.CreateLoginSession( backOfficeIdentity.GetId() !.Value, _ipResolver.GetCurrentRequestIpAddress()) : Guid.NewGuid(); // add our session claim backOfficeIdentity.AddClaim(new Claim( Constants.Security.SessionIdClaimType, session.ToString(), ClaimValueTypes.String, Constants.Security.BackOfficeAuthenticationType, Constants.Security.BackOfficeAuthenticationType, backOfficeIdentity)); // since it is a cookie-based authentication add that claim backOfficeIdentity.AddClaim(new Claim( ClaimTypes.CookiePath, "/", ClaimValueTypes.String, Constants.Security.BackOfficeAuthenticationType, Constants.Security.BackOfficeAuthenticationType, backOfficeIdentity)); } return(Task.CompletedTask); }, OnSignedIn = ctx => { // occurs when sign in is successful and after the ticket is written to the outbound cookie // When we are signed in with the cookie, assign the principal to the current HttpContext ctx.HttpContext.SetPrincipalForRequest(ctx.Principal); return(Task.CompletedTask); }, OnSigningOut = ctx => { // Clear the user's session on sign out if (ctx.HttpContext?.User?.Identity != null) { var claimsIdentity = ctx.HttpContext.User.Identity as ClaimsIdentity; var sessionId = claimsIdentity?.FindFirstValue(Constants.Security.SessionIdClaimType); if (sessionId.IsNullOrWhiteSpace() == false && Guid.TryParse(sessionId, out Guid guidSession)) { _userService.ClearLoginSession(guidSession); } } // Remove all of our cookies var cookies = new[] { BackOfficeSessionIdValidator.CookieName, _securitySettings.AuthCookieName, Constants.Web.PreviewCookieName, Constants.Security.BackOfficeExternalCookieName, Constants.Web.AngularCookieName, Constants.Web.CsrfValidationCookieName }; foreach (var cookie in cookies) { ctx.Options.CookieManager.DeleteCookie(ctx.HttpContext !, cookie, new CookieOptions { Path = "/" }); } return(Task.CompletedTask); } }; }