Example usage for org.springframework.security.oauth2.common.exceptions InvalidTokenException InvalidTokenException

List of usage examples for org.springframework.security.oauth2.common.exceptions InvalidTokenException InvalidTokenException

Introduction

In this page you can find the example usage for org.springframework.security.oauth2.common.exceptions InvalidTokenException InvalidTokenException.

Prototype

public InvalidTokenException(String msg) 

Source Link

Usage

From source file:org.cloudfoundry.identity.uaa.oauth.token.UaaTokenServices.java

@Override
public OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException {
    Map<String, Object> claims = getClaimsForToken(accessToken);

    // Check token expiry
    Integer expiration = (Integer) claims.get(EXP);
    if (expiration != null && new Date(expiration * 1000l).before(new Date())) {
        throw new InvalidTokenException("Invalid access token (expired): " + accessToken + " expired at "
                + new Date(expiration * 1000l));
    }//from w  w w  . java2  s. c  om

    // Check client ID is valid
    validateClient((String) claims.get(CLIENT_ID));
    validateClient((String) claims.get(CID));

    @SuppressWarnings("unchecked")
    ArrayList<String> scopes = (ArrayList<String>) claims.get(SCOPE);

    AuthorizationRequest authorizationRequest = new AuthorizationRequest((String) claims.get(CLIENT_ID),
            scopes);

    ArrayList<String> rids = (ArrayList<String>) claims.get(AUD);
    //TODO - Fix null resource IDs for a client_credentials request to /oauth/token
    Set<String> resourceIds = Collections
            .unmodifiableSet(rids == null ? new HashSet<String>() : new HashSet<>(rids));
    authorizationRequest.setResourceIds(resourceIds);

    authorizationRequest.setApproved(true);

    Collection<? extends GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(
            StringUtils.collectionToCommaDelimitedString(defaultUserAuthorities));
    if (claims.containsKey("authorities")) {
        Object authoritiesFromClaims = claims.get("authorities");
        if (authoritiesFromClaims instanceof String) {
            authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) authoritiesFromClaims);
        }
        if (authoritiesFromClaims instanceof Collection) {
            authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(
                    StringUtils.collectionToCommaDelimitedString((Collection<?>) authoritiesFromClaims));
        }
    }

    Authentication userAuthentication = null;
    // Is this a user token?
    if (claims.containsKey(EMAIL)) {
        UaaUser user = new UaaUser((String) claims.get(USER_ID), (String) claims.get(USER_NAME), null,
                (String) claims.get(EMAIL), UaaAuthority.USER_AUTHORITIES, null, null, null, null, null, null,
                false);

        UaaPrincipal principal = new UaaPrincipal(user);
        userAuthentication = new UaaAuthentication(principal, UaaAuthority.USER_AUTHORITIES, null);
    } else {
        authorizationRequest.setAuthorities(authorities);
    }

    OAuth2Authentication authentication = new OAuth2Authentication(authorizationRequest.createOAuth2Request(),
            userAuthentication);
    authentication.setAuthenticated(true);
    return authentication;
}

From source file:org.cloudfoundry.identity.uaa.oauth.token.UaaTokenServices.java

/**
 * This method is implemented to support older API calls that assume the
 * presence of a token store/*from w w w .ja  va  2 s . com*/
 */
