Skip to content

Commit c325f77

Browse files
author
BobbySchmidt2
committed
edit pass: scenario-protected-web-api; also need to change projects
1 parent 2528f15 commit c325f77

5 files changed

+111
-92
lines changed

articles/active-directory/develop/scenario-protected-web-api-app-configuration.md

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ ms.workload: identity
1717
ms.date: 05/07/2019
1818
ms.author: jmprieur
1919
ms.custom: aaddev
20-
#Customer intent: As an application developer, I want to know how to write a protected web API using the Microsoft identity platform for developers.
20+
#Customer intent: As a software developer, I want to know how to write a protected web API using the Microsoft identity platform for developers.
2121
ms.collection: M365-identity-device-management
2222
---
2323

@@ -27,16 +27,16 @@ To configure the code for your protected web API, you need to understand what de
2727

2828
## What defines ASP.NET/ASP.NET Core APIs as protected?
2929

30-
Like web apps, the ASP.NET/ASP.NET Core web APIs are "protected" because their controller actions are prefixed with the `[Authorize]` attribute. So the controller actions can be called only if the API is called with an identity that's authorized.
30+
Like web apps, the ASP.NET and ASP.NET Core web APIs are protected because their controller actions are prefixed with the `[Authorize]` attribute. So the controller actions can be called only if the API is called with an authorized identity.
3131

3232
Consider the following questions:
3333

34-
- How does the web API know the identity of the app that calls it? (Only an app can call a web API.)
34+
- How does the web API know the identity of the app that calls it, since only an app can call a web API?
3535
- If the app called the web API on behalf of a user, what's the user's identity?
3636

3737
## Bearer token
3838

39-
The information about the identity of the app, and about the user (unless the web app accepts service-to-service calls from a daemon app), is held in the bearer token that's set in the header when the app is called.
39+
Unless the web app accepts service-to-service calls from a daemon app, information about the app identity and about the user is held in the bearer token that's set in the header when the app is called.
4040

4141
Here's a C# code example that shows a client calling the API after it acquires a token with Microsoft Authentication Library for .NET (MSAL.NET):
4242

@@ -53,7 +53,9 @@ HttpResponseMessage response = await _httpClient.GetAsync(apiUri);
5353
```
5454

5555
> [!IMPORTANT]
56-
> The bearer token was requested by a client application to the Microsoft identity platform endpoint *for the web API*. The web API is the only application that should verify the token and view the claims it contains. Client apps should never try to inspect the claims in tokens. (The web API could require, in the future, that the token be encrypted. This requirement would prevent access for client apps that can view access tokens.)
56+
> A client application requests the bearer token to the Microsoft identity platform endpoint *for the web API*. The web API is the only application that should verify the token and view the claims it contains. Client apps should never try to inspect the claims in tokens.
57+
>
58+
> In the future, the web API could require that the token be encrypted. This requirement would prevent access for client apps that can view access tokens.
5759

5860
## JwtBearer configuration
5961

@@ -89,7 +91,7 @@ This section describes how to configure a bearer token.
8991

9092
### Code initialization
9193

92-
When an app is called on a controller action that holds an `[Authorize]` attribute, ASP.NET/ASP.NET Core looks at the bearer token in the Authorization header of the calling request and extracts the access token. The token is then forwarded to the JwtBearer middleware, which calls Microsoft IdentityModel Extensions for .NET.
94+
When an app is called on a controller action that holds an `[Authorize]` attribute, ASP.NET and ASP.NET Core look at the bearer token in the Authorization header of the calling request and extracts the access token. The token is then forwarded to the JwtBearer middleware, which calls Microsoft IdentityModel Extensions for .NET.
9395

9496
In ASP.NET Core, this middleware is initialized in the Startup.cs file:
9597

@@ -103,7 +105,7 @@ The middleware is added to the web API by this instruction:
103105
services.AddAzureAdBearer(options => Configuration.Bind("AzureAd", options));
104106
```
105107

106-
Currently, the ASP.NET Core templates create Azure Active Directory (Azure AD) web APIs that sign in users within your organization or any organization, not with personal accounts. But you can easily change them to use the Microsoft identity platform endpoint by adding this code to the Startup.cs file:
108+
Currently, the ASP.NET Core templates create Azure Active Directory (Azure AD) web APIs that sign in users within your organization or any organization. They do not sign in users with personal accounts. But you can easily change the templates to use the Microsoft identity platform endpoint by adding this code to the Startup.cs file:
107109

108110
```csharp
109111
services.Configure<JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationScheme, options =>
@@ -125,40 +127,42 @@ services.Configure<JwtBearerOptions>(AzureADDefaults.JwtBearerAuthenticationSche
125127
});
126128
```
127129

