0

This question is not a duplicate of AADSTS70011: The provided value for the input parameter 'scope' is not valid because that post didn't solve my problem.

This is the code:

using Microsoft.Identity.Client;

var tenantId = "common";
var clientId = "475c75f3-9fdc-4d23-8956-104342a43740";
var apiUrl = "https://graph.microsoft.com";

var app = PublicClientApplicationBuilder.CreateWithApplicationOptions(
  new PublicClientApplicationOptions{
    TenantId="common",
    ClientId=clientId
  }
)
.WithRedirectUri("http://localhost")
.Build();
string[] scopes = new string[] {$"{apiUrl}/.default"};

var result = await app.AcquireTokenWithDeviceCode(
  scopes,
  deviceCodeResult =>
  {
    Console.WriteLine(deviceCodeResult.Message);
    return Task.FromResult(0);
  }
).ExecuteAsync();
Console.WriteLine(result.AccessToken);

This is the error message that I get:

Unhandled exception. MSAL.NetCore.4.44.0.0.MsalServiceException: 
        ErrorCode: invalid_scope
Microsoft.Identity.Client.MsalServiceException: AADSTS70011: The provided value for the input parameter 'scope' is not valid. One or more scopes in 'https://graph.microsoft.com/.default offline_access profile openid' are not compatible with each other.
Trace ID: 977837bb-49bb-448a-990f-f640ee518500
Correlation ID: f6483ab1-e0be-43b0-8859-086b28ac6ea2
Timestamp: 2022-06-12 00:26:35Z
   at Microsoft.Identity.Client.OAuth2.OAuth2Client.ThrowServerException(HttpResponse response, RequestContext requestContext)
   at Microsoft.Identity.Client.OAuth2.OAuth2Client.CreateResponse[T](HttpResponse response, RequestContext requestContext)
   at Microsoft.Identity.Client.OAuth2.OAuth2Client.ExecuteRequestAsync[T](Uri endPoint, HttpMethod method, RequestContext requestContext, Boolean expectErrorsOn200OK, Boolean addCommonHeaders, Func`2 onBeforePostRequestData)
   at Microsoft.Identity.Client.OAuth2.OAuth2Client.GetTokenAsync(Uri endPoint, RequestContext requestContext, Boolean addCommonHeaders, Func`2 onBeforePostRequestHandler)
   at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ICoreLogger logger)
   at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ICoreLogger logger)
   at Microsoft.Identity.Client.OAuth2.TokenClient.SendTokenRequestAsync(IDictionary`2 additionalBodyParameters, String scopeOverride, String tokenEndpointOverride, CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.DeviceCodeRequest.WaitForTokenResponseAsync(DeviceCodeResult deviceCodeResult, CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.DeviceCodeRequest.WaitForTokenResponseAsync(DeviceCodeResult deviceCodeResult, CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.DeviceCodeRequest.ExecuteAsync(CancellationToken cancellationToken)
   at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync(CancellationToken cancellationToken)
   at Microsoft.Identity.Client.ApiConfig.Executors.PublicClientExecutor.ExecuteAsync(AcquireTokenCommonParameters commonParameters, AcquireTokenWithDeviceCodeParameters deviceCodeParameters, CancellationToken cancellationToken)
   at Program.<Main>$(String[] args) in /home/adrian/azure/Program.cs:line 16
   at Program.<Main>(String[] args)
        StatusCode: 400

According to this documentation, the device code flow can be reproduced with this script:

TENANT_ID='common'
CLIENT_ID='475c75f3-9fdc-4d23-8956-104342a43740'

output=$(
  curl -s https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/devicecode \
  -X POST \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d "client_id=${CLIENT_ID}&scope=user.read%20openid%20profile"
)

echo "URL: $(jq -r '.verification_uri' <<<$output)"
echo "CODE: $(jq -r '.user_code' <<<$output)"

read

output=$(
  curl -s https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/token \
  -X POST \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d "grant_type=urn:ietf:params:oauth:grant-type:device_code&client_id=${CLIENT_ID}&device_code=$(jq -r '.device_code' <<<$output)"
)

curl -s https://graph.microsoft.com/v1.0/me \
-H "Authorization: Bearer $(jq -r '.access_token' <<<$output)" | jq

However, for some reason when I execute the script I don't get any errors. Why?

EDIT: I thought I was using the .default scope in the script too, my bad. This is the updated code, which now returns yet another different error:

TENANT_ID='common'
CLIENT_ID='475c75f3-9fdc-4d23-8956-104342a43740'

output=$(
  curl -s https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/devicecode \
  -X POST \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d "client_id=${CLIENT_ID}&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default"
)

echo "URL: $(jq -r '.verification_uri' <<<$output)"
echo "CODE: $(jq -r '.user_code' <<<$output)"

read

curl -s https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/token \
-X POST \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d "grant_type=urn:ietf:params:oauth:grant-type:device_code&client_id=${CLIENT_ID}&device_code=$(jq -r '.device_code' <<<$output)"

and this is the error I get:

{
  "error": "invalid_scope",
  "error_description": "AADSTS70011: The provided value for the input parameter 'scope' is not valid. One or more scopes in 'https://graph.microsoft.com/.default' are not compatible with each other.\r\nTrace ID: 9d5809b7-32ad-4c18-a8d8-4ac49a439100\r\nCorrelation ID: eb10447d-fce6-4a33-b669-c62924f4e08a\r\nTimestamp: 2022-06-12 09:59:54Z",
  "error_codes": [
    70011
  ],
  "timestamp": "2022-06-12 09:59:54Z",
  "trace_id": "9d5809b7-32ad-4c18-a8d8-4ac49a439100",
  "correlation_id": "eb10447d-fce6-4a33-b669-c62924f4e08a"
}
Adrian
  • 1,558
  • 1
  • 13
  • 31
  • The error message is pretty clear tho: One or more scopes in 'https://graph.microsoft.com/.default offline_access profile openid' are not compatible with each other.. – Thomas Jun 12 '22 at 09:11
  • what should be the scope of the token ? – Thomas Jun 12 '22 at 09:11
  • Yes but the thing is: Why am I getting the error message only in the C# code and not in the bash script when both do essentially the same? – Adrian Jun 12 '22 at 09:13
  • in the bash script, there is no https://graph.microsoft.com/.default scope. – Thomas Jun 12 '22 at 09:47
  • you could just leave that empty: `string[] scopes = new string[0];` – Thomas Jun 12 '22 at 09:48
  • @Thomas I did that and now the error I get `Exception of type 'Microsoft.Fast.Profile.Core.Exception.ProfileAccessDeniedException' was thrown.`. Shouldn't `.default` take automatically the correct permissions that are configured in "API permissions" in the app registration in Azure AD? – Adrian Jun 12 '22 at 10:06
  • @Thomas you were right about the script, my bad. I edited it properly and now I get an error message saying `One or more scopes in 'https://graph.microsoft.com/.default' are not compatible with each other.`. There is only one scope now, `.default`, and the error message is complaining that some scopes are not compatible with each other. How can this be even possible with just one scope? – Adrian Jun 12 '22 at 10:08
  • what are the MS graph permissions you like to get ? if you combine them with `offline_access profile openid` you need to explicitely specify them one by one, the `/.default` won't work. – Thomas Jun 12 '22 at 10:26
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/245529/discussion-between-adrian-and-thomas). – Adrian Jun 12 '22 at 15:10

0 Answers0