@Override
public OAuth2AccessToken readAccessToken(String accessToken) {
    Map<String, Object> claims = getClaimsForToken(accessToken);

    // Expiry is verified by check_token
    OpenIdToken token = new OpenIdToken(accessToken);
    token.setTokenType(OAuth2AccessToken.BEARER_TYPE);
    Integer exp = (Integer) claims.get(EXP);
    if (null != exp) {
        token.setExpiration(new Date(exp.longValue() * 1000l));
    }

    @SuppressWarnings("unchecked")
    ArrayList<String> scopes = (ArrayList<String>) claims.get(SCOPE);
    if (null != scopes && scopes.size() > 0) {
        token.setScope(new HashSet<String>(scopes));
    }

    String email = (String) claims.get(EMAIL);

    // Only check user access tokens
    if (null != email) {
        String userId = (String) claims.get(USER_ID);

        UaaUser user = userDatabase.retrieveUserById(userId);

        Integer accessTokenIssuedAt = (Integer) claims.get(IAT);
        long accessTokenIssueDate = accessTokenIssuedAt.longValue() * 1000l;

        // If the user changed their password, expire the access token
        if (user.getModified().after(new Date(accessTokenIssueDate))) {
            logger.debug("User was last modified at " + user.getModified() + " access token was issued at "
                    + new Date(accessTokenIssueDate));
            throw new InvalidTokenException("Invalid access token (password changed): " + accessToken);
        }

        // Check approvals to make sure they're all valid, approved and not
        // more recent
        // than the token itself
        String clientId = (String) claims.get(CLIENT_ID);
        ClientDetails client = clientDetailsService.loadClientByClientId(clientId);

        @SuppressWarnings("unchecked")
        ArrayList<String> tokenScopes = (ArrayList<String>) claims.get(SCOPE);
        Set<String> autoApprovedScopes = getAutoApprovedScopes(claims.get(GRANT_TYPE), tokenScopes, client);
        if (autoApprovedScopes.containsAll(tokenScopes)) {
            return token;
        }
        checkForApproval(userId, clientId, tokenScopes, autoApprovedScopes, new Date(accessTokenIssueDate));
    }

    return token;
}

From source file:org.cloudfoundry.identity.uaa.oauth.token.UaaTokenServices.java

private Map<String, Object> getClaimsForToken(String token) {
    Jwt tokenJwt = null;// w  w w .  j  a v a 2  s.  c  om
    try {
        tokenJwt = JwtHelper.decodeAndVerify(token, signerProvider.getVerifier());
    } catch (Throwable t) {
        logger.debug("Invalid token (could not decode)");
        throw new InvalidTokenException("Invalid token (could not decode): " + token);
    }

    Map<String, Object> claims = null;
    try {
        claims = mapper.readValue(tokenJwt.getClaims(), new TypeReference<Map<String, Object>>() {
        });
    } catch (Exception e) {
        throw new IllegalStateException("Cannot read token claims", e);
    }

    if (tokenEndpoint != null && !tokenEndpoint.equals(claims.get(ISS))) {
        throw new InvalidTokenException("Invalid issuer for token:" + claims.get(ISS));
    }

    return claims;
}

From source file:org.cloudfoundry.identity.uaa.oauth.TokenRevocationEndpoint.java

@ExceptionHandler({ ScimResourceNotFoundException.class, NoSuchClientException.class,
        EmptyResultDataAccessException.class })
public ResponseEntity<OAuth2Exception> handleException(Exception e) throws Exception {
    logger.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage());
    InvalidTokenException e404 = new InvalidTokenException("Resource not found") {
        @Override//from w w w. ja va 2  s.  c  om
        public int getHttpErrorCode() {
            return 404;
        }
    };
    return exceptionTranslator.translate(e404);
}

From source file:org.cloudfoundry.identity.uaa.oauth.UaaTokenServices.java