128-
This code snippet is extracted from the ASP.NET Core Web Api incremental tutorial in [Microsoft.Identity.Web/WebApiServiceCollectionExtensions.cs#L50-L63](https://github.com/Azure-Samples/active-directory-dotnet-native-aspnetcore-v2/blob/154282843da2fc2958fad151e2a11e521e358d42/Microsoft.Identity.Web/WebApiServiceCollectionExtensions.cs#L50-L63). The `AddProtectedWebApi` method, which does a lot more, is called from the Startup.cs
130+
This preceding code snippet is extracted from the ASP.NET Core Web Api incremental tutorial in [Microsoft.Identity.Web/WebApiServiceCollectionExtensions.cs#L50-L63](https://github.com/Azure-Samples/active-directory-dotnet-native-aspnetcore-v2/blob/154282843da2fc2958fad151e2a11e521e358d42/Microsoft.Identity.Web/WebApiServiceCollectionExtensions.cs#L50-L63). The **AddProtectedWebApi** method, which does a lot more, is called from Startup.cs.
129131
130132
## Token validation
131133

132-
The JwtBearer middleware, like the OpenID Connect middleware in web apps, is directed by `TokenValidationParameters` to validate the token. The token is decrypted (as needed), the claims are extracted, and the signature is verified. The middleware then validates the token by checking for this data:
134+
In the preceding snippet, the JwtBearer middleware, like the OpenID Connect middleware in web apps, is directed by the value of `TokenValidationParameters` to validate the token. The token is decrypted as needed, the claims are extracted, and the signature is verified. The middleware then validates the token by checking for this data:
133135

134-
- It's targeted for the web API (audience).
135-
- It was issued for an app that's allowed to call the web API (sub).
136-
- It was issued by a trusted security token service (STS) (issuer).
137-
- Its lifetime is in range (expiry).
138-
- It wasn't tampered with (signature).
136+
- Audience: The token is targeted for the web API.
137+
- Sub: The token was issued for an app that's allowed to call the web API.
138+
- Issuer: The token was issued by a trusted security token service (STS).
139+
- Expiry: The token's lifetime is in range.
140+
- Signature: The token wasn't tampered with.
139141

140-
There can also be special validations. For example, it's possible to validate that signing keys (when embedded in a token) are trusted and that the token isn't being replayed. Finally, some protocols require specific validations.
142+
There can also be special validations. For example, it's possible to validate that signing keys, when embedded in a token, are trusted and that the token isn't being replayed. Also, some protocols require specific validations.
141143

142144
### Validators
143145

144-
The validation steps are captured in validators, which are all in the [Microsoft IdentityModel Extensions for .NET](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet) open-source library, in one source file: [Microsoft.IdentityModel.Tokens/Validators.cs](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/master/src/Microsoft.IdentityModel.Tokens/Validators.cs).
146+
The validation steps are captured in validators, which are provided by the [Microsoft IdentityModel Extensions for .NET](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet) open-source library. The validators are defined in the library source file [Microsoft.IdentityModel.Tokens/Validators.cs](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/master/src/Microsoft.IdentityModel.Tokens/Validators.cs).
145147
146148
The validators are described in this table:
147149

148150
| Validator | Description |
149151
|---------|---------|
150-
| `ValidateAudience` | Ensures the token is for the application that validates the token (for me). |
151-
| `ValidateIssuer` | Ensures the token was issued by a trusted STS (from someone I trust). |
152-
| `ValidateIssuerSigningKey` | Ensures the application validating the token trusts the key that was used to sign the token. (Special case where the key is embedded in the token. Not usually required.) |
153-
| `ValidateLifetime` | Ensures the token is still (or already) valid. The validator checks if the lifetime of the token (`notbefore` and `expires` claims) is in range. |
154-
| `ValidateSignature` | Ensures the token hasn't been tampered with. |
155-
| `ValidateTokenReplay` | Ensures the token isn't replayed. (Special case for some onetime use protocols.) |
152+
| **ValidateAudience** | Ensures the token is for the application that validates the token for you. |
153+
| **ValidateIssuer** | Ensures the token was issued by a trusted STS, meaning from someone you trust. |
154+
| **ValidateIssuerSigningKey** | Ensures the application validating the token trusts the key that was used to sign the token. The is a special case where the key is embedded in the token. But this case does not usually arise. |
155+
| **ValidateLifetime** | Ensures the token is still or already valid. The validator checks if the lifetime of the token, meaning the **notbefore** and **expires** claims, is in range. |
156+
| **ValidateSignature** | Ensures the token hasn't been tampered with. |
157+
| **ValidateTokenReplay** | Ensures the token isn't replayed. There is a special case for some onetime-use protocols. |
156158

157-
The validators are all associated with properties of the `TokenValidationParameters` class, themselves initialized from the ASP.NET/ASP.NET Core configuration. In most cases, you won't have to change the parameters. There's one exception, for apps that aren't single tenants. (That is, web apps that accept users from any organization or from personal Microsoft accounts.) In this case, the issuer must be validated.
159+
The validators are associated with properties of the **TokenValidationParameters** class. The properties are initialized from the ASP.NET and ASP.NET Core configuration. In most cases, you won't need to change the parameters.
160+
161+
There's one exception for apps that aren't single tenants. These are web apps that accept users from any organization or from personal Microsoft accounts. In this case, the issuer must be validated.
158162

159163
## Token validation in Azure Functions
160164

161-
It's also possible to validate incoming access tokens in Azure functions. You can find examples of validating tokens in Azure functions in [Dotnet](https://github.com/Azure-Samples/ms-identity-dotnet-webapi-azurefunctions), [NodeJS](https://github.com/Azure-Samples/ms-identity-nodejs-webapi-azurefunctions), and [Python](https://github.com/Azure-Samples/ms-identity-python-webapi-azurefunctions).
165+
It's also possible to validate incoming access tokens in Azure Functions. You can find examples of validating tokens in Azure Functions in [Microsoft .NET](https://github.com/Azure-Samples/ms-identity-dotnet-webapi-azurefunctions), [NodeJS](https://github.com/Azure-Samples/ms-identity-nodejs-webapi-azurefunctions), and [Python](https://github.com/Azure-Samples/ms-identity-python-webapi-azurefunctions).
162166

163167
## Next steps
164168

0 commit comments

Comments
 (0)