1
votes

I am creating an OpenID/OAuth2 client for Oracle IDCS. At first, I tested my Spring-Boot configuration with Google and GitHub, and it worked just fine. However, when I was trying to integrate with Oracle IDCS, I was receiving 401 Unauthorized when the application tries to get the signing keys from JWK Set URI (https://idcs-XXXXXXXXX.identity.oraclecloud.com/admin/v1/SigningCert/jwk). I learned that Oracle IDCS JWK Set URI requires the token in the header (Authorization: Bearer <Access Token Value>). This is not the case with Google and GitHub.

application.yml

spring:
  main:
    banner-mode: "console"
  jpa:
    hibernate:
      ddl-auto: "create-drop"
  security:
    oauth2:
      client:
        registration:
          oracle:
            client-id: XXXXXX
            client-secret: XXXXXX
            authorization-grant-type: authorization_code
            redirect-uri: "http://localhost:8080/login/oauth2/code/oracle"
            scope: openid
            client-name: Oracle
            provider: oracle
        provider:
          oracle:
            authorization-uri: "https://idcs-XXXXXXXXX.identity.oraclecloud.com/oauth2/v1/authorize"
            token-uri: "https://idcs-XXXXXXXXX.identity.oraclecloud.com/oauth2/v1/token"
            user-info-uri: "https://idcs-XXXXXXXXX.identity.oraclecloud.com/oauth2/v1/userinfo"
            jwk-set-uri: "https://idcs-XXXXXXXXX.identity.oraclecloud.com/admin/v1/SigningCert/jwk"
            token-info-uri: "https://idcs-XXXXXXXXX.identity.oraclecloud.com/oauth2/v1/introspect"
            user-name-attribute: name
  profiles:
    active: "@spring.profiles.active@"

snippet from org.springframework.security.oauth2.jwt.NimbusJwtDecoder

private static class RestOperationsResourceRetriever implements ResourceRetriever {
    private static final MediaType APPLICATION_JWK_SET_JSON = new MediaType("application", "jwk-set+json");
        private final RestOperations restOperations;

        RestOperationsResourceRetriever(RestOperations restOperations) {
            Assert.notNull(restOperations, "restOperations cannot be null");
            this.restOperations = restOperations;
        }

        @Override
        public Resource retrieveResource(URL url) throws IOException {
            HttpHeaders headers = new HttpHeaders();
            headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON, APPLICATION_JWK_SET_JSON));

            ResponseEntity<String> response;
            try {
                RequestEntity<Void> request = new RequestEntity<>(headers, HttpMethod.GET, url.toURI());
                response = this.restOperations.exchange(request, String.class);
            } catch (Exception ex) {
                throw new IOException(ex);
            }

            if (response.getStatusCodeValue() != 200) {
                throw new IOException(response.toString());
            }

            return new Resource(response.getBody(), "UTF-8");
        }
    }
}

UPDATE: Manually sending an HTTP GET request with the token to JWK Set URI gives me the keys.

curl -v -k -X GET -H "Content-Type:application/json" -H "Authorization: Bearer XXXXXXXXX" https://idcs-XXXXXXXXX.identity.oraclecloud.com/admin/v1/SigningCert/jwk

{
    "keys":[
        {
            "kty":"RSA",
            "x5t#S256":"XXXX",
            "e":"XXXX",
            "x5t":"XXXX",
            "kid":"SIGNING_KEY",
            "x5c":[
                "XXXX",
                "XXXX"

            ],
            "key_ops":[
                "encrypt",
                "verify"

            ],
            "alg":"RS256",
            "n":"XXXX"

        }
    ]
}

How do I go about including the token in the HTTP GET request header to JWK Set URI?

Is there a way in Spring Boot OAuth2 client to manually set the signing keys? The configuration detailed here does not work.

1
Hello, did you get this resolved, i am also facing a similar issue where jwks uri is protected. Between, how did you try Google as OP public network or from VPN?PrabhakarP
I have not resolved this yet. I'm working on this on and off and I will make sure to reply when I resolved it.bmacainag
Is there any doc to use spring security with IDCS?Sufail Khan

1 Answers

0
votes

You need to turn on "IDCS -> Settings -> Default Settings -> Access Signing Certificate" to configure whether clients can access the signing certificate for the identity domain without logging in to Oracle Identity Cloud Service.