@Override
public OAuth2AccessToken refreshAccessToken(String refreshTokenValue, TokenRequest request)
        throws AuthenticationException {
    if (null == refreshTokenValue) {
        throw new InvalidTokenException("Invalid refresh token (empty token)");
    }//from   w  w  w  . ja v  a2 s . co  m

    if (!"refresh_token".equals(request.getRequestParameters().get("grant_type"))) {
        throw new InvalidGrantException(
                "Invalid grant type: " + request.getRequestParameters().get("grant_type"));
    }

    TokenValidation tokenValidation = validateToken(refreshTokenValue);
    Map<String, Object> claims = tokenValidation.getClaims();
    refreshTokenValue = tokenValidation.getJwt().getEncoded();

    @SuppressWarnings("unchecked")
    ArrayList<String> tokenScopes = (ArrayList<String>) claims.get(SCOPE);
    if (isRestrictRefreshGrant() && !tokenScopes.contains(UAA_REFRESH_TOKEN)) {
        throw new InsufficientScopeException(String.format("Expected scope %s is missing", UAA_REFRESH_TOKEN));
    }

    // TODO: Should reuse the access token you get after the first
    // successful authentication.
    // You will get an invalid_grant error if your previous token has not
    // expired yet.
    // OAuth2RefreshToken refreshToken =
    // tokenStore.readRefreshToken(refreshTokenValue);
    // if (refreshToken == null) {
    // throw new InvalidGrantException("Invalid refresh token: " +
    // refreshTokenValue);
    // }

    String clientId = (String) claims.get(CID);
    if (clientId == null || !clientId.equals(request.getClientId())) {
        throw new InvalidGrantException("Wrong client for this refresh token: " + refreshTokenValue);
    }

    String userid = (String) claims.get(USER_ID);

    String refreshTokenId = (String) claims.get(JTI);
    String accessTokenId = generateUniqueTokenId();

    boolean opaque = TokenConstants.OPAQUE
            .equals(request.getRequestParameters().get(TokenConstants.REQUEST_TOKEN_FORMAT));
    boolean revocable = opaque || (claims.get(REVOCABLE) == null ? false : (Boolean) claims.get(REVOCABLE));

    // TODO: Need to add a lookup by id so that the refresh token does not
    // need to contain a name
    UaaUser user = userDatabase.retrieveUserById(userid);
    ClientDetails client = clientDetailsService.loadClientByClientId(clientId);

    Integer refreshTokenIssuedAt = (Integer) claims.get(IAT);
    long refreshTokenIssueDate = refreshTokenIssuedAt.longValue() * 1000l;

    Integer refreshTokenExpiry = (Integer) claims.get(EXP);
    long refreshTokenExpireDate = refreshTokenExpiry.longValue() * 1000l;

    if (new Date(refreshTokenExpireDate).before(new Date())) {
        throw new InvalidTokenException("Invalid refresh token (expired): " + refreshTokenValue + " expired at "
                + new Date(refreshTokenExpireDate));
    }

    // default request scopes to what is in the refresh token
    Set<String> requestedScopes = request.getScope();
    if (requestedScopes.isEmpty()) {
        requestedScopes = new HashSet<>(tokenScopes);
    }

    // The user may not request scopes that were not part of the refresh
    // token
    if (tokenScopes.isEmpty() || !tokenScopes.containsAll(requestedScopes)) {
        throw new InvalidScopeException(
                "Unable to narrow the scope of the client authentication to " + requestedScopes + ".",
                new HashSet<>(tokenScopes));
    }

    // from this point on, we only care about the scopes requested, not what
    // is in the refresh token
    // ensure all requested scopes are approved: either automatically or
    // explicitly by the user
    String grantType = claims.get(GRANT_TYPE).toString();
    checkForApproval(userid, clientId, requestedScopes, getAutoApprovedScopes(grantType, tokenScopes, client));

    // if we have reached so far, issue an access token
    Integer validity = client.getAccessTokenValiditySeconds();

    String nonce = (String) claims.get(NONCE);

    @SuppressWarnings("unchecked")
    Map<String, String> additionalAuthorizationInfo = (Map<String, String>) claims.get(ADDITIONAL_AZ_ATTR);

    @SuppressWarnings("unchecked")
    Map<String, String> externalAttributes = (Map<String, String>) claims.get(EXTERNAL_ATTR);

    String revocableHashSignature = (String) claims.get(REVOCATION_SIGNATURE);
    if (hasText(revocableHashSignature)) {
        String clientSecretForHash = client.getClientSecret();
        if (clientSecretForHash != null && clientSecretForHash.split(" ").length > 1) {
            clientSecretForHash = clientSecretForHash.split(" ")[1];
        }
        String newRevocableHashSignature = UaaTokenUtils.getRevocableTokenSignature(client, clientSecretForHash,
                user);
        if (!revocableHashSignature.equals(newRevocableHashSignature)) {
            throw new TokenRevokedException(refreshTokenValue);
        }
    }

    Set<String> audience = new HashSet<>((ArrayList<String>) claims.get(AUD));

    int zoneAccessTokenValidity = getZoneAccessTokenValidity();

    CompositeAccessToken accessToken = createAccessToken(accessTokenId, user.getId(), user,
            (claims.get(AUTH_TIME) != null) ? new Date(((Long) claims.get(AUTH_TIME)) * 1000l) : null,
            validity != null ? validity.intValue() : zoneAccessTokenValidity, null, requestedScopes, clientId,
            audience /*request.createOAuth2Request(client).getResourceIds()*/, grantType, refreshTokenValue,
            nonce, additionalAuthorizationInfo, externalAttributes, new HashSet<>(), revocableHashSignature,
            false, null, //TODO populate response types
            null, revocable, null, null);

    DefaultExpiringOAuth2RefreshToken expiringRefreshToken = new DefaultExpiringOAuth2RefreshToken(
            refreshTokenValue, new Date(refreshTokenExpireDate));
    return persistRevocableToken(accessTokenId, refreshTokenId, accessToken, expiringRefreshToken, clientId,
            user.getId(), opaque, revocable);

}

