Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
06a744b
Initial Commit
tnorling May 15, 2020
f6fefcd
Create clientInfo from idToken
tnorling May 15, 2020
69e40cb
Merge branch 'cloud-discovery' of https://github.com/AzureAD/microsof…
tnorling May 27, 2020
56fdfdd
Update default type
tnorling May 27, 2020
10335de
Update Sample Readmes
tnorling May 27, 2020
520a465
Update package name for sample
tnorling May 27, 2020
c2ccdec
Merge branch 'cloud-discovery' of https://github.com/AzureAD/microsof…
tnorling Jun 3, 2020
00873a3
Merge branch 'dev' of https://github.com/AzureAD/microsoft-authentica…
tnorling Jun 3, 2020
93549a4
Strip Policy from UID
tnorling Jun 4, 2020
ccb09e7
Update policy strip logic
tnorling Jun 4, 2020
d8862d5
Sample
tnorling Jun 4, 2020
35ad895
Update with lab app registration
tnorling Jun 5, 2020
167ca67
Merge branch 'dev' of https://github.com/AzureAD/microsoft-authentica…
tnorling Jun 15, 2020
47d0a87
Update AuthorityType logic
tnorling Jun 15, 2020
336fc2a
Remove sample
tnorling Jun 15, 2020
c88a12e
Move isAdfs to Authority class
tnorling Jun 15, 2020
661f000
Unit tests
tnorling Jun 15, 2020
3b9c058
Add tests
tnorling Jun 16, 2020
5197bc4
Add upn as backup for username
tnorling Jun 16, 2020
76b1685
Revert "Add upn as backup for username"
tnorling Jun 16, 2020
c969187
Add upn as backup for username
tnorling Jun 16, 2020
c91e0f0
Merge branch 'dev' into b2c-multiple-policies
tnorling Jun 16, 2020
456ba37
Remove samples, will be added in different PR
tnorling Jun 16, 2020
5a5472b
Address Feedback
tnorling Jun 16, 2020
5398cca
Update to ternary
tnorling Jun 16, 2020
dfa6f5d
Update lib/msal-core/src/ClientInfo.ts
tnorling Jun 17, 2020
6114764
Merge branch 'msal-core-adfs' of https://github.com/AzureAD/microsoft…
tnorling Jun 17, 2020
a283256
Add sample + E2E
tnorling Jun 17, 2020
afd59f0
Update testRunner and LabClient
tnorling Jun 17, 2020
9b29939
Merge branch 'dev' into msal-core-adfs
tnorling Jun 17, 2020
4a6d1d3
Merge branch 'msal-core-adfs' of https://github.com/AzureAD/microsoft…
tnorling Jun 17, 2020
85a990a
Add readme to sample
tnorling Jun 22, 2020
c8c7a1e
Update server port
tnorling Jun 23, 2020
ab12b92
Update samples/VanillaJSTestApp/app/adfs/Readme.md
tnorling Jun 23, 2020
88c9132
Addressing feedback
tnorling Jun 24, 2020
6a962d5
Merge branch 'adfs-sample' of https://github.com/AzureAD/microsoft-au…
tnorling Jun 24, 2020
c1b8d1a
Merge branch 'dev' of https://github.com/AzureAD/microsoft-authentica…
tnorling Jul 7, 2020
4a664b9
Fix linting
tnorling Jul 7, 2020
176334f
Merge branch 'dev' into msal-core-adfs
tnorling Jul 25, 2020
2201bd3
Merge branch 'dev' of https://github.com/AzureAD/microsoft-authentica…
tnorling Aug 10, 2020
f674871
Cleanup
tnorling Aug 10, 2020
b861e2d
Update FAQ
tnorling Aug 10, 2020
553a623
Merge branch 'dev' into msal-core-adfs
tnorling Aug 11, 2020
63bac81
Change files
tnorling Aug 12, 2020
c08165c
Merge branch 'dev' of https://github.com/AzureAD/microsoft-authentica…
tnorling Aug 12, 2020
91dc3ac
Merge branch 'dev' of https://github.com/AzureAD/microsoft-authentica…
tnorling Aug 12, 2020
b082274
Tests passing
tnorling Aug 12, 2020
d5548a1
Change files
tnorling Aug 12, 2020
c400722
Merge branch 'dev' into msal-core-adfs
tnorling Aug 17, 2020
5f10555
Merge pull request #1668 from AzureAD/msal-core-adfs
tnorling Aug 17, 2020
30f7b66
Merge branch '1.4.0-release' of https://github.com/AzureAD/microsoft-…
tnorling Aug 17, 2020
603c101
[msal-core] Fix response type configuration by basing it mainly on sc…
Aug 17, 2020
cefd4ca
Merge branch '1.4.0-release' of https://github.com/AzureAD/microsoft-…
tnorling Aug 17, 2020
3782c0b
Update test
tnorling Aug 17, 2020
364621d
Update samples/VanillaJSTestApp/app/adfs/Readme.md
tnorling Aug 17, 2020
4fcdb41
Update welcome message
tnorling Aug 17, 2020
f5378d3
Merge branch 'adfs-sample' of https://github.com/AzureAD/microsoft-au…
tnorling Aug 17, 2020
c4fc53c
Add federationProvider to LabClient
tnorling Aug 17, 2020
2e2116d
Merge pull request #1791 from AzureAD/adfs-sample
tnorling Aug 18, 2020
065b8d8
Fix heading
tnorling Aug 18, 2020
83746d1
Update lib/msal-core/docs/FAQ.md
tnorling Aug 18, 2020
2be68fb
Merge branch '1.4.0-release' of https://github.com/AzureAD/microsoft-…
tnorling Aug 18, 2020
148fa9b
Address Feedback
tnorling Aug 18, 2020
9c011d5
Tests passing
tnorling Aug 19, 2020
f10c797
Merge pull request #1757 from AzureAD/b2c-multiple-policies
tnorling Aug 19, 2020
649a731
[msal-core] Fix invalid state issue by removing second layer of URL d…
Aug 20, 2020
c45ccd5
Merge branch 'dev' of https://github.com/AzureAD/microsoft-authentica…
tnorling Aug 24, 2020
efcfbb2
Update SRI hashes
tnorling Aug 24, 2020
2985cc2
Merge branch 'dev' into 1.4.0-release
tnorling Aug 24, 2020
552edd5
Merge branch 'dev' into 1.4.0-release
tnorling Aug 24, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "minor",
"comment": "Enables idToken acquisition in acquireToken API calls through the use of OIDC scopes by redefining the way response_type is determined. (PR #2022)",
"packageName": "msal",
"email": "[email protected]",
"dependentChangeType": "patch",
"date": "2020-08-10T18:48:42.205Z"
}
85 changes: 85 additions & 0 deletions lib/msal-core/docs/response-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Response Types

