Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Microsoft Identity Platform aka Azure ActiveDirectory V2 #649

Merged
merged 15 commits into from
Aug 20, 2020

Conversation

darrelmiller
Copy link
Contributor

@darrelmiller darrelmiller commented Jul 29, 2020

Following in the footsteps of the excellent aadToken system variable, this PR adds an aadV2Token that makes it easy to use the OAuth2 compliant AzureAD V2 endpoints. I specifically created this to make it easy to call the Microsoft Graph API.

###  Minimal call
GET https://graph.microsoft.com/v1.0/me
Authorization: {{$aadV2Token scopes:User.Read}}

### Call providing explicit tenantId
GET https://graph.microsoft.com/v1.0/me
Authorization: {{$aadV2Token tenantId:8cea02ec-9788-4bac-a19b-3e782a3e9bb0}}

### Call providing scopes required to make the call
GET https://graph.microsoft.com/v1.0/users
Authorization: {{$aadV2Token scopes:User.Read.All }}

### AppOnly calls with clientId and secret in the environment variables
GET https://graph.microsoft.com/v1.0/users/[email protected]
Authorization: {{$aadV2Token appOnly}}

### Call providing scopes required to make the call bring your own clientId 
### if you don't want to use the default
GET https://graph.microsoft.com/v1.0/users
Authorization: {{$aadV2Token scopes:User.Read.All clientId:5b98077a-25fd-4bcd-9ae6-d2fbf42c8054}}

Feedback welcome. This is my first time writing any non-trivial amount of TypeScript so there may be some horrible C# looking things in there.

@darrelmiller
Copy link
Contributor Author

Apparently I have a lot of linting issues to fix :-)

src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
README.md Show resolved Hide resolved
src/utils/aadV2TokenProvider.ts Outdated Show resolved Hide resolved
@darrelmiller darrelmiller changed the title Add support for Azure ActiveDirectory V2 Authentication Add support for Microsoft Identity Platform aka Azure ActiveDirectory V2 Aug 15, 2020
@Huachao Huachao linked an issue Aug 20, 2020 that may be closed by this pull request
@Huachao Huachao merged commit 064c1d7 into Huachao:master Aug 20, 2020
@Huachao
Copy link
Owner

Huachao commented Aug 20, 2020

@darrelmiller merged, thanks 😄

@Huachao
Copy link
Owner

Huachao commented Aug 30, 2020

@darrelmiller @luismanez @henriksen @dannmartens @rgregg @marcoscheel you can try the latest version 0.24.2 to verify it

@dannmartens
Copy link

dannmartens commented Aug 30, 2020

I've tried it (the example calls provided, verbatim), after upgrading to v0.24.2 and I can't get it to work, unfortunately.

I've tested with a REST client environment, and with direct parameters between double brackets. At no point did I get a user prompt. Same for "appOnly," with the client secret set.

I'm using parameter names, such as "tenantId, clientId and clientSecret." For the tenantId, I am using the actual domain.

I checked the source code and found the environment variables are "aadV2TenantId, aadV2ClientId and aadV2ClientSecret," but it made no difference when I used those.

All the responses look like this:

HTTP/1.1 401 Unauthorized
Cache-Control: private
Content-Type: application/json
request-id: 815815a4-1942-4514-83e3-603a26bc781c
client-request-id: 815815a4-1942-4514-83e3-603a26bc781c
x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"North Europe","Slice":"SliceC","Ring":"4","ScaleUnit":"001","RoleInstance":"AGSFE_IN_9"}}
WWW-Authenticate: Bearer realm="", authorization_uri="https://login.microsoftonline.com/common/oauth2/authorize", client_id="00000003-0000-0000-c000-000000000000"
Strict-Transport-Security: max-age=31536000
Date: Sun, 30 Aug 2020 11:56:08 GMT
Connection: close
Content-Length: 265

{
  "error": {
    "code": "InvalidAuthenticationToken",
    "message": "CompactToken parsing failed with error code: 80049217",
    "innerError": {
      "date": "2020-08-30T11:56:08",
      "request-id": "815815a4-1942-4514-83e3-603a26bc781c"
    }
  }
}

If the returned client Id is something to go by, it seems my parameter values are not getting picked up.

I might be doing something wrong, but I am at a loss here. Can you document the actual parameter name combos, which are known to work?

@Huachao
Copy link
Owner

Huachao commented Aug 30, 2020

@darrelmiller could you please take a look at @dannmartens issue?

@henriksen
Copy link

I got it working, but I had to ask with a scope one time first. The minimal call did not work at first. I would get a permission denied error. But after using a scope once and consenting to it, then it works fine, both with and without the scope.

@dannmartens
Copy link

I can't get it to work with "scopes" set either. Can you copy your working example, here? I'll give that a try.

Additionally, I don't think a scope, the kind we use to address a protected proprietary API, such as api://8b97218d-8c1a-4a91-972f-54884baa0bfb/.default is parsed properly. I get an error:
image

I currently use the two-step method, and that always works.

# @name auth	
POST https://login.microsoftonline.com/{{tenant_id}}/oauth2/v2.0/token HTTP/1.1
Content-type: application/x-www-form-urlencoded	

# See environment settings in .vscode/settings.json
grant_type=password
&client_id={{client_id}}
&client_secret={{client_secret}}
&scope={{scope}}
&username={{username}}
&password={{password}}

### Actual call
GET {{base_url}}/api/v1/test HTTP/1.1
Accept: application/json
Authorization: Bearer {{auth.response.body.access_token}}

@darrelmiller
Copy link
Contributor Author

darrelmiller commented Aug 31, 2020

@henriksen By default all apps created in Azure AD are given consent to User.Read scope from Microsoft Graph by default. Accessing anything else will require providing a scope parameter to trigger the consent dialog. Once you have consented the application to that scope, you don't need the scope parameter anymore.

@dannmartens Try using api://8b97218d-8c1a-4a91-972f-54884baa0bfb as the aadV2AppUri in an environment. That is the prefix to ensure your scopes are globally unique. Because you are using appOnly, the .default scope is used, but I add that on in when creating the request to the Auth server. The scopes provided as parameters to the token only work for delegated access.

Probably would be a good idea if I make the appUri value a bit more tolerant because everyone makes a mistake on this. I also had some issues with whether the final slash should be percent encoded.
https://github.com/Huachao/vscode-restclient/blob/master/src/utils/aadV2TokenProvider.ts#L113-L115

@darrelmiller
Copy link
Contributor Author

@henriksen I think I may have figured out why the call without the scope didn't work. Ignore everything I said about getting User.Read by default. You don't get that default because I did another workaround to avoid a different AADV2 bug.

@darrelmiller
Copy link
Contributor Author

And sadly, scopes need to be capitalized properly. e.g. User.Read. I will create fix for that.

@dannmartens
Copy link

@darrelmiller Thanks for looking into this!

I would like to solicit for your opinion: do you think it is necessary to have the parameter names prefixed with "aadV2?" It seems to complicate configuration more than is necessary. Are there any cases where this would cause naming issues with the original AADToken?

Typical configuration values I use for the different IAM flows are:

  • authority
  • tenantId
  • clientId
  • clientSecret
  • applicationIdUri
  • scopes
  • endpoint (usually hard-coded)

Values in scopes can be:

  • User.Read.All,Group.Read.All
  • api://8b97218d-8c1a-4a91-972f-54884baa0bfb/.default
  • api://8b97218d-8c1a-4a91-972f-54884baa0bfb/Resource.Read.All

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

How to query the microsoft graph thanks to rest client
4 participants