public async Task<IEndpointResult> CreateLoginResultAsync(ValidatedAuthorizeRequest request) { var signin = new SignInRequest(); // let the login page know the client requesting authorization signin.ClientId = request.ClientId; // pass through display mode to signin service if (request.DisplayMode.IsPresent()) { signin.DisplayMode = request.DisplayMode; } // pass through ui locales to signin service if (request.UiLocales.IsPresent()) { signin.UiLocales = request.UiLocales; } // pass through login_hint if (request.LoginHint.IsPresent()) { signin.LoginHint = request.LoginHint; } // look for well-known acr value -- idp var idp = request.GetIdP(); if (idp.IsPresent()) { signin.IdP = idp; } // look for well-known acr value -- tenant var tenant = request.GetTenant(); if (tenant.IsPresent()) { signin.Tenant = tenant; } // process acr values var acrValues = request.GetAcrValues(); if (acrValues.Any()) { signin.AcrValues = acrValues; } var message = new Message<SignInRequest>(signin) { ResponseUrl = _context.GetIdentityServerBaseUrl().EnsureTrailingSlash() + Constants.RoutePaths.Oidc.AuthorizeAfterLogin, AuthorizeRequestParameters = request.Raw.ToDictionary() }; await _signInRequestStore.WriteAsync(message); return new LoginPageResult(message.Id); }
// postpone //private Func<string> LogEvent(string message) //{ // return () => // { // var validationLog = new TokenRequestValidationLog(_validatedRequest); // var json = LogSerializer.Serialize(validationLog); // return string.Format("{0}\n {1}", message, json); // }; //} private async Task RaiseSuccessfulResourceOwnerAuthenticationEventAsync(string userName, string subjectId, SignInRequest signInRequest) { await _events.RaiseSuccessfulResourceOwnerFlowAuthenticationEventAsync(userName, subjectId, signInRequest); }
private async Task RaiseFailedResourceOwnerAuthenticationEventAsync(string userName, SignInRequest signInRequest, string error) { await _events.RaiseFailedResourceOwnerFlowAuthenticationEventAsync(userName, signInRequest, error); }
private async Task<TokenRequestValidationResult> ValidateResourceOwnerCredentialRequestAsync(NameValueCollection parameters) { _logger.LogInformation("Start password token request validation"); // if we've disabled local authentication, then fail if (_options.AuthenticationOptions.EnableLocalLogin == false || _validatedRequest.Client.EnableLocalLogin == false) { LogError("EnableLocalLogin is disabled, failing with UnsupportedGrantType"); return Invalid(Constants.TokenErrors.UnsupportedGrantType); } ///////////////////////////////////////////// // check if client is authorized for grant type ///////////////////////////////////////////// if (_validatedRequest.Client.Flow != Flows.ResourceOwner) { LogError("Client not authorized for resource owner flow"); return Invalid(Constants.TokenErrors.UnauthorizedClient); } ///////////////////////////////////////////// // check if client is allowed to request scopes ///////////////////////////////////////////// if (!(await ValidateRequestedScopesAsync(parameters))) { LogError("Invalid scopes."); return Invalid(Constants.TokenErrors.InvalidScope); } ///////////////////////////////////////////// // check resource owner credentials ///////////////////////////////////////////// var userName = parameters.Get(Constants.TokenRequest.UserName); var password = parameters.Get(Constants.TokenRequest.Password); if (userName.IsMissing() || password.IsMissing()) { LogError("Username or password missing."); return Invalid(Constants.TokenErrors.InvalidGrant); } if (userName.Length > _options.InputLengthRestrictions.UserName || password.Length > _options.InputLengthRestrictions.Password) { LogError("Username or password too long."); return Invalid(Constants.TokenErrors.InvalidGrant); } _validatedRequest.UserName = userName; ///////////////////////////////////////////// // check optional parameters and populate SignInMessage ///////////////////////////////////////////// var signInMessage = new SignInRequest(); // pass through client_id signInMessage.ClientId = _validatedRequest.Client.ClientId; // process acr values var acr = parameters.Get(Constants.AuthorizeRequest.AcrValues); if (acr.IsPresent()) { if (acr.Length > _options.InputLengthRestrictions.AcrValues) { LogError("Acr values too long."); return Invalid(Constants.TokenErrors.InvalidRequest); } var acrValues = acr.FromSpaceSeparatedString().Distinct().ToList(); // look for well-known acr value -- idp var idp = acrValues.FirstOrDefault(x => x.StartsWith(Constants.KnownAcrValues.HomeRealm)); if (idp.IsPresent()) { signInMessage.IdP = idp.Substring(Constants.KnownAcrValues.HomeRealm.Length); acrValues.Remove(idp); } // look for well-known acr value -- tenant var tenant = acrValues.FirstOrDefault(x => x.StartsWith(Constants.KnownAcrValues.Tenant)); if (tenant.IsPresent()) { signInMessage.Tenant = tenant.Substring(Constants.KnownAcrValues.Tenant.Length); acrValues.Remove(tenant); } // pass through any remaining acr values if (acrValues.Any()) { signInMessage.AcrValues = acrValues; } } _validatedRequest.SignInMessage = signInMessage; ///////////////////////////////////////////// // authenticate user ///////////////////////////////////////////// var authenticationContext = new LocalAuthenticationContext { UserName = userName, Password = password, SignInRequest = signInMessage }; await _users.AuthenticateLocalAsync(authenticationContext); var authnResult = authenticationContext.AuthenticateResult; if (authnResult == null || authnResult.IsError || authnResult.IsPartialSignIn) { var error = "invalid_username_or_password"; if (authnResult != null && authnResult.IsError) { error = authnResult.ErrorMessage; } if (authnResult != null && authnResult.IsPartialSignIn) { error = "Partial signin returned from AuthenticateLocalAsync"; } LogError("User authentication failed: " + error); await RaiseFailedResourceOwnerAuthenticationEventAsync(userName, signInMessage, error); if (authnResult != null) { return Invalid(Constants.TokenErrors.InvalidGrant, authnResult.ErrorMessage); } return Invalid(Constants.TokenErrors.InvalidGrant); } _validatedRequest.UserName = userName; _validatedRequest.Subject = authnResult.User; await RaiseSuccessfulResourceOwnerAuthenticationEventAsync(userName, authnResult.User.GetSubjectId(), signInMessage); _logger.LogInformation("Password token request validation success."); return Valid(); }