From source file:org.cloudfoundry.identity.uaa.oauth.UaaTokenServices.java

private void checkForApproval(String userid, String clientId, Collection<String> requestedScopes,
        Collection<String> autoApprovedScopes) {
    if (autoApprovedScopes.containsAll(requestedScopes)) {
        return;//from   w  w w .  ja  va2 s .c o  m
    }
    Set<String> approvedScopes = new HashSet<>(autoApprovedScopes);

    // Search through the users approvals for scopes that are requested, not
    // auto approved, not expired,
    // not DENIED and not approved more recently than when this access token
    // was issued.
    List<Approval> approvals = approvalStore.getApprovals(userid, clientId);
    for (Approval approval : approvals) {
        if (requestedScopes.contains(approval.getScope()) && approval.getStatus() == ApprovalStatus.APPROVED) {
            if (!approval.isCurrentlyActive()) {
                logger.debug("Approval " + approval + " has expired. Need to re-approve.");
                throw new InvalidTokenException("Invalid token (approvals expired)");
            }
            approvedScopes.add(approval.getScope());
        }
    }

    // Only issue the token if all the requested scopes have unexpired
    // approvals made before the refresh token was
    // issued OR if those scopes are auto approved
    if (!approvedScopes.containsAll(requestedScopes)) {
        logger.debug("All requested scopes " + requestedScopes + " were not approved " + approvedScopes);
        Set<String> unapprovedScopes = new HashSet<String>(requestedScopes);
        unapprovedScopes.removeAll(approvedScopes);
        throw new InvalidTokenException(
                "Invalid token (some requested scopes are not approved): " + unapprovedScopes);
    }
}

From source file:org.cloudfoundry.identity.uaa.oauth.UaaTokenServices.java

private CompositeAccessToken createAccessToken(String tokenId, String userId, UaaUser user,
        Date userAuthenticationTime, int validitySeconds, Collection<GrantedAuthority> clientScopes,
        Set<String> requestedScopes, String clientId, Set<String> resourceIds, String grantType,
        String refreshToken, String nonce, Map<String, String> additionalAuthorizationAttributes,
        Map<String, String> externalAttributes, Set<String> responseTypes, String revocableHashSignature,
        boolean forceIdTokenCreation, Set<String> externalGroupsForIdToken,
        Map<String, List<String>> userAttributesForIdToken, boolean revocable,
        Set<String> authenticationMethods, Set<String> authNContextClassRef) throws AuthenticationException {
    CompositeAccessToken accessToken = new CompositeAccessToken(tokenId);
    accessToken.setExpiration(new Date(System.currentTimeMillis() + (validitySeconds * 1000L)));
    accessToken.setRefreshToken(refreshToken == null ? null : new DefaultOAuth2RefreshToken(refreshToken));

    if (null == requestedScopes || requestedScopes.size() == 0) {
        logger.debug("No scopes were granted");
        throw new InvalidTokenException("No scopes were granted");
    }/*from w ww.  ja  va 2  s.c  om*/

    accessToken.setScope(requestedScopes);

    Map<String, Object> info = new HashMap<String, Object>();
    info.put(JTI, accessToken.getValue());
    if (null != additionalAuthorizationAttributes) {
        info.put(ADDITIONAL_AZ_ATTR, additionalAuthorizationAttributes);
    }
    if (null != externalAttributes) {
        info.put(EXTERNAL_ATTR, externalAttributes);
    }
    if (nonce != null) {
        info.put(NONCE, nonce);
    }
    accessToken.setAdditionalInformation(info);

    String content;
    Map<String, ?> jwtAccessToken = createJWTAccessToken(accessToken, userId, user, userAuthenticationTime,
            clientScopes, requestedScopes, clientId, resourceIds, grantType, refreshToken,
            revocableHashSignature, revocable);
    try {
        content = JsonUtils.writeValueAsString(jwtAccessToken);
    } catch (JsonUtils.JsonUtilException e) {
        throw new IllegalStateException("Cannot convert access token to JSON", e);
    }
    String token = JwtHelper.encode(content, KeyInfo.getActiveKey().getSigner()).getEncoded();
    // This setter copies the value and returns. Don't change.
    accessToken.setValue(token);
    populateIdToken(accessToken, jwtAccessToken, requestedScopes, responseTypes, clientId, forceIdTokenCreation,
            externalGroupsForIdToken, user, userAttributesForIdToken, authenticationMethods,
            authNContextClassRef);
    publish(new TokenIssuedEvent(accessToken, SecurityContextHolder.getContext().getAuthentication()));

    return accessToken;
}

