okta / okta-sdk-dotnet

A .NET SDK for interacting with the Okta management API, enabling server-side code to manage Okta users, groups, applications, and more.
Other
160 stars 100 forks source link

`Custom scopes are not allowed for this request` when using `PrivateKey` #753

Open gao-artur opened 3 weeks ago

gao-artur commented 3 weeks ago

Describe the bug?

It worked in 7.0.6 but doesn't work in all versions between 8.0.0 and 9.0.0.

When trying to use any API with PrivateKey, the following exception is thrown:

Okta.Sdk.Client.ApiException: Error calling GetBearerToken: {"error":"invalid_scope","error_description":"Custom scopes are not allowed for this request."}
    at Okta.Sdk.Api.OAuthApi.GetBearerTokenWithHttpInfoAsync(CancellationToken cancellationToken)
   at Okta.Sdk.Api.OAuthApi.GetBearerTokenAsync(CancellationToken cancellationToken)
   at Okta.Sdk.Client.DefaultOAuthTokenProvider.RequestAccessTokenAsync(CancellationToken cancellationToken)
   at Okta.Sdk.Client.DefaultOAuthTokenProvider.GetAccessTokenResponseAsync(Boolean forceRenew, CancellationToken cancellationToken)
   at Okta.Sdk.Client.DefaultOAuthTokenProvider.AddOrUpdateAuthorizationHeader(RequestOptions requestOptions, String requestUri, String httpMethod, CancellationToken cancellationToken)
   at Okta.Sdk.Api.ApplicationApi.GetApplicationWithHttpInfoAsync(String appId, String expand, CancellationToken cancellationToken)
   at Okta.Sdk.Api.ApplicationApi.GetApplicationAsync(String appId, String expand, CancellationToken cancellationToken)
   at TestProject2.UnitTest1.TestMethod1() in C:\Users\Artur\source\repos\TestProject2\UnitTest1.cs:line 21

What is expected to happen?

The API call should succeed.

What is the actual behavior?

ApiException: Error calling GetBearerToken: {"error":"invalid_scope","error_description":"Custom scopes are not allowed for this request."}

Reproduction Steps?

Add config to appsetting.json

{
  "Okta": {
    "Client": {
      "OktaDomain": "xxx",
      "ClientId": "xxx",
      "AuthorizationMode": "PrivateKey",
      "PrivateKey": {
        "p": "xxx",
        "kty": "RSA",
        "q": "xxx",
        "d": "xxx",
        "e": "xxx",
        "use": "sig",
        "qi": "xxx",
        "dp": "xxx",
        "alg": "RS256",
        "dq": "xxx",
        "n": "xxx"
      },
      "Scopes": [
        "okta.apps.manage"
      ]
    }
  }
}

Try getting the application

var api = new ApplicationApi();
var app = await api.GetApplicationAsync("app id");

Additional Information?

No response

.NET Version

8.0.403

SDK Version

9.0.0

OS version

BuildNumber Caption OSArchitecture Version
19045 Microsoft Windows 10 Enterprise 64-bit 10.0.19045
bryanapellanes-okta commented 3 weeks ago

@gao-artur Thanks for bringing this to our attention. I've entered an internal ticket for tracking and prioritization: OKTA-824760

chekm8 commented 1 week ago

@bryanapellanes-okta Any update on this? Is there an alternate preferred option for accessing the Okta Management APIs as a work around in the mean time?

I currently have a "API Services" application configured to use Public key / Private key and I am getting the same error.

Note: I also had to disable "Require Demonstrating Proof of Possession (DPoP)" which was blocking me, Possible related to #745. According to the main help page DPoP should have been handled automatically but it was throwing "GetBearerToken: {"error":"invalid_dpop_proof","error_description":"The DPoP proof JWT cannot be parsed."}" error. Not sure if the 2 are related, but after disabling DPoP I get the "Custom scopes are not allowed" message.

nyklav commented 1 week ago

I think I was able to determine the cause of the “Custom scopes are not allowed” error, but this only applies if you are using multiple scopes.

OAuthApi.cs

var scopes = string.Join("+", Configuration.Scopes);
localVarRequestOptions.FormParameters.Add("scope", scopes);

The space character is encoded twice, the first time string.Join("+", Configuration.Scopes) and the second time inside the RestSharp library. Because of this, we get okta.groups.read%20okta.users.read instead of okta.groups.read+okta.users.read.

Replacing the plus sign with a space solved the problem.

var scopes = string.Join(" ", Configuration.Scopes);