private async Task <AuthorizeRequestValidationResult> ValidateOptionalParametersAsync(ValidatedAuthorizeRequest request) { ////////////////////////////////////////////////////////// // check nonce ////////////////////////////////////////////////////////// var nonce = request.Raw.Get(OidcConstants.AuthorizeRequest.Nonce); if (nonce.IsPresent()) { if (nonce.Length > _options.InputLengthRestrictions.Nonce) { LogError("Nonce too long", request); return(Invalid(request, description: "Invalid nonce")); } request.Nonce = nonce; } else { if (request.ResponseType.FromSpaceSeparatedString().Contains(TokenTypes.IdentityToken)) { LogError("Nonce required for flow with id_token response type", request); return(Invalid(request, description: "Invalid nonce")); } } ////////////////////////////////////////////////////////// // check prompt ////////////////////////////////////////////////////////// var prompt = request.Raw.Get(OidcConstants.AuthorizeRequest.Prompt); if (prompt.IsPresent()) { var prompts = prompt.Split(' ', StringSplitOptions.RemoveEmptyEntries); if (prompts.All(p => Constants.SupportedPromptModes.Contains(p))) { if (prompts.Contains(OidcConstants.PromptModes.None) && prompts.Length > 1) { LogError("prompt contains 'none' and other values. 'none' should be used by itself.", request); return(Invalid(request, description: "Invalid prompt")); } request.OriginalPromptModes = prompts; } else { _logger.LogDebug("Unsupported prompt mode - ignored: " + prompt); } } var suppressed_prompt = request.Raw.Get(Constants.SuppressedPrompt); if (suppressed_prompt.IsPresent()) { var prompts = suppressed_prompt.Split(' ', StringSplitOptions.RemoveEmptyEntries); if (prompts.All(p => Constants.SupportedPromptModes.Contains(p))) { if (prompts.Contains(OidcConstants.PromptModes.None) && prompts.Length > 1) { LogError("suppressed_prompt contains 'none' and other values. 'none' should be used by itself.", request); return(Invalid(request, description: "Invalid prompt")); } request.SuppressedPromptModes = prompts; } else { _logger.LogDebug("Unsupported suppressed_prompt mode - ignored: " + prompt); } } request.PromptModes = request.OriginalPromptModes.Except(request.SuppressedPromptModes).ToArray(); ////////////////////////////////////////////////////////// // check ui locales ////////////////////////////////////////////////////////// var uilocales = request.Raw.Get(OidcConstants.AuthorizeRequest.UiLocales); if (uilocales.IsPresent()) { if (uilocales.Length > _options.InputLengthRestrictions.UiLocale) { LogError("UI locale too long", request); return(Invalid(request, description: "Invalid ui_locales")); } request.UiLocales = uilocales; } ////////////////////////////////////////////////////////// // check display ////////////////////////////////////////////////////////// var display = request.Raw.Get(OidcConstants.AuthorizeRequest.Display); if (display.IsPresent()) { if (Constants.SupportedDisplayModes.Contains(display)) { request.DisplayMode = display; } _logger.LogDebug("Unsupported display mode - ignored: " + display); } ////////////////////////////////////////////////////////// // check max_age ////////////////////////////////////////////////////////// var maxAge = request.Raw.Get(OidcConstants.AuthorizeRequest.MaxAge); if (maxAge.IsPresent()) { if (int.TryParse(maxAge, out var seconds)) { if (seconds >= 0) { request.MaxAge = seconds; } else { LogError("Invalid max_age.", request); return(Invalid(request, description: "Invalid max_age")); } } else { LogError("Invalid max_age.", request); return(Invalid(request, description: "Invalid max_age")); } } ////////////////////////////////////////////////////////// // check login_hint ////////////////////////////////////////////////////////// var loginHint = request.Raw.Get(OidcConstants.AuthorizeRequest.LoginHint); if (loginHint.IsPresent()) { if (loginHint.Length > _options.InputLengthRestrictions.LoginHint) { LogError("Login hint too long", request); return(Invalid(request, description: "Invalid login_hint")); } request.LoginHint = loginHint; } ////////////////////////////////////////////////////////// // check acr_values ////////////////////////////////////////////////////////// var acrValues = request.Raw.Get(OidcConstants.AuthorizeRequest.AcrValues); if (acrValues.IsPresent()) { if (acrValues.Length > _options.InputLengthRestrictions.AcrValues) { LogError("Acr values too long", request); return(Invalid(request, description: "Invalid acr_values")); } request.AuthenticationContextReferenceClasses = acrValues.FromSpaceSeparatedString().Distinct().ToList(); } ////////////////////////////////////////////////////////// // check custom acr_values: idp ////////////////////////////////////////////////////////// var idp = request.GetIdP(); if (idp.IsPresent()) { // if idp is present but client does not allow it, strip it from the request message if (request.Client.IdentityProviderRestrictions != null && request.Client.IdentityProviderRestrictions.Any()) { if (!request.Client.IdentityProviderRestrictions.Contains(idp)) { _logger.LogWarning("idp requested ({idp}) is not in client restriction list.", idp); request.RemoveIdP(); } } } ////////////////////////////////////////////////////////// // check session cookie ////////////////////////////////////////////////////////// if (_options.Endpoints.EnableCheckSessionEndpoint) { if (request.Subject.IsAuthenticated()) { var sessionId = await _userSession.GetSessionIdAsync(); if (sessionId.IsPresent()) { request.SessionId = sessionId; } else { LogError("Check session endpoint enabled, but SessionId is missing", request); } } else { request.SessionId = ""; // empty string for anonymous users } } return(Valid(request)); }