Skip to content

Commit d74600f

Browse files
committed
edits
1 parent e88fc19 commit d74600f

File tree

5 files changed

+219
-207
lines changed

5 files changed

+219
-207
lines changed

articles/app-service/app-service-web-configure-tls-mutual-auth.md

Lines changed: 53 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
2-
title: Set up TLS mutual authentication
3-
description: Learn how to set up TLS mutual authentication in Azure App Service for secure two-way communication between client and server.
2+
title: Set Up TLS mutual authentication
3+
description: Learn how to set up TLS mutual authentication in Azure App Service to help secure two-way communication between client and server.
44
keywords: TLS mutual authentication, Azure App Service security, secure client-server communication
55
author: msangapu-msft
66
ms.author: msangapu
@@ -12,38 +12,44 @@ ms.custom: devx-track-csharp, devx-track-extended-java, devx-track-js, devx-trac
1212
---
1313
# Configure TLS mutual authentication in Azure App Service
1414

15-
You can restrict access to your Azure App Service app by enabling different types of authentication for it. One way to do it is to request a client certificate when the client request is over TLS/SSL and validate the certificate. This mechanism is called Transport Layer Security (TLS) mutual authentication or client certificate authentication. This article shows how to set up your app to use client certificate authentication.
15+
You can restrict access to your Azure App Service app by enabling different types of authentication for it. One way to set up authentication is to request a client certificate when the client request is over TLS/SSL and to validate the certificate. This mechanism is called Transport Layer Security (TLS) mutual authentication or client certificate authentication. This article shows how to set up your app to use client certificate authentication.
1616

1717
> [!NOTE]
1818
> Your app code is responsible for validating the client certificate. App Service doesn't do anything with this client certificate other than forwarding it to your app.
19-
>
20-
> If you access your site over HTTP and not HTTPS, you will not receive any client certificate. So if your application requires client certificates, you should not allow requests to your application over HTTP.
19+
>
20+
> If you access your site over HTTP and not HTTPS, you don't receive any client certificates. If your application requires client certificates, you shouldn't allow requests to your application over HTTP.
2121
2222
[!INCLUDE [Prepare your web app](../../includes/app-service-ssl-prepare-app.md)]
2323

2424
## Enable client certificates
25-
When you enable client certificate for your app, you should select your choice of client certificate mode. Each mode defines how your app handles incoming client certificates:
2625

27-
|Client certificate modes|Description|
26+
When you enable client certificates for your app, you should select your choice of client certificate mode. Each mode defines how your app handles incoming client certificates.
27+
28+
|Client certificate mode|Description|
2829
|-|-|
2930
|Required|All requests require a client certificate.|
30-
|Optional|Requests may or may not use a client certificate and clients are prompted for a certificate by default. For example, browser clients will show a prompt to select a certificate for authentication.|
31-
|Optional Interactive User|Requests may or may not use a client certificate and clients are not prompted for a certificate by default. For example, browser clients won't show a prompt to select a certificate for authentication.|
31+
|Optional|Requests can use a client certificate and clients are prompted for a certificate by default. For example, browser clients show a prompt to select a certificate for authentication.|
32+
|Optional Interactive User|Requests can use a client certificate and clients aren't prompted for a certificate by default. For example, browser clients don't show a prompt to select a certificate for authentication.|
3233

3334
### [Azure portal](#tab/azureportal)
34-
To set up your app to require client certificates in Azure portal:
35-
1. Navigate to your app's management page.
36-
1. From the left navigation of your app's management page, select **Configuration** > **General Settings**.
37-
1. Select **Client certificate mode** of choice. Select **Save** at the top of the page.
35+
36+
To set up your app to require client certificates in the Azure portal:
37+
38+
1. Go to your app management page.
39+
1. On the resource menu, select **Configuration** > **General Settings**.
40+
1. For **Client certificate mode**, select your choice.
41+
1. Select **Save**.
3842