> :warning: This document only applies to `[email protected]` which implements the Implicit Flow Grant type. For the Authorization Code Flow Grant type, please use the [msal-browser](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-browser) library.

## Quick Reference

> This section provides a summary of the main points this document addresses, without getting into any details. If you need more clarity or information about the functionality and behavior of Response Types in `[email protected]`, please read the rest of this document.

The key takeaways of the way `[email protected]` determines and handles `Response Types` are:

1. `loginRedirect`, `loginPopup` and `ssoSilent` will always return ID tokens and have a `response_type` of `id_token`.
2. `acquireToken` requests will always return an ID token if `openid` or `profile` are included in the request scopes.
3. `acquireToken` requests will always return an access token if a `resource scope` is requested.

If you're interested in learning more about the reasoning and implications around the way response types are determined and what they are used for, please read the rest of this document.

## Definition and Types
The `[email protected]` library, in compliance of both the OAuth 2.0 protocol specification as well as the OpenID Connect specification, defines and supports three different `response types`:

* token
* id_token
* id_token token

The **`[email protected]` library does not support the `code` response type because it does not implement the Authorization Code grant. If you are looking to implement the Authorization Code grant type, consider the [msal-browser](https://github.com/AzureAD/microsoft-authentication-library-for-js/tree/dev/lib/msal-browser) library.**

The listed response types are possible values for the `response_type` parameter in OAuth 2.0 HTTP requests. Assuming a valid request, this parameter determines what kind of token is sent back by the Secure Token Service (STS) that `[email protected]` requests access and ID tokens from.

| Response Type | Specification that defines it | Expected token type from successful request | Action |
| ------------- | ----------------------------- | ------------------------------------------- | ------ |
| `token` |[OAuth 2.0](https://tools.ietf.org/html/rfc6749#section-3.1.1) | Access Token | Authorization |
| `id_token`| [OpenID Connect](https://openid.net/specs/openid-connect-core-1_0.html#Authentication) | ID Token | Authentication |
|`id_token token`| [OpenID Connect](https://openid.net/specs/openid-connect-core-1_0.html#Authentication) | Access Token and ID token | Authorization & Authentication |

**Note: Given that `[email protected]` uses the OAuth 2.0 Implicit Flow exclusively, which leverages URL fragments for token reception, it is important to be mindful of URL length limitations. Browsers like IE impose restrictions on the length of URLs, so getting both an access token and ID token in the same URL may cause unexpected or incorrect behavior.**

## Response Type configuration and behavior

The `response_type` attribute presented above cannot be configured directly. However, it is important to understand the way `[email protected]` determines which response type is set and, therefore, what kind of token the developer can expect for each scenario. The factors that come into consideration when setting the request's `response_type` parameter are the following:

1. The `[email protected]` API called
2. Whether the account passed into the request configuration matches the account in the MSAL cache
3. The contents of the `scopes` array in the Authorization Request Configuration object. For more information on `scopes` configuration, please consult the [Scopes](/docs/scopes.md) document.

**Important note: Login APIs will always set `response_type=id_token`, given that they are designed to perform user login (authentication).**

Login APIs include:

* loginRedirect
* loginPopup
* ssoSilent

In other words, whenever you call `loginRedirect` or `loginPopup` to sign a user in, you should expect to receive an ID token if the request is successful.

The following section contains quick reference tables for both `login` and `acquireToken` APIs that accurately map the request configuration to the resulting response type.

## Quick reference tables

### Login APIs

Applies to: `loginRedirect`, `loginPopup`, `ssoSilent`

| Input scopes | Account passed in | Response Type Result |
| ----------------- | ------------ | -------------------- |
| Any case | Any case | `id_token`|

### Acquire Token APIs

Applies to: `acquireTokenRedirect`, `acquireTokenPopup`, `acquireTokenSilent`

* *OIDC scopes: any combination of `openid` and/or `profile`*
* *OIDC scopes only: Same as OIDC scopes but with no other scopes in the array*

| Input scopes | Account passed in | Response Type Result |
| ----------------- | ------------ | -------------------- |
| ClientId as only scope | Any case | `id_token`|
| OIDC scopes only | Any case | `id_token`|
| ClientId with OIDC scopes | Any case | `id_token token` |
| Resource scope(s) with OIDC scopes (technically the same as above) | Any case | `id_token token` |
| Resource scope(s) only | Matches cached account object | `token` |
| Resource scope(s) and ClientId | Matches cached account object | `token` |
| Resource scope(s) only | Doesn't match cached account object | `id_token token` |

**Note: As seen in the table above, when ClientId is not the only scope, it is assumed to be a resource scope with no special behavior.**


105 changes: 105 additions & 0 deletions lib/msal-core/docs/scopes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Scope Configuration and Behavior

## Contents
* [Quick Reference](#quick-reference)
* [Scopes](#scopes)
* [Scope Functions](#scope-functions)
* [Scope Types](#scope-types)
* [Resource scopes for Authorization](#resource-scopes-for-authorization)
* [OpenID Connect Scopes for Authentication](#openid-connect-scopes-for-authentication)
* [Scopes Behavior](#scopes-behavior)
* [Default Scopes in Authorization Requests](#default-scopes-on-authorization-requests)
* [Special OIDC Scopes behavior cases](#special-oidc-scopes-behavior-cases)

## Quick Reference

> This section provides a summary of the main points this document addresses, without getting into any details. If you need more clarity or information about the functionality and behavior of Scopes in `[email protected]`, please read the rest of this document.

The key takeaways of the way `[email protected]` handles and uses scopes are:

1. The `[email protected]` library will always append `openid` and `profile` as scopes in every outgoing request.
2. Setting the value of the application's ClientId as the only scope will result in it being replaced by `openid` and `profile` and an ID Token being returned

If you're interested in learning more about the reasoning and implications around these two specific behaviors, please read on.



## Scopes

Microsoft identity platform access tokens, which `[email protected]` acquires in compliance with the OAuth 2.0 protocol specification, are issued to applications as proof of authorization on behalf of a user for a certain resource. The issuing of these tokens is not only specific to an `audience`, or application, but also specific to a set of `scopes` or permissions.

### Scope Functions

#### Function of scopes in OAuth 2.0

The main function of the `scopes` configuration, per the [OAuth 2.0 Access Token Scope Reference](https://tools.ietf.org/html/rfc6749#section-3.3), is to determine the permissions for which an application requests `authorization` on behalf of the user. Said function is both supported and covered by `[email protected]` and the Microsoft identity platform in general. For more information on the regular function of authorization scopes, please consult the official [Microsoft identity platform documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent).

#### Special use of scopes in [email protected]

In addition to the global concept and use of `scopes`, it is important to understand that `[email protected]` gives scopes a special use that adds to the importance of their configuration. In short, `[email protected]` allows developers to leverage certain scopes in order to determine the `response_type` for the final request. For more information on the way the scopes configuration determines the `response_type` parameter, please refer to the [Response Types Document](/docs/response-types.md).



## Scope Types

As far as `[email protected]` is concerned, there are two main types of `scopes` that can be configured in a token request.

### Resource scopes for Authorization

`Resource scopes` are the main type of access token `scopes` that `[email protected]` deals with. These are the `scopes` that represent permissions for specific actions against a particular resource. In other words, these `scopes` determine what actions and resources the requesting application is `authorized` to access on behalf of the user. The following are some examples of the `resource scopes` that the [Microsoft Graph](https://docs.microsoft.com/en-us/graph/overview) service can authorize an application for given the user's consent:

* `User.Read`: Authorizes the application to read a user's account details.
* `Mail.Read`: Authorizes the application to read a user's e-mails.

Including resource scopes in the configuration for a token request doesn't always mean that the response will include an **access token** for said scopes. In the specific case of `[email protected]`'s `login` APIs (`loginRedirect`, `loginPopup`), adding resource scopes may allow the user to **constent** to said scopes ahead of time, but successful `login` API calls always result in an **ID Token, not an access token**, being returned.

### OpenID Connect Scopes for Authentication

`OpenID Connect (OIDC) scopes` are a specific set of scopes that can be added to requests when `authenticating` a user. In most cases, `OIDC scopes` are added to configure the claims included in an ID Token ([OIDC Reference](https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims) / [Microsoft Docs](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes)). Some services, such as the Secure Token Service that `[email protected]` acquires tokens from, also use OIDC scopes in their internal logic. For this reason, it is important to understand and pay attention to the special behavior `[email protected]` has around OIDC scopes (described in the [next section](#default-scopes-on-authorization-requests)).

The OIDC scopes that `[email protected]` pays particular attention to are outlined in the table below.

| OIDC Scope | Required by OIDC Specification | Function | OIDC Reference | Microsoft Docs |
| ---------- | ------------------------------ | -------- | -------------- | -------------- |
| `openid`| Mandatory | Main `OIDC scope` that indicates a request for `authentication` [per the OIDC specification](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). In AAD requests, this is the scope that prompts the "Sign in" permission that a user can consent to. | [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest)| [Permissions and consent in the Microsoft identity platform endpoint](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-protocols-oidc#send-the-sign-in-request)|
|`profile`| Optional | Used for ID Token `claims` configuration. Adds the end-user's default profile information as a claim to the ID token returned | [Requesting Claims using Scopes Values](https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims) | [OpenID Permissions](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent)|


## Scopes Behavior

### Default Scopes on Authorization Requests

Understanding how `OIDC scopes` configure the claims included in an authentication response's ID Token is important when using `[email protected]` to acquire said ID Tokens. However, there is an important note to be made on how the `openid` and `profile` scopes are added by `[email protected]` to all server requests by default that does not directly relate to the OpenID Connect specification.

Like previously mentioned, the Secure Token Service that `[email protected]` requests access and ID tokens from also makes use of the `openid` and `profile` scopes. Specifically, the STS expects these two scopes in order to configure and provide the `client_info` parameter in authorization and authentication responses. The `[email protected]` library depends on the contents of `client_info` in order to successfully cache tokens and, therefore, provide silent token acquisition as a feature.

**For this reason, whether or not the developer adds the `openid` or `profile` scopes to their request configuration, `[email protected]` will make sure they are included before sending the request to the STS.**

### Special OIDC Scopes behavior cases

The following is a list of practical implications and examples of the default scope behavior described in the previous section.

- If the scopes array does not include either `openid` or `profile`, whichever is missing (could be both) will be added to the scopes array by default before the request is sent out.

Examples:

```js
{ scopes: ['User.Read'] } // becomes { scopes: ['User.Read', 'openid', 'profile'] } before the request is sent

{ scopes: ['User.Read', 'openid'] } // becomes { scopes ['User.Read', 'openid', 'profile']} before the request is sent

{ scopes: ['User.Read', 'profile'] } // becomes { scopes ['User.Read', 'profile', 'openid']} before the request is sent

{ scopes: ['http://contoso.com/scope'] } // becomes { scopes ['http://contoso.com/scope', 'openid', 'profile'] }
```
- ClientId is removed from the scopes array when it is the only scope in the configuration. If it is not the only scope, it is treated as a resource scope and will be sent in the final server request.

Examples:

```js
{ scopes: ['YOUR_CLIENT_ID'] } // becomes { scopes: ['openid', 'profile'] } before the request is sent (ClientId is spliced out)

{ scopes: ['YOUR_CLIENT_ID', 'User.Read'] } // becomes { scopes ['YOUR_CLIENT_ID', 'User.Read', 'openid', 'profile']} before the request is sent (ClientId is treated as resource scope and therefore not spliced out)

{ scopes: ['YOUR_CLIENT_ID', 'openid'] } // becomes { scopes ['YOUR_CLIENT_ID', 'openid', 'profile']} before the request is sent
```
Loading