You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: articles/active-directory/develop/scenario-protected-web-api-app-registration.md
+9-9Lines changed: 9 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -56,9 +56,9 @@ Scopes are usually of the form `resourceURI/scopeName`. For Microsoft Graph, the
56
56
57
57
During app registration, you'll need to define the following parameters:
58
58
59
-
-One resource URI - By default the application registration portal recommends that you to use `api://{clientId}`. This resource URI is unique, but it's not human readable. You can change it, but make sure that it's unique.
60
-
- One or several**scopes** (that client applicationswill refer to as **delegated permissions** for your Web API)
61
-
- One or several**app roles** (that client applicationswill refer to as **application permissions** for your Web API)
59
+
-The resource URI - By default the application registration portal recommends that you to use `api://{clientId}`. This resource URI is unique, but it's not human readable. You can change it, but make sure that it's unique.
60
+
- One or more**scopes** (to client applications, they will show up as **delegated permissions** for your Web API)
61
+
- One or more**app roles** (to client applications, they will show up as **application permissions** for your Web API)
62
62
63
63
The scopes are also displayed on the consent screen that's presented to end users who use your application. Therefore, you'll need to provide the corresponding strings that describe the scope:
64
64
@@ -84,15 +84,15 @@ The scopes are also displayed on the consent screen that's presented to end user
84
84
85
85
In this paragraph, you'll learn how to register your protected Web API so that it can be called securely by daemon applications:
86
86
87
-
- you' statuill need to expose application permissions
88
-
- tenant admins may require AAD to acquire tokens for your Web App only for registered applications;
87
+
- you'll need to expose **application permissions**. You will only declare application permissions as daemon applications do not interact with users and therefore delegated permissions would not make sense.
88
+
- tenant admins may require Azure AD to issue tokens for your Web App to only applications that have registered that they want to access one of the Web API apps permissions.
89
89
90
90
#### How to expose application permissions (app roles)
91
91
92
92
To Expose application permissions, you'll need to edit the manifest.
93
93
94
94
1. In the application registration for your application, click **Manifest**.
95
-
1. Edit the manifest by locating the `appRoles` setting and adding one or several application roles. The role definition is provided in the JSON block below. Leave the `allowedMemberTypes` to "Application" only.
95
+
1. Edit the manifest by locating the `appRoles` setting and adding one or several application roles. The role definition is provided in the sample JSON block below. Leave the `allowedMemberTypes` to "Application" only. Please make sure that the **id** is a unique guid and **displayName** and **Value** don't contain any spaces.
96
96
1. Save the manifest.
97
97
98
98
The content of `appRoles` should be the following (the `id` can be any unique GUID)
@@ -114,7 +114,7 @@ The content of `appRoles` should be the following (the `id` can be any unique GU
114
114
115
115
#### How to ensure that Azure AD issues tokens for your Web API only to allowed clients
116
116
117
-
The Web API tests for the app role (that's the developer way of doing it). But you can even ask Azure Active Directory to issue a token for your Web API only to applications that were approved by the tenant admin. To add this additional security:
117
+
The Web API checks for the app role (that's the developer way of doing it). But you can even configure Azure Active Directory to issue a token for your Web API only to applications that were approved by the tenant admin to access your API. To add this additional security:
118
118
119
119
1. On the app **Overview** page for your app registration, select the hyperlink with the name of your application in **Managed application in local directory**. The title for this field can be truncated. You could, for instance, read: `Managed application in ...`
120
120
@@ -127,9 +127,9 @@ The Web API tests for the app role (that's the developer way of doing it). But y
127
127
128
128
> [!IMPORTANT]
129
129
>
130
-
> By setting **User assignment required?** to **Yes**, AAD will check the app role assignments of the clients when they request an access token for the Web API. If the client was not be assigned to any AppRoles, AAD would just return `invalid_client: AADSTS501051: Application xxxx is not assigned to a role for the xxxx`
130
+
> By setting **User assignment required?** to **Yes**, AAD will check the app role assignments of the clients when they request an access token for the Web API. If the client was not be assigned to any AppRoles, AAD would just return the following error: `invalid_client: AADSTS501051: Application xxxx is not assigned to a role for the xxxx`
131
131
>
132
-
> If you keep **User assignment required?** to **No**, <spanstyle='background-color:yellow; display:inline'>Azure AD won’t check the app role assignments when a client requests an access token to your Web API</span>. Therefore, any daemon client (that is any client using client credentials flow) would still be able to obtain the access token for the Web API just by specifying its audience. Any application, would be able to access the API without having to request permissions for it. Now this is not then end of it, as your Web API can always, as is done in this sample, verify that the application has the right role (which was authorized by the tenant admin), by validating that the access token has a `roles` claim, and the right value for this claim (in our case `access_as_application`).
132
+
> If you keep **User assignment required?** to **No**, <spanstyle='background-color:yellow; display:inline'>Azure AD won’t check the app role assignments when a client requests an access token for your Web API</span>. Therefore, any daemon client (that is any client using client credentials flow) would still be able to obtain an access token for the API just by specifying its audience. Any application, would be able to access the API without having to request permissions for it. Now, this is not then end of it, as your Web API can always, as explained in the next section, verify that the application has the right role (which was authorized by the tenant admin), by validating that the access token has a `roles` claim, and the right value for this claim (in our case `access_as_application`).
Copy file name to clipboardExpand all lines: articles/active-directory/develop/scenario-protected-web-api-verification-scope-app-roles.md
+42-23Lines changed: 42 additions & 23 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,7 +16,7 @@ ms.workload: identity
16
16
ms.date: 05/07/2019
17
17
ms.author: jmprieur
18
18
ms.custom: aaddev
19
-
#Customer intent: As an application developer, I want to know how to write a protected Web API using the Microsoft identity platform for developers.
19
+
#Customer intent: As an application developer, I want to learn how to write a protected Web API using the Microsoft identity platform for developers.
20
20
ms.collection: M365-identity-device-management
21
21
---
22
22
@@ -30,7 +30,7 @@ This article describes how you can add authorization to your Web API. This prote
30
30
For an ASP.NET / ASP.NET Core Web API to be protected, you'll need to add the `[Authorize]` attribute on:
31
31
32
32
- the Controller itself if you want all the actions of the controller to be protected
33
-
- the individual controller action for your API, otherwise.
33
+
-or the individual controller action for your API.
34
34
35
35
```CSharp
36
36
[Authorize]
@@ -73,14 +73,14 @@ public class TodoListController : Controller
73
73
74
74
The `VerifyUserHasAnyAcceptedScope` method would do something like the following:
75
75
76
-
- verify that there's a claims named `scope`
77
-
- verify that the claim has a value containing the scope expected by the API.
76
+
- verify that there's a claims named `http://schemas.microsoft.com/identity/claims/scope` or `scp`
77
+
- verify that the claim has a value containing the scope expected by the API.
78
78
79
79
```CSharp
80
80
/// <summary>
81
81
/// When applied to an <seecref="HttpContext"/>, verifies that the user authenticated in the
82
-
/// Web API has any of the accepted scopes. *
83
-
/// If the authentication user does not have any of these <paramrefname="acceptedScopes"/>, the
82
+
/// Web API has any of the accepted scopes.
83
+
/// If the authenticated user does not have any of these <paramrefname="acceptedScopes"/>, the
84
84
/// method throws an HTTP Unauthorized with the message telling which scopes are expected in the token
85
85
/// </summary>
86
86
/// <paramname="acceptedScopes">Scopes accepted by this API</param>
@@ -104,15 +104,13 @@ The `VerifyUserHasAnyAcceptedScope` method would do something like the following
104
104
}
105
105
```
106
106
107
-
This sample code is for ASP.NET Core. For ASP.NET just replace `HttpContext.User` by `ClaimsPrincipal.Current`, and the claim type `"http://schemas.microsoft.com/identity/claims/scope"` by `"scope"` (See also the code snippet below)
108
-
107
+
This sample code is for ASP.NET Core. For ASP.NET just replace `HttpContext.User` by `ClaimsPrincipal.Current`, and the claim type `"http://schemas.microsoft.com/identity/claims/scope"` by `"scp"` (See also the code snippet below)
109
108
110
109
## Verifying app roles in APIs called by daemon apps
111
110
112
-
If you Web API is called by a [Daemon application](scenario-daemon-overview.md), then that application should require an application permission
113
-
to your Web API. We've seen in [scenario-protected-web-api-app-registration.md#how-to-expose-application-permissions--app-roles-] that your API
114
-
exposes such permissions (for instance as the `access_as_application` app role). You now need to have your APIs verify that the token it received contains the `roles` claims and
115
-
that this claim has the value it expects. To do this, the code is similar to the code that verifies delegated permissions, except that, instead of testing for `scopes`, your controller action will test for `roles`:
111
+
If your Web API is called by a [Daemon application](scenario-daemon-overview.md), then that application should require an application permission to your Web API. We've seen in [scenario-protected-web-api-app-registration.md#how-to-expose-application-permissions--app-roles-] that your API exposes such permissions (for instance as the `access_as_application` app role).
112
+
You now need to have your APIs verify that the token it received contains the `roles` claims and
113
+
that this claim has the value it expects. The code doing this verification is similar to the code that verifies delegated permissions, except that, instead of testing for `scopes`, your controller action will test for `roles`:
116
114
117
115
```CSharp
118
116
[Authorize]
@@ -125,26 +123,47 @@ public class TodoListController : ApiController
125
123
}
126
124
```
127
125
128
-
TheValidateAppRole() method can be something like this:
126
+
The `ValidateAppRole()`methodcanbesomethinglikethis:
129
127
130
128
```CSharp
131
-
private void ValidateAppRole(stringappRole)
129
+
private void ValidateAppRole(string appRole)
130
+
{
131
+
//
132
+
// The `role` claim tells you what permissions the client application has in the service.
133
+
// In this case we look for a `role` value of `access_as_application`
134
+
//
135
+
136
+
if (!isAppOnlyToken)
132
137
{
133
-
//
134
-
// The `role` claim tells you what permissions the client application has in the service.
135
-
// In this case we look for a `role` value of `access_as_application`
if (scopeClaim==null|| (scopeClaim.Value!=appRole))
139
-
{
140
-
thrownewHttpResponseException(newHttpResponseMessage { StatusCode=HttpStatusCode.Unauthorized, ReasonPhrase=$"The 'roles' claim does not contain '{appRole}' or was not found" });
ReasonPhrase=$"The 'roles' claim does not contain '{appRole}' or was not found"
145
+
});
146
+
}
147
+
}
143
148
}
144
149
```
145
150
146
151
This sample code is for ASP.NET. For ASP.NET Core, just replace `ClaimsPrincipal.Current` by `HttpContext.User` and the `"roles"` claim name by `"http://schemas.microsoft.com/identity/claims/roles"` (see also the code snippet above)
147
152
153
+
### Accepting app only tokens if the Web API should only be called by daemon apps
154
+
155
+
The `roles` claim is also used for users in user assignment patterns (See [How to: Add app roles in your application and receive them in the token](howto-add-app-roles-in-azure-ad-apps.md)). So just checking roles will allow apps to sign in as users and the other way around.
156
+
157
+
If you want to only allow daemon applications to call your Web API, you'll want to add a condition, when you validate the app role, that the token is an app-only token:
0 commit comments