class KeyStoreJwkKeyResolver implements SigningKeyResolver {

    @Override
    @SuppressWarnings("rawtypes")
    public Key resolveSigningKey(JwsHeader header, Claims claims) {
        String keyId = header.getKeyId();
        if (keyId == null || keyId.isEmpty()) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("KeyStoreJwkKeyResolver:resolveSigningKey: invalid key ID " + keyId);
            }
            return null;
        }

        // 1. find in key store
        String issuer = claims.getIssuer();
        if (this.keyStore != null && issuer != null && !issuer.isEmpty()) {
            String[] ds = AthenzUtils.splitPrincipalName(issuer);
            if (ds == null) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("KeyStoreJwkKeyResolver:resolveSigningKey: skip using KeyStore, invalid issuer " + issuer);
                }
            } else {
                String domain = ds[0];
                String service = ds[1];

                if (!SYS_AUTH_DOMAIN.equals(domain)) {
                    LOG.debug("KeyStoreJwkKeyResolver:resolveSigningKey: skip using KeyStore, invalid domain " + domain);
                } else {
                    String publicKey = this.keyStore.getPublicKey(domain, service, keyId);
                    if (publicKey != null && !publicKey.isEmpty()) {
                        try {
                            if (LOG.isDebugEnabled()) {
                                LOG.debug("KeyStoreJwkKeyResolver:resolveSigningKey: will use public key from key store: ({}, {}, {})", domain, service, keyId);
                            }
                            return Crypto.loadPublicKey(publicKey);
                        } catch (Throwable t) {
                            LOG.warn("KeyStoreJwkKeyResolver:resolveSigningKey: invalid public key format", t);
                        }
                    }
                }
            }
        }

        // 2. find in JWKS
        if (LOG.isDebugEnabled()) {
            LOG.debug("KeyStoreJwkKeyResolver:resolveSigningKey: will use public key from JWKS: ({})", keyId);
        }
        return this.jwksResolver.resolveSigningKey(header, claims);
    }

    public  KeyStoreJwkKeyResolver(KeyStore keyStore, String url, SSLContext sslContext);

}