/// <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 async Task <ActionResult <UserDetail> > PostLogin(LoginModel loginModel) { // Sign the user in with username/password, this also gives a chance for developers to // custom verify the credentials and auto-link user accounts with a custom IBackOfficePasswordChecker SignInResult result = await _signInManager.PasswordSignInAsync( loginModel.Username, loginModel.Password, isPersistent : true, lockoutOnFailure : true); if (result.Succeeded) { // return the user detail return(GetUserDetail(_userService.GetByUsername(loginModel.Username))); } if (result.RequiresTwoFactor) { var twofactorView = _backOfficeTwoFactorOptions.GetTwoFactorView(loginModel.Username); if (twofactorView.IsNullOrWhiteSpace()) { return(new ValidationErrorResult($"The registered {typeof(IBackOfficeTwoFactorOptions)} of type {_backOfficeTwoFactorOptions.GetType()} did not return a view for two factor auth ")); } IUser attemptedUser = _userService.GetByUsername(loginModel.Username); // create a with information to display a custom two factor send code view var verifyResponse = new ObjectResult(new { twoFactorView = twofactorView, userId = attemptedUser.Id }) { StatusCode = StatusCodes.Status402PaymentRequired }; return(verifyResponse); } // TODO: We can check for these and respond differently if we think it's important // result.IsLockedOut // result.IsNotAllowed // return BadRequest (400), we don't want to return a 401 because that get's intercepted // by our angular helper because it thinks that we need to re-perform the request once we are // authorized and we don't want to return a 403 because angular will show a warning message indicating // that the user doesn't have access to perform this function, we just want to return a normal invalid message. return(BadRequest()); }