3943
### [Azure CLI](#tab/azurecli)
40-
With Azure CLI, run the following command in the [Cloud Shell](https://shell.azure.com):
44+
45+
With the Azure CLI, run the following command in the [Cloud Shell](https://shell.azure.com):
4146

4247
```azurecli-interactive
4348
az webapp update --set clientCertEnabled=true --name <app-name> --resource-group <group-name>
4449
```
4550

4651
### [Bicep](#tab/bicep)
52+
4753
For Bicep, modify the properties `clientCertEnabled`, `clientCertMode`, and `clientCertExclusionPaths`. A sample Bicep snippet is provided for you:
4854

4955
```bicep
@@ -64,7 +70,8 @@ resource appService 'Microsoft.Web/sites@2020-06-01' = {
6470
```
6571

6672
### [ARM template](#tab/arm)
67-
For ARM templates, modify the properties `clientCertEnabled`, `clientCertMode`, and `clientCertExclusionPaths`. A sample ARM template snippet is provided for you:
73+
74+
For Azure Resource Manager templates (ARM templates), modify the properties `clientCertEnabled`, `clientCertMode`, and `clientCertExclusionPaths`. A sample ARM template snippet is provided for you:
6875

6976
```ARM
7077
{
@@ -96,48 +103,52 @@ When you enable mutual auth for your application, all paths under the root of yo
96103
> [!NOTE]
97104
> Using any client certificate exclusion path triggers TLS renegotiation for incoming requests to the app.
98105
99-
1. From the left navigation of your app's management page, select **Configuration** > **General Settings**.
106+
1. On the resource menu of your app's management pane, select **Configuration** > **General Settings**.
100107

101108
1. Next to **Certificate exclusion paths**, select the edit icon.
102109

103110
1. Select **New path**, specify a path, or a list of paths separated by `,` or `;`, and select **OK**.
104111

105-
1. Select **Save** at the top of the page.
112+
1. Select **Save**.
106113

107114
In the following screenshot, any path for your app that starts with `/public` doesn't request a client certificate. Path matching is case-insensitive.
108115

109116
![Certificate Exclusion Paths][exclusion-paths]
110117

111118
## Client certificate and TLS renegotiation
119+
112120
For some client certificate settings, App Service requires TLS renegotiation to read a request before knowing whether to prompt for a client certificate. Any of the following settings triggers TLS renegotiation:
113-
1. Using "Optional Interactive User" client certificate mode.
114-
1. Using [client certificate exclusion path](#exclude-paths-from-requiring-authentication).
121+
122+
- Using the "Optional Interactive User" client certificate mode.
123+
- Using the [client certificate exclusion path](#exclude-paths-from-requiring-authentication).
115124

116125
> [!NOTE]
117-
> TLS 1.3 and HTTP 2.0 don't support TLS renegotiation. These protocols will not work if your app is configured with client certificate settings that use TLS renegotiation.
126+
> TLS 1.3 and HTTP 2.0 don't support TLS renegotiation. These protocols don't work if your app is configured with client certificate settings that use TLS renegotiation.
118127
119128
To disable TLS renegotiation and to have the app negotiate client certificates during TLS handshake, you must configure your app with *all* these settings:
120-
1. Set client certificate mode to "Required" or "Optional"
121-
2. Remove all client certificate exclusion paths
122129

123-
### Uploading large files with TLS renegotiation
124-
Client certificate configurations that use TLS renegotiation cannot support incoming requests with large files greater than 100 kb due to buffer size limitations. In this scenario, any POST or PUT requests over 100 kb will fail with a 403 error. This limit isn't configurable and can't be increased.
130+
1. Set client certificate mode to "Required" or "Optional."
131+
1. Remove all client certificate exclusion paths.
132+
133+
### Upload large files with TLS renegotiation
125134

126-
To address the 100 kb limit, consider these alternative solutions:
135+
Client certificate configurations that use TLS renegotiation can't support incoming requests with large files greater than 100 KB due to buffer size limitations. In this scenario, any POST or PUT requests over 100 KB fails with a 403 error. This limit isn't configurable and can't be increased.
127136

128-
1. Disable TLS renegotiation. Update your app's client certificate configurations with _all_ these settings:
129-
- Set client certificate mode to either "Required" or "Optional"
130-
- Remove all client certificate exclusion paths
137+
To address the 100-KB limit, consider these alternative solutions:
138+
139+
1. Disable TLS renegotiation. Update your app's client certificate configurations with *all* these settings:
140+
- Set the client certificate mode to either "Required" or "Optional."
141+
- Remove all client certificate exclusion paths.
131142
1. Send a HEAD request before the PUT/POST request. The HEAD request handles the client certificate.
132143
1. Add the header `Expect: 100-Continue` to your request. This causes the client to wait until the server responds with a `100 Continue` before sending the request body, which bypasses the buffers.
133144

134145
## Access client certificate
135146

136147
In App Service, TLS termination of the request happens at the frontend load balancer. When App Service forwards the request to your app code with [client certificates enabled](#enable-client-certificates), it injects an `X-ARR-ClientCert` request header with the client certificate. App Service doesn't do anything with this client certificate other than forwarding it to your app. Your app code is responsible for validating the client certificate.
137148

138-
For ASP.NET, the client certificate is available through the **HttpRequest.ClientCertificate** property.
149+
For ASP.NET, the client certificate is available through the `HttpRequest.ClientCertificate` property.
139150

140-
For other application stacks (Node.js, PHP, etc.), the client cert is available in your app through a base64 encoded value in the `X-ARR-ClientCert` request header.
151+
For other application stacks (Node.js, PHP, etc.), the client cert is available in your app through a base64-encoded value in the `X-ARR-ClientCert` request header.
141152

142153
## ASP.NET Core sample
143154

@@ -273,22 +284,22 @@ public class Startup
273284
//
274285
private bool IsValidClientCertificate()
275286
{
276-
// In this example we will only accept the certificate as a valid certificate if all the conditions below are met:
277-
// 1. The certificate isn't expired and is active for the current time on server.
278-
// 2. The subject name of the certificate has the common name nildevecc
279-
// 3. The issuer name of the certificate has the common name nildevecc and organization name Microsoft Corp
280-
// 4. The thumbprint of the certificate is 30757A2E831977D8BD9C8496E4C99AB26CB9622B
287+
// In this example, we accept the certificate as a valid certificate only if all the conditions below are met:
288+
// - The certificate isn't expired and is active for the current time on the server.
289+
// - The subject name of the certificate has the common name nildevecc.
290+
// - The issuer name of the certificate has the common name nildevecc and the organization name Microsoft Corp.
291+
// - The thumbprint of the certificate is 30757A2E831977D8BD9C8496E4C99AB26CB9622B.
281292
//
282293
// This example doesn't test that this certificate is chained to a Trusted Root Authority (or revoked) on the server
283-
// and it allows for self signed certificates
294+
// and it allows for self-signed certificates.
284295
//
285296
286297
if (certificate == null || !String.IsNullOrEmpty(errorString)) return false;
287298

288-
// 1. Check time validity of certificate
299+
// 1. Check time validity of the certificate.
289300
if (DateTime.Compare(DateTime.Now, certificate.NotBefore) < 0 || DateTime.Compare(DateTime.Now, certificate.NotAfter) > 0) return false;
290301

291-
// 2. Check subject name of certificate
302+
// 2. Check the subject name of the certificate.
292303
bool foundSubject = false;
293304
string[] certSubjectData = certificate.Subject.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
294305
foreach (string s in certSubjectData)
@@ -301,7 +312,7 @@ public class Startup
301312
}
302313
if (!foundSubject) return false;
303314

304-
// 3. Check issuer name of certificate
315+
// 3. Check the issuer name of the certificate.
305316
bool foundIssuerCN = false, foundIssuerO = false;
306317
string[] certIssuerData = certificate.Issuer.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
307318
foreach (string s in certIssuerData)
@@ -321,7 +332,7 @@ public class Startup
321332

322333
if (!foundIssuerCN || !foundIssuerO) return false;
323334

324-
// 4. Check thumbprint of certificate
335+
// 4. Check the thumbprint of the certificate.
325336
if (String.Compare(certificate.Thumbprint.Trim().ToUpper(), "30757A2E831977D8BD9C8496E4C99AB26CB9622B") != 0) return false;
326337

327338
return true;
@@ -332,7 +343,7 @@ public class Startup
332343

333344
## Node.js sample
334345

335-
The following Node.js sample code gets the `X-ARR-ClientCert` header and uses [node-forge](https://github.com/digitalbazaar/forge) to convert the base64-encoded PEM string into a certificate object and validate it:
346+
The following Node.js sample code gets the `X-ARR-ClientCert` header and uses [node-forge](https://github.com/digitalbazaar/forge) to convert the base64-encoded Privacy Enhanced Mail (PEM) string into a certificate object and validate it:
336347

337348
```javascript
338349
import { NextFunction, Request, Response } from 'express';
@@ -377,8 +388,7 @@ export class AuthorizationHandler {
377388

378389
## Java sample
379390

380-
The following Java class encodes the certificate from `X-ARR-ClientCert` to an `X509Certificate` instance. `certificateIsValid()` validates that the certificate's thumbprint matches the one given in the constructor and that certificate hasn't expired.
381-
391+
The following Java class encodes the certificate from `X-ARR-ClientCert` to an `X509Certificate` instance. `certificateIsValid()` validates that the certificate's thumbprint matches the one given in the constructor and that certificate isn't expired.
382392

383393
```java
384394
import java.io.ByteArrayInputStream;

0 commit comments

Comments
 (0)