/// <summary> /// Custom validation logic for the authorize request. /// </summary> /// <param name="request">The validated request.</param> /// <returns> /// The validation result /// </returns> public Task<ValidationResult> ValidateAuthorizeRequestAsync(ValidatedAuthorizeRequest request) { return Task.FromResult(new ValidationResult { IsError = false }); }
private async Task<AuthorizeResponse> CreateHybridFlowResponseAsync(ValidatedAuthorizeRequest request) { var code = await CreateCodeAsync(request); var response = await CreateImplicitFlowResponseAsync(request, code); response.Code = code; return response; }
public async Task<AuthorizeRequestValidationResult> ValidateAsync(NameValueCollection parameters, ClaimsPrincipal subject = null) { Logger.Info("Start authorize request protocol validation"); var request = new ValidatedAuthorizeRequest { Options = _options, Subject = subject ?? Principal.Anonymous }; if (parameters == null) { Logger.Error("Parameters are null."); throw new ArgumentNullException("parameters"); } request.Raw = parameters; // validate client_id and redirect_uri var clientResult = await ValidateClientAsync(request); if (clientResult.IsError) { return clientResult; } // state, response_type, response_mode var mandatoryResult = ValidateCoreParameters(request); if (mandatoryResult.IsError) { return mandatoryResult; } // scope, scope restrictions and plausability var scopeResult = await ValidateScopeAsync(request); if (scopeResult.IsError) { return scopeResult; } // nonce, prompt, acr_values, login_hint etc. var optionalResult = ValidateOptionalParameters(request); if (optionalResult.IsError) { return optionalResult; } // custom validator var customResult = await _customValidator.ValidateAuthorizeRequestAsync(request); if (customResult.IsError) { LogError("Error in custom validation: " + customResult.Error, request); return Invalid(request, customResult.ErrorType, customResult.Error); } LogSuccess(request); return Valid(request); }
public async Task<AuthorizeResponse> CreateCodeFlowResponseAsync(ValidatedAuthorizeRequest request) { var code = await CreateCodeAsync(request); return new AuthorizeResponse { Request = request, RedirectUri = request.RedirectUri, Code = code, State = request.State }; }
public async Task Anonymous_User_must_SignIn() { var generator = new AuthorizeInteractionResponseGenerator(null, null, new DefaultLocalizationService()); var request = new ValidatedAuthorizeRequest { ClientId = "foo" }; var result = await generator.ProcessLoginAsync(request, Principal.Anonymous); result.IsLogin.Should().BeTrue(); }
public AuthorizeRequestValidator(IdentityServerOptions options, IClientStore clients, ICustomRequestValidator customValidator, IRedirectUriValidator uriValidator, ScopeValidator scopeValidator, IOwinContext context) { _options = options; _clients = clients; _customValidator = customValidator; _uriValidator = uriValidator; _scopeValidator = scopeValidator; _validatedRequest = new ValidatedAuthorizeRequest { Options = _options, Environment = context.Environment }; }
public AuthorizeRequestValidator(IdentityServerOptions options, IClientStore clients, ICustomRequestValidator customValidator, IRedirectUriValidator uriValidator, ScopeValidator scopeValidator, SessionCookie sessionCookie) { _options = options; _clients = clients; _customValidator = customValidator; _uriValidator = uriValidator; _scopeValidator = scopeValidator; _sessionCookie = sessionCookie; _validatedRequest = new ValidatedAuthorizeRequest { Options = _options, }; }
public async Task Authenticated_User_must_not_SignIn() { var users = new Mock<IUserService>(); users.Setup(x => x.IsActiveAsync(It.IsAny<ClaimsPrincipal>())).Returns(Task.FromResult<bool>(true)); var generator = new AuthorizeInteractionResponseGenerator(null, users.Object, new DefaultLocalizationService()); var request = new ValidatedAuthorizeRequest { ClientId = "foo", }; var principal = IdentityServerPrincipal.Create("123", "dom"); var result = await generator.ProcessLoginAsync(request, principal); result.IsLogin.Should().BeFalse(); }
public AuthorizeRequestValidationLog(ValidatedAuthorizeRequest request) { Raw = request.Raw.ToDictionary(); if (request.Client != null) { ClientId = request.Client.ClientId; ClientName = request.Client.ClientName; AllowedRedirectUris = request.Client.RedirectUris; } if (request.Subject != null) { var subjectClaim = request.Subject.FindFirst(Constants.ClaimTypes.Subject); if (subjectClaim != null) { SubjectId = subjectClaim.Value; } else { SubjectId = "unknown"; } } if (request.AuthenticationContextReferenceClasses.Any()) { AuthenticationContextReferenceClasses = request.AuthenticationContextReferenceClasses; } RedirectUri = request.RedirectUri; ResponseType = request.ResponseType; ResponseMode = request.ResponseMode; Flow = request.Flow; RequestedScopes = request.RequestedScopes.ToSpaceSeparatedString(); State = request.State; UiLocales = request.UiLocales; Nonce = request.Nonce; DisplayMode = request.DisplayMode; PromptMode = request.PromptMode; LoginHint = request.LoginHint; MaxAge = request.MaxAge; SessionId = request.SessionId; }
public async Task<AuthorizeResponse> CreateResponseAsync(ValidatedAuthorizeRequest request) { if (request.Flow == Flows.AuthorizationCode) { return await CreateCodeFlowResponseAsync(request); } if (request.Flow == Flows.Implicit) { return await CreateImplicitFlowResponseAsync(request); } if (request.Flow == Flows.Hybrid) { return await CreateHybridFlowResponseAsync(request); } Logger.Error("Unsupported flow: " + request.Flow.ToString()); throw new InvalidOperationException("invalid flow: " + request.Flow.ToString()); }
public async Task<AuthorizeResponse> CreateCodeFlowResponseAsync(ValidatedAuthorizeRequest request) { var code = await CreateCodeAsync(request); var response = new AuthorizeResponse { Request = request, RedirectUri = request.RedirectUri, Code = code, State = request.State }; if (request.IsOpenIdRequest) { response.SessionState = GenerateSessionStateValue(request); } return response; }
private async Task<string> CreateCodeAsync(ValidatedAuthorizeRequest request) { var code = new AuthorizationCode { Client = request.Client, Subject = request.Subject, IsOpenId = request.IsOpenIdRequest, RequestedScopes = request.ValidatedScopes.GrantedScopes, RedirectUri = request.RedirectUri, Nonce = request.Nonce, WasConsentShown = request.WasConsentShown, }; // store id token and access token and return authorization code var id = CryptoRandom.CreateUniqueId(); await _authorizationCodes.StoreAsync(id, code); return id; }
public void ProcessConsentAsync_NoPromptMode_ConsentServiceRequiresConsent_NoPriorConsent_ReturnsConsentResult() { RequiresConsent(true); var request = new ValidatedAuthorizeRequest() { ResponseMode = Constants.ResponseModes.Fragment, State = "12345", RedirectUri = "https://client.com/callback", PromptMode = Constants.PromptModes.Consent }; var result = subject.ProcessConsentAsync(request).Result; request.WasConsentShown.Should().BeFalse(); result.IsConsent.Should().BeTrue(); AssertUpdateConsentNotCalled(); }
public void ProcessConsentAsync_RequiresConsentButPromptModeIsNone_ReturnsErrorResult() { RequiresConsent(true); var request = new ValidatedAuthorizeRequest() { ResponseMode = Constants.ResponseModes.Fragment, State = "12345", RedirectUri = "https://client.com/callback", PromptMode = Constants.PromptModes.None }; var result = subject.ProcessConsentAsync(request).Result; request.WasConsentShown.Should().BeFalse(); result.IsError.Should().BeTrue(); result.Error.ErrorType.Should().Be(ErrorTypes.Client); result.Error.Error.Should().Be(Constants.AuthorizeErrors.InteractionRequired); AssertErrorReturnsRequestValues(result.Error, request); AssertUpdateConsentNotCalled(); }
public void ProcessConsentAsync_PromptModeIsSelectAccount_Throws() { RequiresConsent(true); var request = new ValidatedAuthorizeRequest() { ResponseMode = Constants.ResponseModes.Fragment, State = "12345", RedirectUri = "https://client.com/callback", PromptMode = Constants.PromptModes.SelectAccount }; Func<Task> act = () => subject.ProcessConsentAsync(request); act.ShouldThrow<ArgumentException>() .And.Message.Should().Contain("PromptMode"); }
public void ProcessConsentAsync_AllowsNullConsent() { var request = new ValidatedAuthorizeRequest() { ResponseMode = Constants.ResponseModes.Fragment, State = "12345", RedirectUri = "https://client.com/callback", PromptMode = Constants.PromptModes.Consent }; var result = subject.ProcessConsentAsync(request, null).Result; }
private void LogSuccess(ValidatedAuthorizeRequest request) { var validationLog = new AuthorizeRequestValidationLog(request); var json = LogSerializer.Serialize(validationLog); Logger.InfoFormat("{0}\n {1}", "Authorize request validation success", json); }
private AuthorizeRequestValidationResult ValidateCoreParameters(ValidatedAuthorizeRequest request) { ////////////////////////////////////////////////////////// // check state ////////////////////////////////////////////////////////// var state = request.Raw.Get(Constants.AuthorizeRequest.State); if (state.IsPresent()) { request.State = state; } ////////////////////////////////////////////////////////// // response_type must be present and supported ////////////////////////////////////////////////////////// var responseType = request.Raw.Get(Constants.AuthorizeRequest.ResponseType); if (responseType.IsMissing()) { LogError("Missing response_type", request); return(Invalid(request, ErrorTypes.Client, Constants.AuthorizeErrors.UnsupportedResponseType)); } if (!Constants.SupportedResponseTypes.Contains(responseType)) { LogError("Response type not supported: " + responseType, request); return(Invalid(request, ErrorTypes.Client, Constants.AuthorizeErrors.UnsupportedResponseType)); } request.ResponseType = responseType; ////////////////////////////////////////////////////////// // match response_type to flow ////////////////////////////////////////////////////////// request.Flow = Constants.ResponseTypeToFlowMapping[request.ResponseType]; ////////////////////////////////////////////////////////// // check if flow is allowed at authorize endpoint ////////////////////////////////////////////////////////// if (!Constants.AllowedFlowsForAuthorizeEndpoint.Contains(request.Flow)) { LogError("Invalid flow", request); return(Invalid(request)); } ////////////////////////////////////////////////////////// // check response_mode parameter and set response_mode ////////////////////////////////////////////////////////// // set default response mode for flow first request.ResponseMode = Constants.AllowedResponseModesForFlow[request.Flow].First(); // check if response_mode parameter is present and valid var responseMode = request.Raw.Get(Constants.AuthorizeRequest.ResponseMode); if (responseMode.IsPresent()) { if (Constants.SupportedResponseModes.Contains(responseMode)) { if (Constants.AllowedResponseModesForFlow[request.Flow].Contains(responseMode)) { request.ResponseMode = responseMode; } else { LogError("Invalid response_mode for flow: " + responseMode, request); return(Invalid(request, ErrorTypes.User, Constants.AuthorizeErrors.UnsupportedResponseType)); } } else { LogError("Unsupported response_mode: " + responseMode, request); return(Invalid(request, ErrorTypes.User, Constants.AuthorizeErrors.UnsupportedResponseType)); } } ////////////////////////////////////////////////////////// // check if flow is allowed for client ////////////////////////////////////////////////////////// if (request.Flow != request.Client.Flow) { LogError("Invalid flow for client: " + request.Flow, request); return(Invalid(request, ErrorTypes.User, Constants.AuthorizeErrors.UnauthorizedClient)); } return(Valid(request)); }
public async Task <AuthorizeRequestValidationResult> ValidateAsync(NameValueCollection parameters, ClaimsPrincipal subject = null) { Logger.Info("Start authorize request protocol validation"); var request = new ValidatedAuthorizeRequest { Options = _options, Subject = subject ?? Principal.Anonymous }; if (parameters == null) { Logger.Error("Parameters are null."); throw new ArgumentNullException("parameters"); } request.Raw = parameters; // validate client_id and redirect_uri var clientResult = await ValidateClientAsync(request); if (clientResult.IsError) { return(clientResult); } // state, response_type, response_mode var mandatoryResult = ValidateCoreParameters(request); if (mandatoryResult.IsError) { return(mandatoryResult); } // scope, scope restrictions and plausability var scopeResult = await ValidateScopeAsync(request); if (scopeResult.IsError) { return(scopeResult); } // nonce, prompt, acr_values, login_hint etc. var optionalResult = ValidateOptionalParameters(request); if (optionalResult.IsError) { return(optionalResult); } // custom validator var customResult = await _customValidator.ValidateAuthorizeRequestAsync(request); if (customResult.IsError) { LogError("Error in custom validation: " + customResult.Error, request); return(Invalid(request, customResult.ErrorType, customResult.Error)); } LogSuccess(request); return(Valid(request)); }
private void AssertErrorReturnsRequestValues(AuthorizeError error, ValidatedAuthorizeRequest request) { error.ResponseMode.Should().Be(request.ResponseMode); error.ErrorUri.Should().Be(request.RedirectUri); error.State.Should().Be(request.State); }
public async Task ProcessConsentAsync_PromptModeConsent_ConsentGranted_ScopesSelected_ReturnsConsentResult() { RequiresConsent(true); var request = new ValidatedAuthorizeRequest() { ResponseMode = Constants.ResponseModes.Fragment, State = "12345", RedirectUri = "https://client.com/callback", ValidatedScopes = new ScopeValidator(new InMemoryScopeStore(GetScopes())), Client = new Client { AllowRememberConsent = false } }; await request.ValidatedScopes.AreScopesValidAsync(new string[] { "read", "write" }); var consent = new UserConsent { Button = "yes", RememberConsent = false, Scopes = new string[] { "read" } }; var result = subject.ProcessConsentAsync(request, consent).Result; request.ValidatedScopes.GrantedScopes.Count.Should().Be(1); "read".Should().Be(request.ValidatedScopes.GrantedScopes.First().Name); request.WasConsentShown.Should().BeTrue(); result.IsConsent.Should().BeFalse(); AssertUpdateConsentNotCalled(); }
public void ProcessConsentAsync_NoPromptMode_ConsentServiceRequiresConsent_ConsentNotGranted_ReturnsErrorResult() { RequiresConsent(true); var request = new ValidatedAuthorizeRequest() { ResponseMode = Constants.ResponseModes.Fragment, State = "12345", RedirectUri = "https://client.com/callback", }; var consent = new UserConsent { Button = "no", RememberConsent = false, Scopes = new string[] { "read", "write" } }; var result = subject.ProcessConsentAsync(request, consent).Result; request.WasConsentShown.Should().BeTrue(); result.IsError.Should().BeTrue(); result.Error.ErrorType.Should().Be(ErrorTypes.Client); result.Error.Error.Should().Be(Constants.AuthorizeErrors.AccessDenied); AssertErrorReturnsRequestValues(result.Error, request); AssertUpdateConsentNotCalled(); }
private async Task <AuthorizeRequestValidationResult> ValidateScopeAsync(ValidatedAuthorizeRequest request) { ////////////////////////////////////////////////////////// // scope must be present ////////////////////////////////////////////////////////// var scope = request.Raw.Get(Constants.AuthorizeRequest.Scope); if (scope.IsMissing()) { LogError("scope is missing", request); return(Invalid(request, ErrorTypes.Client)); } if (scope.Length > Constants.MaxScopeLength) { LogError("scopes too long.", request); return(Invalid(request, ErrorTypes.Client)); } request.RequestedScopes = scope.FromSpaceSeparatedString().Distinct().ToList(); if (request.RequestedScopes.Contains(Constants.StandardScopes.OpenId)) { request.IsOpenIdRequest = true; } ////////////////////////////////////////////////////////// // check scope vs response_type plausability ////////////////////////////////////////////////////////// var requirement = Constants.ResponseTypeToScopeRequirement[request.ResponseType]; if (requirement == Constants.ScopeRequirement.Identity || requirement == Constants.ScopeRequirement.IdentityOnly) { if (request.IsOpenIdRequest == false) { LogError("response_type requires the openid scope", request); return(Invalid(request, ErrorTypes.Client)); } } ////////////////////////////////////////////////////////// // check if scopes are valid/supported and check for resource scopes ////////////////////////////////////////////////////////// if (await _scopeValidator.AreScopesValidAsync(request.RequestedScopes) == false) { return(Invalid(request, ErrorTypes.Client, Constants.AuthorizeErrors.InvalidScope)); } if (_scopeValidator.ContainsOpenIdScopes && !request.IsOpenIdRequest) { LogError("Identity related scope requests, but no openid scope", request); return(Invalid(request, ErrorTypes.Client, Constants.AuthorizeErrors.InvalidScope)); } if (_scopeValidator.ContainsResourceScopes) { request.IsResourceRequest = true; } ////////////////////////////////////////////////////////// // check scopes and scope restrictions ////////////////////////////////////////////////////////// if (!_scopeValidator.AreScopesAllowed(request.Client, request.RequestedScopes)) { return(Invalid(request, ErrorTypes.User, Constants.AuthorizeErrors.UnauthorizedClient)); } request.ValidatedScopes = _scopeValidator; ////////////////////////////////////////////////////////// // check id vs resource scopes and response types plausability ////////////////////////////////////////////////////////// if (!_scopeValidator.IsResponseTypeValid(request.ResponseType)) { return(Invalid(request, ErrorTypes.Client, Constants.AuthorizeErrors.InvalidScope)); } return(Valid(request)); }
public void ProcessConsentAsync_NoPromptMode_ConsentServiceRequiresConsent_ConsentGranted_NoScopesSelected_ReturnsConsentResult() { RequiresConsent(true); var request = new ValidatedAuthorizeRequest() { ResponseMode = Constants.ResponseModes.Fragment, State = "12345", RedirectUri = "https://client.com/callback", ValidatedScopes = new ScopeValidator(null), Client = new Client { } }; var consent = new UserConsent { Button = "yes", RememberConsent = false, Scopes = new string[] { } }; var result = subject.ProcessConsentAsync(request, consent).Result; request.WasConsentShown.Should().BeTrue(); result.IsConsent.Should().BeTrue(); result.ConsentError.Should().Be(Messages.MustSelectAtLeastOnePermission); AssertUpdateConsentNotCalled(); }
private async Task<IHttpActionResult> CreateAuthorizeResponseAsync(ValidatedAuthorizeRequest request) { var response = await _responseGenerator.CreateResponseAsync(request); if (request.ResponseMode == Constants.ResponseModes.Query || request.ResponseMode == Constants.ResponseModes.Fragment) { RaiseSuccessEvent(); return new AuthorizeRedirectResult(response); } if (request.ResponseMode == Constants.ResponseModes.FormPost) { RaiseSuccessEvent(); return new AuthorizeFormPostResult(response, Request); } Logger.Error("Unsupported response mode. Aborting."); throw new InvalidOperationException("Unsupported response mode"); }
public async Task ProcessConsentAsync_AllowConsentSelected_SavesConsent() { RequiresConsent(true); var client = new Client { AllowRememberConsent = true }; var user = new ClaimsPrincipal(); var request = new ValidatedAuthorizeRequest() { ResponseMode = Constants.ResponseModes.Fragment, State = "12345", RedirectUri = "https://client.com/callback", ValidatedScopes = new ScopeValidator(new InMemoryScopeStore(GetScopes())), Client = client, Subject = user }; await request.ValidatedScopes.AreScopesValidAsync(new string[] { "read", "write" }); var consent = new UserConsent { Button = "yes", RememberConsent = true, Scopes = new string[] { "read" } }; var result = subject.ProcessConsentAsync(request, consent).Result; AssertUpdateConsentCalled(client, user, "read"); }
IHttpActionResult AuthorizeError(ErrorTypes errorType, string error, ValidatedAuthorizeRequest request) { RaiseFailureEvent(error); // show error message to user if (errorType == ErrorTypes.User) { var env = Request.GetOwinEnvironment(); var username = User.Identity.IsAuthenticated ? User.GetName() : (string)null; var errorModel = new ErrorViewModel { RequestId = env.GetRequestId(), SiteName = _options.SiteName, SiteUrl = env.GetIdentityServerBaseUrl(), CurrentUser = username, ErrorMessage = LookupErrorMessage(error) }; var errorResult = new ErrorActionResult(_viewService, errorModel); return errorResult; } // return error to client var response = new AuthorizeResponse { Request = request, IsError = true, Error = error, State = request.State, RedirectUri = request.RedirectUri }; if (request.ResponseMode == Constants.ResponseModes.FormPost) { return new AuthorizeFormPostResult(response, Request); } else { return new AuthorizeRedirectResult(response); } }
public async Task<ConsentInteractionResponse> ProcessConsentAsync(ValidatedAuthorizeRequest request, UserConsent consent = null) { if (request == null) throw new ArgumentNullException("request"); if (request.PromptMode != null && request.PromptMode != Constants.PromptModes.None && request.PromptMode != Constants.PromptModes.Consent) { throw new ArgumentException("Invalid PromptMode"); } var consentRequired = await _consent.RequiresConsentAsync(request.Client, request.Subject, request.RequestedScopes); if (consentRequired && request.PromptMode == Constants.PromptModes.None) { Logger.Info("Prompt=none requested, but consent is required."); return new ConsentInteractionResponse { Error = new AuthorizeError { ErrorType = ErrorTypes.Client, Error = Constants.AuthorizeErrors.InteractionRequired, ResponseMode = request.ResponseMode, ErrorUri = request.RedirectUri, State = request.State } }; } if (request.PromptMode == Constants.PromptModes.Consent || consentRequired) { var response = new ConsentInteractionResponse(); // did user provide consent if (consent == null) { // user was not yet shown conset screen response.IsConsent = true; } else { request.WasConsentShown = true; // user was shown consent -- did they say yes or no if (consent.WasConsentGranted == false) { // no need to show consent screen again // build access denied error to return to client response.Error = new AuthorizeError { ErrorType = ErrorTypes.Client, Error = Constants.AuthorizeErrors.AccessDenied, ResponseMode = request.ResponseMode, ErrorUri = request.RedirectUri, State = request.State }; } else { // they said yes, set scopes they chose request.ValidatedScopes.SetConsentedScopes(consent.ScopedConsented); if (!request.ValidatedScopes.GrantedScopes.Any()) { // they said yes, but didn't pick any scopes // show consent again and provide error message response.IsConsent = true; response.ConsentError = _localizationService.GetMessage(MessageIds.MustSelectAtLeastOnePermission); } else if (request.Client.AllowRememberConsent) { // remember consent var scopes = Enumerable.Empty<string>(); if (consent.RememberConsent) { // remember what user actually selected scopes = request.ValidatedScopes.GrantedScopes.Select(x => x.Name); } await _consent.UpdateConsentAsync(request.Client, request.Subject, scopes); } } } return response; } return new ConsentInteractionResponse(); }
private AuthorizeRequestValidationResult ValidateOptionalParameters(ValidatedAuthorizeRequest request) { ////////////////////////////////////////////////////////// // check nonce ////////////////////////////////////////////////////////// var nonce = request.Raw.Get(Constants.AuthorizeRequest.Nonce); if (nonce.IsPresent()) { if (nonce.Length > Constants.MaxNonceLength) { LogError("Nonce too long", request); return(Invalid(request, ErrorTypes.Client)); } request.Nonce = nonce; } else { if (request.Flow == Flows.Implicit) { // only openid requests require nonce if (request.IsOpenIdRequest) { LogError("Nonce required for implicit flow with openid scope", request); return(Invalid(request, ErrorTypes.Client)); } } } ////////////////////////////////////////////////////////// // check prompt ////////////////////////////////////////////////////////// var prompt = request.Raw.Get(Constants.AuthorizeRequest.Prompt); if (prompt.IsPresent()) { if (Constants.SupportedPromptModes.Contains(prompt)) { request.PromptMode = prompt; } else { Logger.Info("Unsupported prompt mode - ignored: " + prompt); } } ////////////////////////////////////////////////////////// // check ui locales ////////////////////////////////////////////////////////// var uilocales = request.Raw.Get(Constants.AuthorizeRequest.UiLocales); if (uilocales.IsPresent()) { if (uilocales.Length > Constants.MaxUiLocaleLength) { LogError("UI locale too long", request); return(Invalid(request, ErrorTypes.Client)); } request.UiLocales = uilocales; } ////////////////////////////////////////////////////////// // check display ////////////////////////////////////////////////////////// var display = request.Raw.Get(Constants.AuthorizeRequest.Display); if (display.IsPresent()) { if (Constants.SupportedDisplayModes.Contains(display)) { request.DisplayMode = display; } Logger.Info("Unsupported display mode - ignored: " + display); } ////////////////////////////////////////////////////////// // check max_age ////////////////////////////////////////////////////////// var maxAge = request.Raw.Get(Constants.AuthorizeRequest.MaxAge); if (maxAge.IsPresent()) { int seconds; if (int.TryParse(maxAge, out seconds)) { if (seconds >= 0) { request.MaxAge = seconds; } else { LogError("Invalid max_age.", request); return(Invalid(request, ErrorTypes.Client)); } } else { LogError("Invalid max_age.", request); return(Invalid(request, ErrorTypes.Client)); } } ////////////////////////////////////////////////////////// // check login_hint ////////////////////////////////////////////////////////// var loginHint = request.Raw.Get(Constants.AuthorizeRequest.LoginHint); if (loginHint.IsPresent()) { if (loginHint.Length > Constants.MaxLoginHintLength) { LogError("Login hint too long", request); return(Invalid(request, ErrorTypes.Client)); } request.LoginHint = loginHint; } ////////////////////////////////////////////////////////// // check acr_values ////////////////////////////////////////////////////////// var acrValues = request.Raw.Get(Constants.AuthorizeRequest.AcrValues); if (acrValues.IsPresent()) { if (acrValues.Length > Constants.MaxAcrValuesLength) { LogError("Acr values too long", request); return(Invalid(request, ErrorTypes.Client)); } request.AuthenticationContextReferenceClasses = acrValues.FromSpaceSeparatedString().Distinct().ToList(); } ////////////////////////////////////////////////////////// // check session cookie ////////////////////////////////////////////////////////// if (_options.Endpoints.EnableCheckSessionEndpoint) { var sessionId = _sessionCookie.GetSessionId(); if (sessionId.IsPresent()) { request.SessionId = sessionId; } else { LogError("Check session endpoint enabled, but SessionId is missing", request); } } return(Valid(request)); }
private IHttpActionResult CreateConsentResult( ValidatedAuthorizeRequest validatedRequest, UserConsent consent, NameValueCollection requestParameters, string errorMessage) { var env = Request.GetOwinEnvironment(); var consentModel = new ConsentViewModel { RequestId = env.GetRequestId(), SiteName = _options.SiteName, SiteUrl = env.GetIdentityServerBaseUrl(), ErrorMessage = errorMessage, CurrentUser = User.GetName(), ClientName = validatedRequest.Client.ClientName, ClientUrl = validatedRequest.Client.ClientUri, ClientLogoUrl = validatedRequest.Client.LogoUri ?? null, IdentityScopes = validatedRequest.GetIdentityScopes(this._localizationService), ResourceScopes = validatedRequest.GetResourceScopes(this._localizationService), AllowRememberConsent = validatedRequest.Client.AllowRememberConsent, RememberConsent = consent != null ? consent.RememberConsent : true, LoginWithDifferentAccountUrl = Url.Route(Constants.RouteNames.Oidc.SwitchUser, null).AddQueryString(requestParameters.ToQueryString()), LogoutUrl = Url.Route(Constants.RouteNames.Oidc.EndSession, null), ConsentUrl = Url.Route(Constants.RouteNames.Oidc.Consent, null).AddQueryString(requestParameters.ToQueryString()), AntiForgery = _antiForgeryToken.GetAntiForgeryToken() }; return new ConsentActionResult(_viewService, consentModel); }
private AuthorizeRequestValidationResult Valid(ValidatedAuthorizeRequest request) { var result = new AuthorizeRequestValidationResult { IsError = false, ValidatedRequest = request }; return result; }
public Task<LoginInteractionResponse> ProcessClientLoginAsync(ValidatedAuthorizeRequest request) { // check idp restrictions var currentIdp = request.Subject.GetIdentityProvider(); if (request.Client.IdentityProviderRestrictions != null && request.Client.IdentityProviderRestrictions.Any()) { if (!request.Client.IdentityProviderRestrictions.Contains(currentIdp)) { var response = new LoginInteractionResponse { SignInMessage = _signIn }; Logger.WarnFormat("User is logged in with idp: {0}, but idp not in client restriction list.", currentIdp); return Task.FromResult(response); } } // check if idp is local and local logins are not allowed if (currentIdp == Constants.BuiltInIdentityProvider) { if (_options.AuthenticationOptions.EnableLocalLogin == false || request.Client.EnableLocalLogin == false) { var response = new LoginInteractionResponse { SignInMessage = _signIn }; Logger.Warn("User is logged in with local idp, but local logins not enabled."); return Task.FromResult(response); } } return Task.FromResult(new LoginInteractionResponse()); }
private void LogError(string message, ValidatedAuthorizeRequest request) { var validationLog = new AuthorizeRequestValidationLog(request); var json = LogSerializer.Serialize(validationLog); Logger.ErrorFormat("{0}\n {1}", message, json); }
public async Task<LoginInteractionResponse> ProcessLoginAsync(ValidatedAuthorizeRequest request, ClaimsPrincipal user) { // 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; } // process acr values var acrValues = request.AuthenticationContextReferenceClasses.Distinct().ToList(); // look for well-known acr value -- idp var idp = acrValues.FirstOrDefault(x => x.StartsWith(Constants.KnownAcrValues.HomeRealm)); if (idp.IsPresent()) { _signIn.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()) { _signIn.Tenant = tenant.Substring(Constants.KnownAcrValues.Tenant.Length); acrValues.Remove(tenant); } // pass through any remaining acr values if (acrValues.Any()) { _signIn.AcrValues = acrValues; } if (request.PromptMode == Constants.PromptModes.Login) { // remove prompt so when we redirect back in from login page // we won't think we need to force a prompt again request.Raw.Remove(Constants.AuthorizeRequest.Prompt); Logger.Info("Redirecting to login page because of prompt=login"); return new LoginInteractionResponse { SignInMessage = _signIn }; } // unauthenticated user var isAuthenticated = user.Identity.IsAuthenticated; if (!isAuthenticated) Logger.Info("User is not authenticated. Redirecting to login."); // user de-activated bool isActive = false; if (isAuthenticated) { isActive = await _users.IsActiveAsync(user); if (!isActive) Logger.Info("User is not active. Redirecting to login."); } if (!isAuthenticated || !isActive) { // prompt=none means user must be signed in already if (request.PromptMode == Constants.PromptModes.None) { Logger.Info("prompt=none was requested. But user is not authenticated."); return new LoginInteractionResponse { Error = new AuthorizeError { ErrorType = ErrorTypes.Client, Error = Constants.AuthorizeErrors.LoginRequired, ResponseMode = request.ResponseMode, ErrorUri = request.RedirectUri, State = request.State } }; } return new LoginInteractionResponse { SignInMessage = _signIn }; } // check current idp var currentIdp = user.GetIdentityProvider(); // check if idp login hint matches current provider if (_signIn.IdP.IsPresent()) { if (_signIn.IdP != currentIdp) { Logger.Info("Current IdP is not the requested IdP. Redirecting to login"); Logger.InfoFormat("Current: {0} -- Requested: {1}", currentIdp, _signIn.IdP); return new LoginInteractionResponse { SignInMessage = _signIn }; } } // check authentication freshness if (request.MaxAge.HasValue) { var authTime = user.GetAuthenticationTime(); if (DateTimeOffsetHelper.UtcNow > authTime.AddSeconds(request.MaxAge.Value)) { Logger.Info("Requested MaxAge exceeded. Redirecting to login"); return new LoginInteractionResponse { SignInMessage = _signIn }; } } return new LoginInteractionResponse(); }
public async Task <AuthorizeRequestValidationResult> ValidateClientAsync(ValidatedAuthorizeRequest request) { ////////////////////////////////////////////////////////// // client_id must be present ///////////////////////////////////////////////////////// var clientId = request.Raw.Get(Constants.AuthorizeRequest.ClientId); if (clientId.IsMissingOrTooLong(Constants.MaxClientIdLength)) { LogError("client_id is missing or too long", request); return(Invalid(request)); } request.ClientId = clientId; ////////////////////////////////////////////////////////// // redirect_uri must be present, and a valid uri ////////////////////////////////////////////////////////// var redirectUri = request.Raw.Get(Constants.AuthorizeRequest.RedirectUri); if (redirectUri.IsMissingOrTooLong(Constants.MaxRedirectUriLength)) { LogError("redirect_uri is missing or too long", request); return(Invalid(request)); } Uri uri; if (!Uri.TryCreate(redirectUri, UriKind.Absolute, out uri)) { LogError("invalid redirect_uri: " + redirectUri, request); return(Invalid(request)); } request.RedirectUri = redirectUri; ////////////////////////////////////////////////////////// // check for valid client ////////////////////////////////////////////////////////// var client = await _clients.FindClientByIdAsync(request.ClientId); if (client == null || client.Enabled == false) { LogError("Unknown client or not enabled: " + request.ClientId, request); return(Invalid(request, ErrorTypes.User, Constants.AuthorizeErrors.UnauthorizedClient)); } request.Client = client; ////////////////////////////////////////////////////////// // check if redirect_uri is valid ////////////////////////////////////////////////////////// if (await _uriValidator.IsRedirectUriValidAsync(request.RedirectUri, request.Client) == false) { LogError("Invalid redirect_uri: " + request.RedirectUri, request); return(Invalid(request, ErrorTypes.User, Constants.AuthorizeErrors.UnauthorizedClient)); } return(Valid(request)); }