From source file:org.cloudfoundry.identity.uaa.oauth.UaaTokenServices.java

@Override
public OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException {
    if (StringUtils.isEmpty(accessToken)) {
        throw new InvalidTokenException(
                "Invalid access token value, must be at least 30 characters:" + accessToken);
    }//from   w  ww  . j  a va 2s  .  c om

    TokenValidation tokenValidation = validateToken(accessToken);
    Map<String, Object> claims = tokenValidation.getClaims();
    accessToken = tokenValidation.getJwt().getEncoded();

    // Check token expiry
    Integer expiration = (Integer) claims.get(EXP);
    if (expiration != null && new Date(expiration * 1000l).before(new Date())) {
        throw new InvalidTokenException("Invalid access token (expired): " + accessToken + " expired at "
                + new Date(expiration * 1000l));
    }

    @SuppressWarnings("unchecked")
    ArrayList<String> scopes = (ArrayList<String>) claims.get(SCOPE);

    AuthorizationRequest authorizationRequest = new AuthorizationRequest((String) claims.get(CLIENT_ID),
            scopes);

    ArrayList<String> rids = (ArrayList<String>) claims.get(AUD);
    //TODO - Fix null resource IDs for a client_credentials request to /oauth/token
    Set<String> resourceIds = Collections
            .unmodifiableSet(rids == null ? new HashSet<String>() : new HashSet<>(rids));
    authorizationRequest.setResourceIds(resourceIds);

    authorizationRequest.setApproved(true);

    Collection<? extends GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(
            StringUtils.collectionToCommaDelimitedString(defaultUserAuthorities));
    if (claims.containsKey("authorities")) {
        Object authoritiesFromClaims = claims.get("authorities");
        if (authoritiesFromClaims instanceof String) {
            authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) authoritiesFromClaims);
        }
        if (authoritiesFromClaims instanceof Collection) {
            authorities = AuthorityUtils.commaSeparatedStringToAuthorityList(
                    StringUtils.collectionToCommaDelimitedString((Collection<?>) authoritiesFromClaims));
        }
    }

    Authentication userAuthentication = null;
    // Is this a user token - minimum info is user_id
    if (claims.containsKey(USER_ID)) {
        UaaUser user = userDatabase.retrieveUserById((String) claims.get(USER_ID));
        UaaPrincipal principal = new UaaPrincipal(user);
        userAuthentication = new UaaAuthentication(principal, UaaAuthority.USER_AUTHORITIES, null);
    } else {
        authorizationRequest.setAuthorities(authorities);
    }

    OAuth2Authentication authentication = new UaaOauth2Authentication(accessToken,
            IdentityZoneHolder.get().getId(), authorizationRequest.createOAuth2Request(), userAuthentication);
    authentication.setAuthenticated(true);
    return authentication;
}

From source file:org.cloudfoundry.identity.uaa.oauth.UaaTokenServices.java

