Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to request an Azure bearer token properly or why does it ask me to send a "scope" parameter?

Situation:

I have a WPF application that have to call an http-trigger function which is secured via Azure Active Directory. While trying to retrieve a bearer token for further calls I get following response (no matter if I do it via postman or code):

AADSTS90014: The required field 'scope' is missing

What I've done:

I read ton of different articles and blog posts explaining how to secure an http-trigger function with Azure AD and retrieve a bearer token via rest request. Following one of those articles which I thought fits best to my needs I created the full setup of azure function app, azure function, azure AD configuration and app registrations.

After that I just wanted to use the azure function by sending the bearer token and some other parameters and get the result but I got stuck in retrieving the bearer token.

Code (just in case):

var restClient = new RestClient("https://login.microsoftonline.com/{myTenant}/oauth2/v2.0/token");
var restRequest = new RestRequest(Method.POST);
restRequest.AddHeader("content-type", "application/x-www-form-urlencoded");
restRequest.AddParameter("grant_type", "client_credentials", ParameterType.GetOrPost);
restRequest.AddParameter("client_id", "{app id from azure ad app}", ParameterType.GetOrPost);
restRequest.AddParameter("client_secret", "{generated secret}", ParameterType.GetOrPost);
restRequest.AddParameter("ressource", "https://{somefunctionname}.azurewebsites.net", ParameterType.GetOrPost);
var restResponse = restClient.Execute(restRequest);

Postman body parameters (x-www-form-urlencoded):

grant_type = "client_credentials"

client_id = {app id from azure ad app}

client_secret = {generated secret}

ressource = "https://somefunctionname.azurewebsites.net"

and the Url I use to get the token:

https://login.microsoftonline.com/{myTenant}/oauth2/v2.0/token

My question:

So having a detailed look on the situation I have two major questions:

  1. Why does the authentication service expects a "scope" parameter in my case (is there something wrong in my setup or in my rest request)?
  2. Which scope value to send in case I have to send one?
like image 969
rekcul Avatar asked Dec 03 '22 18:12

rekcul


2 Answers

According to the information you provided, I think you want to use Azure AD v2.0 to access the function protected by Azure AD. If so, since you use Azure AD v2.0, you need to update resource to scope. And the vaule of scope should be ```{app id URI}/.default. For more details, please refer to OAuth 2.0 client credentials flow. enter image description here

Regarding how to get the access token, please refer to the following steps.

  1. Register a client to access web api

    a. Register a new Azure AD application

    enter image description here enter image description here

    b. configure permissions enter image description here

    c. Create a new secret enter image description here

    d. get the app id url enter image description here

  2. Code

 var client = new RestClient("https://login.microsoftonline.com/<your tenant>/oauth2/v2.0/token");
            var request = new RestRequest(Method.POST);
            request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
            request.AddParameter("grant_type", "client_credentials", ParameterType.GetOrPost);
            request.AddParameter("client_id", "your app id", ParameterType.GetOrPost);
            request.AddParameter("client_secret", "your app secret", ParameterType.GetOrPost);
            request.AddParameter("scope", "<your app id url>/.default", ParameterType.GetOrPost);
            IRestResponse response = client.Execute(request);

Result: enter image description here enter image description here

like image 193
Jim Xu Avatar answered Dec 27 '22 15:12

Jim Xu


As the above answer mentioned for azure AD v2 you dont get a token against a resource but a scope. Either change your authority to https://login.microsoftonline.com/{myTenant}/oauth2/token then you can use the v1 endpoint and can get the token against your resource

otherwise you either use the default scope as mentioned in the above answer or you can go the the azure portal and go to the app registration page and navigate to the Expose an API section and then check if any scope already exists you can use that, if not create one

Also make sure https://{somefunctionname}.azurewebsites.net is your app id URI

like image 22
biswpo Avatar answered Dec 27 '22 15:12

biswpo