public void When_Client_Doesnt_Contain_RedirectionUri_Then_EmptyArray_Is_Returned() { // ARRANGE InitializeMockingObjects(); // ACTS & ASSERTS Assert.Empty(_clientValidator.GetRedirectionUrls(null, null)); Assert.Empty(_clientValidator.GetRedirectionUrls(new Core.Common.Models.Client(), null)); Assert.Empty(_clientValidator.GetRedirectionUrls(new Core.Common.Models.Client(), "url")); Assert.Empty(_clientValidator.GetRedirectionUrls(new Core.Common.Models.Client { RedirectionUrls = new List <string>() }, "url")); }
public async Task <ActionResult> ProcessAsync(AuthorizationParameter authorizationParameter, ClaimsPrincipal claimsPrincipal, Core.Common.Models.Client client, string issuerName) { if (authorizationParameter == null) { throw new ArgumentNullException(nameof(authorizationParameter)); } if (client == null) { throw new ArgumentNullException(nameof(client)); } var endUserIsAuthenticated = IsAuthenticated(claimsPrincipal); Consent confirmedConsent = null; if (endUserIsAuthenticated) { confirmedConsent = await GetResourceOwnerConsent(claimsPrincipal, authorizationParameter); } var serializedAuthorizationParameter = authorizationParameter.SerializeWithJavascript(); _oauthEventSource.StartProcessingAuthorizationRequest(serializedAuthorizationParameter); ActionResult result = null; var prompts = _parameterParserHelper.ParsePrompts(authorizationParameter.Prompt); if (prompts == null || !prompts.Any()) { prompts = new List <PromptParameter>(); if (!endUserIsAuthenticated) { prompts.Add(PromptParameter.login); } else { if (confirmedConsent == null) { prompts.Add(PromptParameter.consent); } else { prompts.Add(PromptParameter.none); } } } var redirectionUrls = _clientValidator.GetRedirectionUrls(client, authorizationParameter.RedirectUrl); if (!redirectionUrls.Any()) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidRequestCode, string.Format(ErrorDescriptions.RedirectUrlIsNotValid, authorizationParameter.RedirectUrl), authorizationParameter.State); } var scopeValidationResult = _scopeValidator.Check(authorizationParameter.Scope, client); if (!scopeValidationResult.IsValid) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidScope, scopeValidationResult.ErrorMessage, authorizationParameter.State); } if (!scopeValidationResult.Scopes.Contains(Constants.StandardScopes.OpenId.Name)) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidScope, string.Format(ErrorDescriptions.TheScopesNeedToBeSpecified, Constants.StandardScopes.OpenId.Name), authorizationParameter.State); } var responseTypes = _parameterParserHelper.ParseResponseTypes(authorizationParameter.ResponseType); if (!responseTypes.Any()) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidRequestCode, string.Format(ErrorDescriptions.MissingParameter, Constants.StandardAuthorizationRequestParameterNames.ResponseTypeName), authorizationParameter.State); } if (!_clientValidator.CheckResponseTypes(client, responseTypes.ToArray())) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidRequestCode, string.Format(ErrorDescriptions.TheClientDoesntSupportTheResponseType, authorizationParameter.ClientId, string.Join(",", responseTypes)), authorizationParameter.State); } // Check if the user connection is still valid. if (endUserIsAuthenticated && !authorizationParameter.MaxAge.Equals(default(double))) { var authenticationDateTimeClaim = claimsPrincipal.Claims.FirstOrDefault(c => c.Type == ClaimTypes.AuthenticationInstant); if (authenticationDateTimeClaim != null) { var maxAge = authorizationParameter.MaxAge; var currentDateTimeUtc = DateTimeOffset.UtcNow.ConvertToUnixTimestamp(); var authenticationDateTime = long.Parse(authenticationDateTimeClaim.Value); if (maxAge < currentDateTimeUtc - authenticationDateTime) { result = _actionResultFactory.CreateAnEmptyActionResultWithRedirection(); result.RedirectInstruction.Action = IdentityServerEndPoints.AuthenticateIndex; } } } if (result == null) { result = ProcessPromptParameters( prompts, claimsPrincipal, authorizationParameter, confirmedConsent); await ProcessIdTokenHint(result, authorizationParameter, prompts, claimsPrincipal, issuerName); } var actionTypeName = Enum.GetName(typeof(TypeActionResult), result.Type); var actionName = result.RedirectInstruction == null ? string.Empty : Enum.GetName(typeof(IdentityServerEndPoints), result.RedirectInstruction.Action); _oauthEventSource.EndProcessingAuthorizationRequest( serializedAuthorizationParameter, actionTypeName, actionName); return(result); }
/// <summary> /// Check the parameters based on the RFC : http://openid.net/specs/openid-connect-core-1_0.html#TokenRequestValidation /// </summary> /// <param name="authorizationCodeGrantTypeParameter"></param> /// <param name="authenticationHeaderValue"></param> /// <returns></returns> private async Task <ValidationResult> ValidateParameter( AuthorizationCodeGrantTypeParameter authorizationCodeGrantTypeParameter, AuthenticationHeaderValue authenticationHeaderValue) { // 1. Authenticate the client var instruction = CreateAuthenticateInstruction(authorizationCodeGrantTypeParameter, authenticationHeaderValue); var authResult = await _authenticateClient.AuthenticateAsync(instruction); var client = authResult.Client; if (client == null) { throw new IdentityServerException(ErrorCodes.InvalidClient, authResult.ErrorMessage); } var authorizationCode = await _authorizationCodeRepository.GetAsync(authorizationCodeGrantTypeParameter.Code); // 2. Check if the authorization code is valid if (authorizationCode == null) { throw new IdentityServerException(ErrorCodes.InvalidGrant, ErrorDescriptions.TheAuthorizationCodeIsNotCorrect); } // 3. Check PKCE if (!_clientValidator.CheckPkce(client, authorizationCodeGrantTypeParameter.CodeVerifier, authorizationCode)) { throw new IdentityServerException(ErrorCodes.InvalidGrant, ErrorDescriptions.TheCodeVerifierIsNotCorrect); } // 4. Ensure the authorization code was issued to the authenticated client. var authorizationClientId = authorizationCode.ClientId; if (authorizationClientId != client.ClientId) { throw new IdentityServerException(ErrorCodes.InvalidGrant, string.Format(ErrorDescriptions.TheAuthorizationCodeHasNotBeenIssuedForTheGivenClientId, client.ClientId)); } if (authorizationCode.RedirectUri != authorizationCodeGrantTypeParameter.RedirectUri) { throw new IdentityServerException(ErrorCodes.InvalidGrant, ErrorDescriptions.TheRedirectionUrlIsNotTheSame); } // 5. Ensure the authorization code is still valid. var authCodeValidity = await _configurationService.GetAuthorizationCodeValidityPeriodInSecondsAsync(); var expirationDateTime = authorizationCode.CreateDateTime.AddSeconds(authCodeValidity); var currentDateTime = DateTime.UtcNow; if (currentDateTime > expirationDateTime) { throw new IdentityServerException(ErrorCodes.InvalidGrant, ErrorDescriptions.TheAuthorizationCodeIsObsolete); } // Ensure that the redirect_uri parameter value is identical to the redirect_uri parameter value. var redirectionUrl = _clientValidator.GetRedirectionUrls(client, authorizationCodeGrantTypeParameter.RedirectUri); if (!redirectionUrl.Any()) { throw new IdentityServerException( ErrorCodes.InvalidGrant, string.Format(ErrorDescriptions.RedirectUrlIsNotValid, authorizationCodeGrantTypeParameter.RedirectUri)); } return(new ValidationResult { Client = client, Code = authorizationCode }); }
public async Task <Client> ValidateAsync(AuthorizationParameter parameter) { // Check the required parameters. Read this RFC : http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest if (string.IsNullOrWhiteSpace(parameter.Scope)) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidRequestCode, string.Format(ErrorDescriptions.MissingParameter, Constants.StandardAuthorizationRequestParameterNames.ScopeName), parameter.State); } if (string.IsNullOrWhiteSpace(parameter.ClientId)) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidRequestCode, string.Format(ErrorDescriptions.MissingParameter, Constants.StandardAuthorizationRequestParameterNames.ClientIdName), parameter.State); } if (string.IsNullOrWhiteSpace(parameter.RedirectUrl)) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidRequestCode, string.Format(ErrorDescriptions.MissingParameter, Constants.StandardAuthorizationRequestParameterNames.RedirectUriName), parameter.State); } if (string.IsNullOrWhiteSpace(parameter.ResponseType)) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidRequestCode, string.Format(ErrorDescriptions.MissingParameter, Constants.StandardAuthorizationRequestParameterNames.ResponseTypeName), parameter.State); } ValidateResponseTypeParameter(parameter.ResponseType, parameter.State); ValidatePromptParameter(parameter.Prompt, parameter.State); // With this instruction // The redirect_uri is considered well-formed according to the RFC-3986 var redirectUrlIsCorrect = Uri.IsWellFormedUriString(parameter.RedirectUrl, UriKind.Absolute); if (!redirectUrlIsCorrect) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidRequestCode, ErrorDescriptions.TheRedirectionUriIsNotWellFormed, parameter.State); } var client = await _clientRepository.GetClientByIdAsync(parameter.ClientId); if (client == null) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidRequestCode, string.Format(ErrorDescriptions.ClientIsNotValid, parameter.ClientId), parameter.State); } if (!_clientValidator.GetRedirectionUrls(client, parameter.RedirectUrl).Any()) { throw new IdentityServerExceptionWithState( ErrorCodes.InvalidRequestCode, string.Format(ErrorDescriptions.RedirectUrlIsNotValid, parameter.RedirectUrl), parameter.State); } return(client); }