|
1 | 1 | ---
|
2 |
| -title: Requesting access tokens in Azure Active Directory B2C | Microsoft Docs |
3 |
| -description: This article will show you how to setup a client application and acquire an access token. |
| 2 | +title: Request an access token - Azure Active Directory B2C | Microsoft Docs |
| 3 | +description: Learn how to request an access token from Azure Active Directory B2C. |
4 | 4 | services: active-directory-b2c
|
5 | 5 | author: davidmu1
|
6 | 6 | manager: daveba
|
7 | 7 |
|
8 | 8 | ms.service: active-directory
|
9 | 9 | ms.workload: identity
|
10 | 10 | ms.topic: conceptual
|
11 |
| -ms.date: 08/09/2017 |
| 11 | +ms.date: 04/16/2019 |
12 | 12 | ms.author: davidmu
|
13 | 13 | ms.subservice: B2C
|
14 | 14 |
|
15 | 15 | ---
|
16 |
| -# Azure AD B2C: Requesting access tokens |
| 16 | +# Request an access token in Azure Active Directory B2C |
17 | 17 |
|
18 |
| -An access token (denoted as **access\_token** in the responses from Azure AD B2C) is a form of security token that a client can use to access resources that are secured by an [authorization server](active-directory-b2c-reference-protocols.md), such as a web API. Access tokens are represented as [JWTs](active-directory-b2c-reference-tokens.md) and contain information about the intended resource server and the granted permissions to the server. When calling the resource server, the access token must be present in the HTTP request. |
| 18 | +An *access token* contains claims that you can use in Azure Active Directory (Azure AD) B2C to identify the granted permissions to your APIs. When calling a resource server, an access token must be present in the HTTP request. An access token is denoted as **access_token** in the responses from Azure AD B2C. |
19 | 19 |
|
20 |
| -This article discusses how to configure a client application and web API in order to obtain an **access\_token**. |
| 20 | +This article shows you how to request an access token for a web application and web API. For more information about tokens in Azure AD B2C, see the [overview of tokens in Azure Active Directory B2C](active-directory-b2c-reference-tokens.md). |
21 | 21 |
|
22 | 22 | > [!NOTE]
|
23 |
| -> **Web API chains (On-Behalf-Of) is not supported by Azure AD B2C.** |
24 |
| -> |
25 |
| -> Many architectures include a web API that needs to call another downstream web API, both secured by Azure AD B2C. This scenario is common in native clients that have a web API back end, which in turn calls a Microsoft online service such as the Azure AD Graph API. |
26 |
| -> |
27 |
| -> This chained web API scenario can be supported by using the OAuth 2.0 JWT Bearer Credential grant, otherwise known as the On-Behalf-Of flow. However, the On-Behalf-Of flow is not currently implemented in Azure AD B2C. |
| 23 | +> **Web API chains (On-Behalf-Of) is not supported by Azure AD B2C.** - Many architectures include a web API that needs to call another downstream web API, both secured by Azure AD B2C. This scenario is common in clients that have a web API back end, which in turn calls a another service. This chained web API scenario can be supported by using the OAuth 2.0 JWT Bearer Credential grant, otherwise known as the On-Behalf-Of flow. However, the On-Behalf-Of flow is not currently implemented in Azure AD B2C. |
28 | 24 |
|
29 |
| -## Register a web API and publish permissions |
| 25 | +## Prerequisites |
30 | 26 |
|
31 |
| -Before requesting an access token, you first need to register a web API and publish permissions (scopes) that can be granted to the client application. |
| 27 | +- [Create a user flow](tutorial-create-user-flows.md) to enable users to sign up and sign in to your application. |
| 28 | +- If you haven't already done so, [add a web API application to your Azure Active Directory B2C tenant](add-web-application.md). |
32 | 29 |
|
33 |
| -### Register a web API |
| 30 | +## Scopes |
34 | 31 |
|
35 |
| -1. On the Azure AD B2C features menu on the Azure portal, click **Applications**. |
36 |
| -2. Click **+Add** at the top of the menu. |
37 |
| -3. Enter a **Name** for the application that will describe your application to consumers. For example, you could enter "Contoso API". |
38 |
| -4. Toggle the **Include web app / web API** switch to **Yes**. |
39 |
| -5. Enter an arbitrary value for the **Reply URLs**. For example, enter `https://localhost:44316/`. The value does not matter since an API should not be receiving the token directly from Azure AD B2C. |
40 |
| -6. Enter an **App ID URI**. This is the identifier used for your web API. For example, enter 'notes' in the box. The **App ID URI** would then be `https://{tenantName}.onmicrosoft.com/notes`. |
41 |
| -7. Click **Create** to register your application. |
42 |
| -8. Click the application that you just created and copy down the globally unique **Application Client ID** that you'll use later in your code. |
| 32 | +Scopes provide a way to manage permissions to protected resources. When an access token is requested, the client application needs to specify the desired permissions in the **scope** parameter of the request. For example, to specify the **Scope Value** of `read` for the API that has the **App ID URI** of `https://contoso.onmicrosoft.com/api`, the scope would be `https://contoso.onmicrosoft.com/api/read`. |
43 | 33 |
|
44 |
| -### Publishing permissions |
| 34 | +Scopes are used by the web API to implement scope-based access control. For example, users of the web API could have both read and write access, or users of the web API might have only read access. To acquire multiple permissions in the same request, you can add multiple entries in the single **scope** parameter of the request, separated by spaces. |
45 | 35 |
|
46 |
| -Scopes, which are analogous to permissions, are necessary when your app is calling an API. Some examples of scopes are "read" or "write". Suppose you want your web or native app to "read" from an API. Your app would call Azure AD B2C and request an access token that gives access to the scope "read". In order for Azure AD B2C to emit such an access token, the app needs to be granted permission to "read" from the specific API. To do this, your API first needs to publish the "read" scope. |
| 36 | +The following example shows scopes decoded in a URL: |
47 | 37 |
|
48 |
| -1. Within the Azure AD B2C **Applications** menu, open the web API application ("Contoso API"). |
49 |
| -2. Click on **Published scopes**. This is where you define the permissions (scopes) that can be granted to other applications. |
50 |
| -3. Add **Scope Values** as necessary (for example, "read"). By default, the "user_impersonation" scope will be defined. You can ignore this if you wish. Enter a description of the scope in the **Scope Name** column. |
51 |
| -4. Click **Save**. |
52 |
| - |
53 |
| -> [!IMPORTANT] |
54 |
| -> The **Scope Name** is the description of the **Scope Value**. When using the scope, make sure to use the **Scope Value**. |
| 38 | +``` |
| 39 | +scope=https://contoso.onmicrosoft.com/api/read openid offline_access |
| 40 | +``` |
55 | 41 |
|
56 |
| -## Grant a native or web app permissions to a web API |
| 42 | +The following example shows scopes encoded in a URL: |
57 | 43 |
|
58 |
| -Once an API is configured to publish scopes, the client application needs to be granted those scopes via the Azure portal. |
| 44 | +``` |
| 45 | +scope=https%3A%2F%2Fcontoso.onmicrosoft.com%2Fapi%2Fread%20openid%20offline_access |
| 46 | +``` |
59 | 47 |
|
60 |
| -1. Navigate to the **Applications** menu in the Azure AD B2C features menu. |
61 |
| -2. Register a client application ([web app](active-directory-b2c-app-registration.md) or [native client](active-directory-b2c-app-registration.md)) if you don’t have one already. If you are following this guide as your starting point, you'll need to register a client application. |
62 |
| -3. Click on **API access**. |
63 |
| -4. Click on **Add**. |
64 |
| -5. Select your web API and the scopes (permissions) you would like to grant. |
65 |
| -6. Click **OK**. |
| 48 | +If you request more scopes than what is granted for your client application, the call succeeds if at least one permission is granted. The **scp** claim in the resulting access token is populated with only the permissions that were successfully granted. The OpenID Connect standard specifies several special scope values. The following scopes represent the permission to access the user’s profile: |
66 | 49 |
|
67 |
| -> [!NOTE] |
68 |
| -> Azure AD B2C does not ask your client application users for their consent. Instead, all consent is provided by the admin, based on the permissions configured between the applications described above. If a permission grant for an application is revoked, all users who were previously able to acquire that permission will no longer be able to do so. |
| 50 | +- **openid** - Requests an ID token. |
| 51 | +- **offline_access** - Requests a refresh token using [Auth Code flows](active-directory-b2c-reference-oauth-code.md). |
69 | 52 |
|
70 |
| -## Requesting a token |
| 53 | +If the **response_type** parameter in an `/authorize` request includes `token`, the **scope** parameter must include at least one resource scope other than `openid` and `offline_access` that will be granted. Otherwise, the `/authorize` request fails. |
71 | 54 |
|
72 |
| -When requesting an access token, the client application needs to specify the desired permissions in the **scope** parameter of the request. For example, to specify the **Scope Value** “read” for the API that has the **App ID URI** of `https://contoso.onmicrosoft.com/notes`, the scope would be `https://contoso.onmicrosoft.com/notes/read`. Below is an example of an authorization code request to the `/authorize` endpoint. |
| 55 | +## Request a token |
73 | 56 |
|
74 |
| -> [!NOTE] |
75 |
| -> Currently, custom domains are not supported along with access tokens. You must use your tenantName.onmicrosoft.com domain in the request URL. |
| 57 | +To request an access token, you need an authorization code. Below is an example of a request to the `/authorize` endpoint for an authorization code. Custom domains are not supported for use with access tokens. Use your tenant-name.onmicrosoft.com domain in the request URL. |
76 | 58 |
|
77 | 59 | In the following example, you replace these values:
|
78 | 60 |
|
79 | 61 | - `<tenant-name>` - The name of your Azure AD B2C tenant.
|
80 | 62 | - `<policy-name>` - The name of your custom policy or user flow.
|
81 |
| -- `<application-ID>` - The application identifier of the client application that you registered. |
| 63 | +- `<application-ID>` - The application identifier of the web application that you registered to support the user flow. |
82 | 64 | - `<redirect-uri>` - The **Redirect URI** that you entered when you registered the client application.
|
83 | 65 |
|
84 | 66 | ```
|
85 |
| -https://<tenant-name>.b2clogin.com/tfp/<tenant-name>.onmicrosoft.com/<policy-name>/oauth2/v2.0/authorize?client_id=<application-ID>&nonce=anyRandomValue&redirect_uri=<redirect_uri>&scope=https%3A%2F%2F<tenant-name>.onmicrosoft.com%2Fnotes%2Fread&response_type=code |
| 67 | +GET https://<tenant-name>.b2clogin.com/tfp/<tenant-name>.onmicrosoft.com/<policy-name>/oauth2/v2.0/authorize? |
| 68 | +client_id=<application-ID> |
| 69 | +&nonce=anyRandomValue |
| 70 | +&redirect_uri=https://jwt.ms |
| 71 | +&scope=https://tenant-name>.onmicrosoft.com/api/read |
| 72 | +&response_type=code |
86 | 73 | ```
|
87 | 74 |
|
88 |
| -To acquire multiple permissions in the same request, you can add multiple entries in the single **scope** parameter, separated by spaces. For example: |
89 |
| - |
90 |
| -URL decoded: |
| 75 | +The response with the authorization code should be similar to this example: |
91 | 76 |
|
92 | 77 | ```
|
93 |
| -scope=https://contoso.onmicrosoft.com/notes/read openid offline_access |
| 78 | +https://jwt.ms/?code=eyJraWQiOiJjcGltY29yZV8wOTI1MjAxNSIsInZlciI6IjEuMC... |
94 | 79 | ```
|
95 | 80 |
|
96 |
| -URL encoded: |
| 81 | +After successfully receiving the authorization code, you can use it to request an access token: |
97 | 82 |
|
98 | 83 | ```
|
99 |
| -scope=https%3A%2F%2Fcontoso.onmicrosoft.com%2Fnotes%2Fread%20openid%20offline_access |
| 84 | +POST <tenant-name>.onmicrosoft.com/oauth2/v2.0/token?p=<policy-name> HTTP/1.1 |
| 85 | +Host: https://<tenant-name>.b2clogin.com |
| 86 | +Content-Type: application/x-www-form-urlencoded |
| 87 | +
|
| 88 | +grant_type=authorization_code |
| 89 | +&client_id=<application-ID> |
| 90 | +&scope=https://<tenant-name>.onmicrosoft.com/api/read |
| 91 | +&code=eyJraWQiOiJjcGltY29yZV8wOTI1MjAxNSIsInZlciI6IjEuMC... |
| 92 | +&redirect_uri=https://jwt.ms |
| 93 | +&client_secret=2hMG2-_:y12n10vwH... |
100 | 94 | ```
|
101 | 95 |
|
102 |
| -You may request more scopes (permissions) for a resource than what is granted for your client application. When this is the case, the call will succeed if at least one permission is granted. The resulting **access\_token** will have its “scp” claim populated with only the permissions that were successfully granted. |
103 |
| - |
104 |
| -> [!NOTE] |
105 |
| -> We do not support requesting permissions against two different web resources in the same request. This kind of request will fail. |
106 |
| -
|
107 |
| -### Special cases |
| 96 | +You should see something similar to the following response: |
108 | 97 |
|
109 |
| -The OpenID Connect standard specifies several special “scope” values. The following special scopes represent the permission to “access the user’s profile”: |
110 |
| - |
111 |
| -* **openid**: This requests an ID token |
112 |
| -* **offline\_access**: This requests a refresh token (using [Auth Code flows](active-directory-b2c-reference-oauth-code.md)). |
113 |
| - |
114 |
| -If the `response_type` parameter in a `/authorize` request includes `token`, the `scope` parameter must include at least one resource scope (other than `openid` and `offline_access`) that will be granted. Otherwise, the `/authorize` request will terminate with a failure. |
115 |
| - |
116 |
| -## The returned token |
117 |
| - |
118 |
| -In a successfully minted **access\_token** (from either the `/authorize` or `/token` endpoint), the following claims will be present: |
119 |
| - |
120 |
| -| Name | Claim | Description | |
121 |
| -| --- | --- | --- | |
122 |
| -|Audience |`aud` |The **application ID** of the single resource that the token grants access to. | |
123 |
| -|Scope |`scp` |The permissions granted to the resource. Multiple granted permissions will be separated by space. | |
124 |
| -|Authorized Party |`azp` |The **application ID** of the client application that initiated the request. | |
| 98 | +``` |
| 99 | +{ |
| 100 | + "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ilg1ZVhrN...", |
| 101 | + "token_type": "Bearer", |
| 102 | + "not_before": 1549647431, |
| 103 | + "expires_in": 3600, |
| 104 | + "expires_on": 1549651031, |
| 105 | + "resource": "f2a76e08-93f2-4350-833c-965c02483b11", |
| 106 | + "profile_info": "eyJ2ZXIiOiIxLjAiLCJ0aWQiOiJjNjRhNGY3ZC0zMDkxLTRjNzMtYTcyMi1hM2YwNjk0Z..." |
| 107 | +} |
| 108 | +``` |
125 | 109 |
|
126 |
| -When your API receives the **access\_token**, it must [validate the token](active-directory-b2c-reference-tokens.md) to prove that the token is authentic and has the correct claims. |
| 110 | +When using https://jwt.ms to examine the access token that was returned, you should see something similar to the following example: |
127 | 111 |
|
128 |
| -We are always open to feedback and suggestions! If you have any difficulties with this topic, please post on Stack Overflow using the tag ['azure-ad-b2c'](https://stackoverflow.com/questions/tagged/azure-ad-b2c). For feature requests, add them to [UserVoice](https://feedback.azure.com/forums/169401-azure-active-directory/category/160596-b2c). |
| 112 | +``` |
| 113 | +{ |
| 114 | + "typ": "JWT", |
| 115 | + "alg": "RS256", |
| 116 | + "kid": "X5eXk4xyojNFum1kl2Ytv8dl..." |
| 117 | +}.{ |
| 118 | + "iss": "https://contoso0926tenant.b2clogin.com/c64a4f7d-3091-4c73-a7.../v2.0/", |
| 119 | + "exp": 1549651031, |
| 120 | + "nbf": 1549647431, |
| 121 | + "aud": "f2a76e08-93f2-4350-833c-965...", |
| 122 | + "oid": "1558f87f-452b-4757-bcd1-883...", |
| 123 | + "sub": "1558f87f-452b-4757-bcd1-883...", |
| 124 | + "name": "David", |
| 125 | + "tfp": "B2C_1_signupsignin1", |
| 126 | + "nonce": "anyRandomValue", |
| 127 | + "scp": "read", |
| 128 | + "azp": "38307aee-303c-4fff-8087-d8d2...", |
| 129 | + "ver": "1.0", |
| 130 | + "iat": 1549647431 |
| 131 | +}.[Signature] |
| 132 | +``` |
129 | 133 |
|
130 | 134 | ## Next steps
|
131 | 135 |
|
132 |
| -* Build a web API using [.NET Core](https://github.com/Azure-Samples/active-directory-b2c-dotnetcore-webapi) |
133 |
| -* Build a web API using [Node.JS](https://github.com/Azure-Samples/active-directory-b2c-javascript-nodejs-webapi) |
| 136 | +- Learn about how to [configure tokens in Azure AD B2C](configure-tokens.md) |
0 commit comments