public async Task <bool> Execute(RevokeTokenParameter revokeTokenParameter, AuthenticationHeaderValue authenticationHeaderValue, X509Certificate2 certificate, string issuerName) { if (revokeTokenParameter == null) { throw new ArgumentNullException(nameof(revokeTokenParameter)); } if (string.IsNullOrWhiteSpace(revokeTokenParameter.Token)) { throw new ArgumentNullException(nameof(revokeTokenParameter.Token)); } // 1. Check the client credentials var errorMessage = string.Empty; var instruction = CreateAuthenticateInstruction(revokeTokenParameter, authenticationHeaderValue, certificate); var authResult = await _authenticateClient.AuthenticateAsync(instruction, issuerName); var client = authResult.Client; if (client == null) { throw new IdentityServerException(ErrorCodes.InvalidClient, authResult.ErrorMessage); } // 2. Retrieve the granted token & check if it exists GrantedToken grantedToken = await _tokenStore.GetAccessToken(revokeTokenParameter.Token); bool isAccessToken = true; if (grantedToken == null) { grantedToken = await _tokenStore.GetRefreshToken(revokeTokenParameter.Token); isAccessToken = false; } if (grantedToken == null) { throw new IdentityServerException(ErrorCodes.InvalidToken, ErrorDescriptions.TheTokenDoesntExist); } // 3. Verifies whether the token was issued to the client making the revocation request if (grantedToken.ClientId != client.ClientId) { throw new IdentityServerException(ErrorCodes.InvalidToken, string.Format(ErrorDescriptions.TheTokenHasNotBeenIssuedForTheGivenClientId, client.ClientId)); } // 4. Invalid the granted token if (isAccessToken) { return(await _tokenStore.RemoveAccessToken(grantedToken.AccessToken)); } return(await _tokenStore.RemoveRefreshToken(grantedToken.RefreshToken)); }
public async Task <GrantedTokenValidationResult> CheckRefreshTokenAsync(string refreshToken) { if (string.IsNullOrWhiteSpace(refreshToken)) { throw new ArgumentNullException(nameof(refreshToken)); } var grantedToken = await _tokenStore.GetRefreshToken(refreshToken); return(CheckGrantedToken(grantedToken)); }
private async Task <GrantedToken> ValidateParameter(RefreshTokenGrantTypeParameter refreshTokenGrantTypeParameter) { var grantedToken = await _tokenStore.GetRefreshToken(refreshTokenGrantTypeParameter.RefreshToken); if (grantedToken == null) { throw new IdentityServerException( ErrorCodes.InvalidGrant, ErrorDescriptions.TheRefreshTokenIsNotValid); } return(grantedToken); }
public async Task <Option <UmaIntrospectionResponse> > Execute( IntrospectionParameter introspectionParameter, CancellationToken cancellationToken) { var introspectionParameterToken = introspectionParameter.Token; if (string.IsNullOrWhiteSpace(introspectionParameterToken)) { return(new ErrorDetails { Status = HttpStatusCode.BadRequest, Title = ErrorCodes.InvalidToken, Detail = Strings.TheTokenDoesntExist }); } // Read this RFC for more information - https://docs.kantarainitiative.org/uma/wg/rec-oauth-uma-federated-authz-2.0.html#introspection-endpoint // 3. Retrieve the token type hint var tokenTypeHint = CoreConstants.StandardTokenTypeHintNames.AccessToken; if (CoreConstants.AllStandardTokenTypeHintNames.Contains(introspectionParameter.TokenTypeHint)) { tokenTypeHint = introspectionParameter.TokenTypeHint; } // 4. Trying to fetch the information about the access_token || refresh_token var grantedToken = tokenTypeHint switch { CoreConstants.StandardTokenTypeHintNames.AccessToken => await _tokenStore .GetAccessToken(introspectionParameterToken, cancellationToken) .ConfigureAwait(false), CoreConstants.StandardTokenTypeHintNames.RefreshToken => await _tokenStore .GetRefreshToken(introspectionParameterToken, cancellationToken) .ConfigureAwait(false), _ => null }; // 5. Return an error if there's no granted token if (grantedToken == null) { return(new ErrorDetails { Title = ErrorCodes.InvalidGrant, Detail = Strings.TheTokenIsNotValid }); } // 6. Fill-in parameters //// default : Specify the other parameters : NBF & JTI var result = new UmaIntrospectionResponse { //Scope = grantedToken.Scope.Split(' ', StringSplitOptions.RemoveEmptyEntries), ClientId = grantedToken.ClientId, Expiration = grantedToken.ExpiresIn, TokenType = grantedToken.TokenType }; if (grantedToken.UserInfoPayLoad != null) { var subject = grantedToken.IdTokenPayLoad?.GetClaimValue(OpenIdClaimTypes.Subject); if (!string.IsNullOrWhiteSpace(subject)) { result = result with { Subject = subject }; } } // 7. Fill-in the other parameters if (grantedToken.IdTokenPayLoad != null) { var audiencesArr = grantedToken.IdTokenPayLoad.GetArrayValue(StandardClaimNames.Audiences); var subject = grantedToken.IdTokenPayLoad.GetClaimValue(OpenIdClaimTypes.Subject); var userName = grantedToken.IdTokenPayLoad.GetClaimValue(OpenIdClaimTypes.Name); result = result with { Audience = string.Join(" ", audiencesArr), IssuedAt = grantedToken.IdTokenPayLoad.Iat ?? 0, Issuer = grantedToken.IdTokenPayLoad.Iss }; if (!string.IsNullOrWhiteSpace(subject)) { result = result with { Subject = subject }; } if (!string.IsNullOrWhiteSpace(userName)) { result = result with { UserName = userName }; } } // 8. Based on the expiration date disable OR enable the introspection resultKind var expirationDateTime = grantedToken.CreateDateTime.AddSeconds(grantedToken.ExpiresIn); result = result with { Active = DateTimeOffset.UtcNow < expirationDateTime }; return(result); } } }
public async Task <IntrospectionResult> Execute( IntrospectionParameter introspectionParameter, AuthenticationHeaderValue authenticationHeaderValue, string issuerName) { // 1. Validate the parameters if (introspectionParameter == null) { throw new ArgumentNullException(nameof(introspectionParameter)); } if (string.IsNullOrWhiteSpace(introspectionParameter.Token)) { throw new ArgumentNullException(nameof(introspectionParameter.Token)); } _introspectionParameterValidator.Validate(introspectionParameter); // 2. Authenticate the client var instruction = CreateAuthenticateInstruction(introspectionParameter, authenticationHeaderValue); var authResult = await _authenticateClient.AuthenticateAsync(instruction, issuerName); if (authResult.Client == null) { throw new IdentityServerException(ErrorCodes.InvalidClient, authResult.ErrorMessage); } // 3. Retrieve the token type hint var tokenTypeHint = Constants.StandardTokenTypeHintNames.AccessToken; if (Constants.AllStandardTokenTypeHintNames.Contains(introspectionParameter.TokenTypeHint)) { tokenTypeHint = introspectionParameter.TokenTypeHint; } // 4. Trying to fetch the information about the access_token || refresh_token GrantedToken grantedToken = null; if (tokenTypeHint == Constants.StandardTokenTypeHintNames.AccessToken) { grantedToken = await _tokenStore.GetAccessToken(introspectionParameter.Token); if (grantedToken == null) { grantedToken = await _tokenStore.GetRefreshToken(introspectionParameter.Token); } } else { grantedToken = await _tokenStore.GetRefreshToken(introspectionParameter.Token); if (grantedToken == null) { grantedToken = await _tokenStore.GetAccessToken(introspectionParameter.Token); } } // 5. Throw an exception if there's no granted token if (grantedToken == null) { throw new IdentityServerException( ErrorCodes.InvalidToken, ErrorDescriptions.TheTokenIsNotValid); } // 6. Fill-in parameters //// TODO : Specifiy the other parameters : NBF & JTI var result = new IntrospectionResult { Scope = grantedToken.Scope, ClientId = grantedToken.ClientId, Expiration = grantedToken.ExpiresIn, TokenType = grantedToken.TokenType }; // 7. Fill-in the other parameters if (grantedToken.IdTokenPayLoad != null) { var audiences = string.Empty; var audiencesArr = grantedToken.IdTokenPayLoad.GetArrayClaim(StandardClaimNames.Audiences); var issuedAt = grantedToken.IdTokenPayLoad.Iat; var issuer = grantedToken.IdTokenPayLoad.Issuer; var subject = grantedToken.IdTokenPayLoad.GetClaimValue(Jwt.Constants.StandardResourceOwnerClaimNames.Subject); var userName = grantedToken.IdTokenPayLoad.GetClaimValue(Jwt.Constants.StandardResourceOwnerClaimNames.Name); if (audiencesArr.Any()) { audiences = string.Join(" ", audiencesArr); } result.Audience = audiences; result.IssuedAt = issuedAt; result.Issuer = issuer; result.Subject = subject; result.UserName = userName; } // 8. Based on the expiration date disable OR enable the introspection result var expirationDateTime = grantedToken.CreateDateTime.AddSeconds(grantedToken.ExpiresIn); var tokenIsExpired = DateTime.UtcNow > expirationDateTime; if (tokenIsExpired) { result.Active = false; } else { result.Active = true; } return(result); }
public async Task <Option <OauthIntrospectionResponse> > Execute( IntrospectionParameter introspectionParameter, CancellationToken cancellationToken) { // Read this RFC for more information - https://www.rfc-editor.org/rfc/rfc7662.txt // 3. Retrieve the token type hint var tokenTypeHint = CoreConstants.StandardTokenTypeHintNames.AccessToken; if (CoreConstants.AllStandardTokenTypeHintNames.Contains(introspectionParameter.TokenTypeHint)) { tokenTypeHint = introspectionParameter.TokenTypeHint; } // 4. Trying to fetch the information about the access_token || refresh_token var introspectionParameterToken = introspectionParameter.Token; var grantedToken = tokenTypeHint switch { _ when introspectionParameterToken == null => null, CoreConstants.StandardTokenTypeHintNames.AccessToken => await _tokenStore .GetAccessToken(introspectionParameterToken, cancellationToken) .ConfigureAwait(false), CoreConstants.StandardTokenTypeHintNames.RefreshToken => await _tokenStore .GetRefreshToken(introspectionParameterToken, cancellationToken) .ConfigureAwait(false), _ => null }; // 5. Return an error if there's no granted token if (grantedToken == null) { return(new OauthIntrospectionResponse()); } // 6. Fill-in parameters //// default : Specify the other parameters : NBF & JTI var result = new OauthIntrospectionResponse { Scope = grantedToken.Scope.Split(' ', StringSplitOptions.RemoveEmptyEntries), ClientId = grantedToken.ClientId, Expiration = grantedToken.ExpiresIn, TokenType = grantedToken.TokenType }; if (grantedToken.UserInfoPayLoad != null) { var subject = grantedToken.IdTokenPayLoad?.GetClaimValue(OpenIdClaimTypes.Subject); if (!string.IsNullOrWhiteSpace(subject)) { result = result with { Subject = subject }; } } // 7. Fill-in the other parameters if (grantedToken.IdTokenPayLoad != null) { var audiencesArr = grantedToken.IdTokenPayLoad.GetArrayValue(StandardClaimNames.Audiences); var subject = grantedToken.IdTokenPayLoad.GetClaimValue(OpenIdClaimTypes.Subject); var userName = grantedToken.IdTokenPayLoad.GetClaimValue(OpenIdClaimTypes.Name); result = result with { Audience = string.Join(" ", audiencesArr), IssuedAt = grantedToken.IdTokenPayLoad.Iat ?? 0, Issuer = grantedToken.IdTokenPayLoad.Iss }; if (!string.IsNullOrWhiteSpace(subject)) { result = result with { Subject = subject }; } if (!string.IsNullOrWhiteSpace(userName)) { result = result with { UserName = userName }; } } // 8. Based on the expiration date disable OR enable the introspection resultKind var expirationDateTime = grantedToken.CreateDateTime.AddSeconds(grantedToken.ExpiresIn); result = result with { Active = DateTimeOffset.UtcNow < expirationDateTime }; return(result); } } }