"The access token provided does not contain the required scopes" in OAuth for Okta

I am trying to access the UserInfo endpoint from java using Nimbusds. I created a client:

       "oauthClient": {
            "autoKeyRotation": true,
            "client_id": "0oaal5rjiwSkD2yvB5d7",
            "token_endpoint_auth_method": "private_key_jwt",
            "pkce_required": false
          "jwks": {
                "keys": [
                        "kty": "RSA",
                        "id": "pkscrwynhlIOWXPqs5d7",
                        "status": "ACTIVE",
                        "kid": "1ef7b41a-6fd2-4d7e-9c09-6a2ab5d2dcda",
                        "use": null,
                        "e": "AQAB",
                        "n": ""

I create a token to use at the organization endpoint:

    Issuer myIssuer = new Issuer(String.format("https://%s",myOktaDomain));
    try {
      opMetadata = OIDCProviderMetadata.resolve(myIssuer);
      myPrivateKey = readFromDER();
    } catch (Exception ex) {

   AccessToken myAccessToken = null;
    URI tokenEndpoint = opMetadata.getTokenEndpointURI();
    AuthorizationGrant clientGrant = new ClientCredentialsGrant();
    String keyID = "1ef7b41a-6fd2-4d7e-9c09-6a2ab5d2dcda";
    Issuer myIssuer = new Issuer(tokenEndpoint);
    Audience aud = new Audience(tokenEndpoint);
    ClientID myID = new ClientID(clientId);
    JWTAuthenticationClaimsSet myClaimsSet = new JWTAuthenticationClaimsSet(myIssuer, myID, aud);
    PrivateKeyJWT clientAuth = new PrivateKeyJWT(myClaimsSet, JWSAlgorithm.RS512, myPrivateKey,
     keyID, null);

I can view the token on jwt.io, and it verifies if I paste in my public and private keys.

  "kid": "1ef7b41a-6fd2-4d7e-9c09-6a2ab5d2dcda",
  "alg": "RS512"
  "iss": "0oaal5rjiwSkD2yvB5d7",
  "sub": "0oaal5rjiwSkD2yvB5d7",
  "aud": "https://dev-mydev.okta.com/oauth2/v1/token",
  "exp": 1697400388,
  "jti": "r1Jzxw-3WigYEUA99z5rkogthgM3BrGOVrWSZP89QuE"

I prepare a token request

    Scope scope = new Scope("okta.users.manage","okta.users.read");
    TokenRequest request = new TokenRequest(tokenEndpoint, clientAuth, clientGrant, scope);
    HTTPResponse httpresponse = request.toHTTPRequest().send();

This returns a token with the payload:

  "ver": 1,
  "jti": "AT.Rig5VR6bcPdp9vbwrsJdxpkzaMxZxUhN3A7Z0c5ugbs",
  "iss": "https://dev-mydev.okta.com",
  "aud": "https://dev-mydev.okta.com",
  "sub": "0oaal5rjiwSkD2yvB5d7",
  "iat": 1697407810,
  "exp": 1697411410,
  "cid": "0oaal5rjiwSkD2yvB5d7",
  "scp": [

I use this token in my request:

    URI userEndpoint = opMetadata.getUserInfoEndpointURI();
    HttpClient httpClient = HttpClient.newBuilder().build();
    HttpRequest request = HttpRequest.newBuilder()
      .header("Authorization", myAccessToken.toAuthorizationHeader())

This returns:

[Bearer authorization_uri="http://dev-mydev.okta.com/oauth2/v1/authorize", realm="http://dev-mydev.okta.com", scope="openid", error="insufficient_scope", error_description="The access token provided does not contain the required scopes.", resource="/oauth2/v1/userinfo"]

What am I missing?

I figured it out. Instead of:

    URI userEndpoint = opMetadata.getUserInfoEndpointURI();

the endpoint is:

    URI userEndpoint = new URI(String.format("https://%s/api/v1/users",myOktaDomain));

HI Jeff,

Glad it is working.

If in the future you do want to call the /userinfo endpoint you would want an access_token which contains at least one of the following scopes [profiile email address].

thank you,

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.