/// <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 _authorizationCodeStore.GetAuthorizationCode(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, AuthCode = authorizationCode }); }