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
# Configure TLS mutual authentication in Azure App Service
14
14
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.
16
16
17
17
> [!NOTE]
18
18
> 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.
21
21
22
22
[!INCLUDE [Prepare your web app](../../includes/app-service-ssl-prepare-app.md)]
23
23
24
24
## 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:
26
25
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|
28
29
|-|-|
29
30
|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.|
32
33
33
34
### [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**.
38
42
39
43
### [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):
41
46
42
47
```azurecli-interactive
43
48
az webapp update --set clientCertEnabled=true --name <app-name> --resource-group <group-name>
44
49
```
45
50
46
51
### [Bicep](#tab/bicep)
52
+
47
53
For Bicep, modify the properties `clientCertEnabled`, `clientCertMode`, and `clientCertExclusionPaths`. A sample Bicep snippet is provided for you:
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:
68
75
69
76
```ARM
70
77
{
@@ -96,48 +103,52 @@ When you enable mutual auth for your application, all paths under the root of yo
96
103
> [!NOTE]
97
104
> Using any client certificate exclusion path triggers TLS renegotiation for incoming requests to the app.
98
105
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**.
100
107
101
108
1. Next to **Certificate exclusion paths**, select the edit icon.
102
109
103
110
1. Select **New path**, specify a path, or a list of paths separated by `,` or `;`, and select **OK**.
104
111
105
-
1. Select **Save** at the top of the page.
112
+
1. Select **Save**.
106
113
107
114
In the following screenshot, any path for your app that starts with `/public` doesn't request a client certificate. Path matching is case-insensitive.
108
115
109
116
![Certificate Exclusion Paths][exclusion-paths]
110
117
111
118
## Client certificate and TLS renegotiation
119
+
112
120
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).
115
124
116
125
> [!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.
118
127
119
128
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
122
129
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
125
134
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.
127
136
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.
131
142
1. Send a HEAD request before the PUT/POST request. The HEAD request handles the client certificate.
132
143
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.
133
144
134
145
## Access client certificate
135
146
136
147
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.
137
148
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.
139
150
140
-
For other application stacks (Node.js, PHP, etc.), the client cert is available in your app through a base64encoded 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.
141
152
142
153
## ASP.NET Core sample
143
154
@@ -273,22 +284,22 @@ public class Startup
273
284
//
274
285
privateboolIsValidClientCertificate()
275
286
{
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.
281
292
//
282
293
// 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 selfsigned certificates
294
+
// and it allows for self-signed certificates.
284
295
//
285
296
286
297
if (certificate==null||!String.IsNullOrEmpty(errorString)) returnfalse;
287
298
288
-
// 1. Check time validity of certificate
299
+
// 1. Check time validity of the certificate.
289
300
if (DateTime.Compare(DateTime.Now, certificate.NotBefore) <0||DateTime.Compare(DateTime.Now, certificate.NotAfter) >0) returnfalse;
if (String.Compare(certificate.Thumbprint.Trim().ToUpper(), "30757A2E831977D8BD9C8496E4C99AB26CB9622B") !=0) returnfalse;
326
337
327
338
returntrue;
@@ -332,7 +343,7 @@ public class Startup
332
343
333
344
## Node.js sample
334
345
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:
@@ -377,8 +388,7 @@ export class AuthorizationHandler {
377
388
378
389
## Java sample
379
390
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.
0 commit comments