public async Task <GrantedToken> Execute(RefreshTokenGrantTypeParameter refreshTokenGrantTypeParameter, AuthenticationHeaderValue authenticationHeaderValue, X509Certificate2 certificate, string issuerName) { if (refreshTokenGrantTypeParameter == null) { throw new ArgumentNullException(nameof(refreshTokenGrantTypeParameter)); } // 1. Try to authenticate the client var instruction = CreateAuthenticateInstruction(refreshTokenGrantTypeParameter, authenticationHeaderValue, certificate); var authResult = await _authenticateClient.AuthenticateAsync(instruction, issuerName); var client = authResult.Client; if (authResult.Client == null) { _oauthEventSource.Info(authResult.ErrorMessage); throw new IdentityServerException(ErrorCodes.InvalidClient, authResult.ErrorMessage); } // 2. Check client if (client.GrantTypes == null || !client.GrantTypes.Contains(GrantType.refresh_token)) { throw new IdentityServerException(ErrorCodes.InvalidClient, string.Format(ErrorDescriptions.TheClientDoesntSupportTheGrantType, client.ClientId, GrantType.refresh_token)); } // 3. Validate parameters var grantedToken = await ValidateParameter(refreshTokenGrantTypeParameter); if (grantedToken.ClientId != client.ClientId) { throw new IdentityServerException(ErrorCodes.InvalidGrant, ErrorDescriptions.TheRefreshTokenCanBeUsedOnlyByTheSameIssuer); } // 4. Generate a new access token & insert it var generatedToken = await _grantedTokenGeneratorHelper.GenerateTokenAsync( grantedToken.ClientId, grantedToken.Scope, issuerName, grantedToken.UserInfoPayLoad, grantedToken.IdTokenPayLoad); generatedToken.ParentTokenId = grantedToken.Id; // 5. Fill-in the idtoken if (generatedToken.IdTokenPayLoad != null) { await _jwtGenerator.UpdatePayloadDate(generatedToken.IdTokenPayLoad); generatedToken.IdToken = await _clientHelper.GenerateIdTokenAsync(generatedToken.ClientId, generatedToken.IdTokenPayLoad); } await _tokenStore.AddToken(generatedToken); _oauthEventSource.GrantAccessToClient(generatedToken.ClientId, generatedToken.AccessToken, generatedToken.Scope); return(generatedToken); }
/// <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, X509Certificate2 certificate, string issuerName) { // 1. Authenticate the client var instruction = CreateAuthenticateInstruction(authorizationCodeGrantTypeParameter, authenticationHeaderValue, certificate); var authResult = await _authenticateClient.AuthenticateAsync(instruction, issuerName, true).ConfigureAwait(false); var client = authResult.Client; if (client == null) { _oauthEventSource.Info(authResult.ErrorMessage); throw new IdentityServerException(ErrorCodes.InvalidClient, authResult.ErrorMessage); } // 2. Check the client if (client.GrantTypes == null || !client.GrantTypes.Contains(GrantType.authorization_code)) { throw new IdentityServerException(ErrorCodes.InvalidClient, string.Format(ErrorDescriptions.TheClientDoesntSupportTheGrantType, client.ClientId, GrantType.authorization_code)); } if (client.ResponseTypes == null || !client.ResponseTypes.Contains(ResponseType.code)) { throw new IdentityServerException(ErrorCodes.InvalidClient, string.Format(ErrorDescriptions.TheClientDoesntSupportTheResponseType, client.ClientId, ResponseType.code)); } var authorizationCode = await _authorizationCodeStore.GetAuthorizationCode(authorizationCodeGrantTypeParameter.Code).ConfigureAwait(false); // 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().ConfigureAwait(false); 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 }); }
public async Task <GrantedToken> Execute(ResourceOwnerGrantTypeParameter resourceOwnerGrantTypeParameter, AuthenticationHeaderValue authenticationHeaderValue, X509Certificate2 certificate, string issuerName) { if (resourceOwnerGrantTypeParameter == null) { throw new ArgumentNullException(nameof(resourceOwnerGrantTypeParameter)); } // 1. Try to authenticate the client var instruction = CreateAuthenticateInstruction(resourceOwnerGrantTypeParameter, authenticationHeaderValue, certificate); var authResult = await _authenticateClient.AuthenticateAsync(instruction, issuerName); var client = authResult.Client; if (authResult.Client == null) { _oauthEventSource.Info(authResult.ErrorMessage); throw new IdentityServerException(ErrorCodes.InvalidClient, authResult.ErrorMessage); } // 2. Check the client. if (client.GrantTypes == null || !client.GrantTypes.Contains(GrantType.password)) { throw new IdentityServerException(ErrorCodes.InvalidClient, string.Format(ErrorDescriptions.TheClientDoesntSupportTheGrantType, client.ClientId, GrantType.password)); } if (client.ResponseTypes == null || !client.ResponseTypes.Contains(ResponseType.token) || !client.ResponseTypes.Contains(ResponseType.id_token)) { throw new IdentityServerException(ErrorCodes.InvalidClient, string.Format(ErrorDescriptions.TheClientDoesntSupportTheResponseType, client.ClientId, "token id_token")); } // 3. Try to authenticate a resource owner var resourceOwner = await _resourceOwnerAuthenticateHelper.Authenticate(resourceOwnerGrantTypeParameter.UserName, resourceOwnerGrantTypeParameter.Password, resourceOwnerGrantTypeParameter.AmrValues); if (resourceOwner == null) { throw new IdentityServerException(ErrorCodes.InvalidGrant, ErrorDescriptions.ResourceOwnerCredentialsAreNotValid); } // 4. Check if the requested scopes are valid var allowedTokenScopes = string.Empty; if (!string.IsNullOrWhiteSpace(resourceOwnerGrantTypeParameter.Scope)) { var scopeValidation = _scopeValidator.Check(resourceOwnerGrantTypeParameter.Scope, client); if (!scopeValidation.IsValid) { throw new IdentityServerException(ErrorCodes.InvalidScope, scopeValidation.ErrorMessage); } allowedTokenScopes = string.Join(" ", scopeValidation.Scopes); } // 5. Generate the user information payload and store it. var claims = resourceOwner.Claims; var claimsIdentity = new ClaimsIdentity(claims, "simpleIdentityServer"); var claimsPrincipal = new ClaimsPrincipal(claimsIdentity); var authorizationParameter = new AuthorizationParameter { Scope = resourceOwnerGrantTypeParameter.Scope }; var payload = await _jwtGenerator.GenerateIdTokenPayloadForScopesAsync(claimsPrincipal, authorizationParameter, issuerName); var generatedToken = await _grantedTokenHelper.GetValidGrantedTokenAsync(allowedTokenScopes, client.ClientId, payload, payload); if (generatedToken == null) { generatedToken = await _grantedTokenGeneratorHelper.GenerateTokenAsync(client, allowedTokenScopes, issuerName, payload, payload); if (generatedToken.IdTokenPayLoad != null) { await _jwtGenerator.UpdatePayloadDate(generatedToken.IdTokenPayLoad); generatedToken.IdToken = await _clientHelper.GenerateIdTokenAsync(client, generatedToken.IdTokenPayLoad); } await _tokenStore.AddToken(generatedToken); _oauthEventSource.GrantAccessToClient(client.ClientId, generatedToken.AccessToken, allowedTokenScopes); } return(generatedToken); }