protected TokenValidation validateToken(String token) {
    TokenValidation tokenValidation;// ww w . j a  va  2  s. c o  m

    if (!UaaTokenUtils.isJwtToken(token)) {
        RevocableToken revocableToken;
        try {
            revocableToken = tokenProvisioning.retrieve(token);
        } catch (EmptyResultDataAccessException ex) {
            throw new TokenRevokedException(
                    "The token expired, was revoked, or the token ID is incorrect: " + token);
        }
        token = revocableToken.getValue();
    }

    tokenValidation = validate(token).checkRevocableTokenStore(tokenProvisioning).throwIfInvalid();
    Jwt tokenJwt = tokenValidation.getJwt();

    String keyId = tokenJwt.getHeader().getKid();
    KeyInfo key;
    if (keyId != null) {
        key = KeyInfo.getKey(keyId);
    } else {
        key = KeyInfo.getActiveKey();
    }

    if (key == null) {
        throw new InvalidTokenException("Invalid key ID: " + keyId);
    }
    SignatureVerifier verifier = key.getVerifier();
    tokenValidation.checkSignature(verifier).throwIfInvalid();
    Map<String, Object> claims = tokenValidation.getClaims();

    tokenValidation.checkIssuer(getTokenEndpoint()).throwIfInvalid();

    String clientId = (String) claims.get(CID);
    String userId = (String) claims.get(USER_ID);
    UaaUser user = null;
    ClientDetails client;
    try {
        client = clientDetailsService.loadClientByClientId(clientId);
    } catch (NoSuchClientException x) {
        //happens if the client is deleted and token exist
        throw new UnauthorizedClientException("Invalid client ID " + clientId);
    }
    tokenValidation.checkClient(client).throwIfInvalid();

    if (UaaTokenUtils.isUserToken(claims)) {
        try {
            user = userDatabase.retrieveUserById(userId);
            tokenValidation.checkUser(user).throwIfInvalid();
        } catch (UsernameNotFoundException x) {
        }
    }

    tokenValidation.checkRevocableTokenStore(tokenProvisioning).throwIfInvalid();

    List<String> clientSecrets = new ArrayList<>();
    List<String> revocationSignatureList = new ArrayList<>();
    if (client.getClientSecret() != null) {
        clientSecrets.addAll(Arrays.asList(client.getClientSecret().split(" ")));
    } else {
        revocationSignatureList.add(UaaTokenUtils.getRevocableTokenSignature(client, null, user));
    }

    for (String clientSecret : clientSecrets) {
        revocationSignatureList.add(UaaTokenUtils.getRevocableTokenSignature(client, clientSecret, user));
    }

    tokenValidation = tokenValidation.checkRevocationSignature(revocationSignatureList);

    tokenValidation.throwIfInvalid();
    return tokenValidation;
}

From source file:org.cloudfoundry.identity.uaa.provider.oauth.XOAuthAuthenticationManager.java

private JsonWebKeySet<JsonWebKey> getTokenKeyFromOAuth(AbstractXOAuthIdentityProviderDefinition config) {
    String tokenKey = config.getTokenKey();
    if (StringUtils.hasText(tokenKey)) {
        Map<String, Object> p = new HashMap<>();
        p.put("value", tokenKey);
        p.put("kty", KeyInfo.isAssymetricKey(tokenKey) ? RSA.name() : MAC.name());
        logger.debug("Key configured, returning.");
        return new JsonWebKeySet<>(Arrays.asList(new JsonWebKey(p)));
    }// w  ww  .j  a  v  a  2 s .  co  m
    URL tokenKeyUrl = config.getTokenKeyUrl();
    if (tokenKeyUrl == null || !StringUtils.hasText(tokenKeyUrl.toString())) {
        return new JsonWebKeySet<>(Collections.emptyList());
    }

    MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
    headers.add("Authorization", getClientAuthHeader(config));
    headers.add("Accept", "application/json");
    HttpEntity tokenKeyRequest = new HttpEntity<>(null, headers);
    logger.debug("Fetching token keys from:" + tokenKeyUrl);
    ResponseEntity<String> responseEntity = getRestTemplate(config).exchange(tokenKeyUrl.toString(),
            HttpMethod.GET, tokenKeyRequest, String.class);
    logger.debug("Token key response:" + responseEntity.getStatusCode());
    if (responseEntity.getStatusCode() == HttpStatus.OK) {
        return JsonWebKeyHelper.deserialize(responseEntity.getBody());
    } else {
        throw new InvalidTokenException(
                "Unable to fetch verification keys, status:" + responseEntity.getStatusCode());
    }
}