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: aspnetcore/blazor/security/blazor-web-app-with-entra.md
+76-63Lines changed: 76 additions & 63 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -59,20 +59,6 @@ This section explains how to configure the sample app.
59
59
60
60
In the app's registration in the Entra or Azure portal, use a **Web** platform configuration with a **Redirect URI** of `https://localhost/signin-oidc` (a port isn't required). Confirm that **ID tokens** and access tokens under **Implicit grant and hybrid flows** are **not** selected. The OpenID Connect handler automatically requests the appropriate tokens using the code returned from the authorization endpoint.
61
61
62
-
### Establish the client secret
63
-
64
-
Use the [Secret Manager tool](xref:security/app-secrets) to store the server app's client secret under the configuration key `AzureAd:ClientSecret`.
65
-
66
-
Create a client secret in the app's Entra ID registration in the Entra or Azure portal (**Manage** > **Certificates & secrets** > **New client secret**). Use the **Value** of the new secret in the following guidance.
67
-
68
-
Execute the following command in a command shell from the server project's directory, such as the Developer PowerShell command shell in Visual Studio. The `{SECRET}` placeholder is the client secret obtained from the app's registration:
69
-
70
-
```dotnetcli
71
-
dotnet user-secrets set "AzureAd:ClientSecret" "{SECRET}"
72
-
```
73
-
74
-
If using Visual Studio, you can confirm the secret is set by right-clicking the server project in **Solution Explorer** and selecting **Manage User Secrets**.
75
-
76
62
### Configure the app
77
63
78
64
In the server project's app settings file (`appsettings.json`), provide the app's `AzureAd` section configuration. Obtain the application (client) ID, tenant (publisher) domain, and directory (tenant) ID from the app's registration in the Entra or Azure portal:
@@ -109,57 +95,41 @@ Example:
109
95
110
96
The callback path (`CallbackPath`) must match the redirect URI (login callback path) configured when registering the application in the Entra or Azure portal. Paths are configured in the **Authentication** blade of the app's registration. The default value of `CallbackPath` is `/signin-oidc` for a registered redirect URI of `https://localhost/signin-oidc` (a port isn't required).
111
97
112
-
<!-- UPDATE 9.0 Replace the following with the INCLUDE link after
> Don't store app secrets, connection strings, credentials, passwords, personal identification numbers (PINs), private C#/.NET code, or private keys/tokens in client-side code, which is ***always insecure***. In test/staging and production environments, server-side Blazor code and web APIs should use secure authentication flows that avoid maintaining credentials within project code or configuration files. Outside of local development testing, we recommend avoiding the use of environment variables to store sensitive data, as environment variables aren't the most secure approach. For local development testing, the [Secret Manager tool](xref:security/app-secrets) is recommended for securing sensitive data.
102
+
Create a client secret in the app's Entra ID registration in the Entra or Azure portal (**Manage** > **Certificates & secrets** > **New client secret**). Use the **Value** of the new secret in the following guidance.
121
103
122
-
## Redirect to the home page on sign out
104
+
Use one of the following approaches to supply the client secret to the app:
123
105
124
-
When a user navigates around the app, the `LogInOrOut` component (`Layout/LogInOrOut.razor`) sets a hidden field for the return URL (`ReturnUrl`) to the value of the current URL (`currentURL`). When the user signs out of the app, the identity provider returns them to the page from which they signed out.
106
+
*[Secret Manager tool](#secret-manager-tool)
107
+
*[Azure Key Vault](#azure-key-vault)
125
108
126
-
If the user signs out from a secure page, they're returned back to the same secure page after signing out only to be sent back through the authentication process. This behavior is fine when users need to switch accounts frequently. However, a alternative app specification may call for the user to be returned to the app's home page or some other page after signing out. The following example shows how to set the app's home page as the return URL for sign-out operations.
109
+
We strongly recommend that you avoid storing client secrets in project code or configuration files. Use secure authentication flows, such as either of the approaches in this section.
127
110
128
-
The important changes to the `LogInOrOut` component are demonstrated in the following example. There's no need to provide a hidden field for the `ReturnUrl` set to the home page at `/` because that's the default path. <xref:System.IDisposable> is no longer implemented. The <xref:Microsoft.AspNetCore.Components.NavigationManager> is no longer injected. The entire `@code` block is removed.
111
+
### Secret Manager tool
129
112
130
-
`Layout/LogInOrOut.razor`:
113
+
The [Secret Manager tool](xref:security/app-secrets) can store the server app's client secret under the configuration key `AzureAd:ClientSecret`.
131
114
132
-
```razor
133
-
@using Microsoft.AspNetCore.Authorization
115
+
Execute the following command in a command shell from the server project's directory, such as the Developer PowerShell command shell in Visual Studio. The `{SECRET}` placeholder is the client secret obtained from the app's registration:
dotnet user-secrets set "AzureAd:ClientSecret" "{SECRET}"
154
119
```
155
120
156
-
## Obtain the client secret from Azure Key Vault
121
+
If using Visual Studio, you can confirm the secret is set by right-clicking the server project in **Solution Explorer** and selecting **Manage User Secrets**.
122
+
123
+
### Azure Key Vault
157
124
158
125
[Azure Key Vault](https://azure.microsoft.com/products/key-vault/) provides a safe approach for providing the app's client secret to the app when hosting in [Microsoft Azure](https://azure.microsoft.com/).
159
126
160
-
To create a key vault and set a client secret, see [About Azure Key Vault secrets (Azure documentation)](/azure/key-vault/secrets/about-secrets), which cross-links resources to get started with Azure Key Vault. To implement the code in this section, record the key vault URI and the secret name from Azure when you create the key vault and secret.
127
+
To create a key vault and set a client secret, see [About Azure Key Vault secrets (Azure documentation)](/azure/key-vault/secrets/about-secrets), which cross-links resources to get started with Azure Key Vault. To implement the code in this section, record the key vault URI and the secret name from Azure when you create the key vault and secret. When you set the access policy for the secret in the **Access policies** panel:
128
+
129
+
* Only the **Get** secret permission is required.
130
+
* Select the application as the **Principal** for the secret.
161
131
162
-
The following `GetKeyVaultSecret` method retrieves a secret from a key vault. Add this method to the server project. Adjust the namespace (`BlazorSample.Helpers`) to match your project namespace scheme.
132
+
The following `GetKeyVaultSecret` method retrieves a secret from a key vault. Add this method to the server project. Adjust the namespace (`BlazorSample.Helpers`) to match your project namespace scheme. If you aren't using Visual Studio, you can use the [Secret Manager tool](#secret-manager-tool) locally to store the secret and use the approach in this section in staging/production when the app is deployed.
163
133
164
134
`Helpers/AzureHelper`:
165
135
@@ -177,6 +147,7 @@ public static class AzureHelper
177
147
DefaultAzureCredentialOptionsoptions=new()
178
148
{
179
149
// Specify the tenant ID to use the dev credentials when running the app locally
150
+
// in Visual Studio.
180
151
VisualStudioTenantId=tenantId,
181
152
SharedTokenCacheTenantId=tenantId
182
153
};
@@ -189,24 +160,32 @@ public static class AzureHelper
189
160
}
190
161
```
191
162
192
-
In the server project's `Program` file after Microsoft identity platform services are added (`AddMicrosoftIdentityWebApp`), obtain and apply the client secret using the following code:
163
+
In the server project's `Program` file where services are registered, obtain and apply the client secret using the following code:
Supply the vault URI and secret name from configuration.
179
+
If you wish to control the environment where the preceding code operates, for example to avoid running the code locally because you've opted to use the [Secret Manager tool](#secret-manager-tool) for local development, you can wrap the preceding code in a conditional statement that checks the environment:
208
180
209
-
In the `AzureAd` section of `appsettings.json`, add configuration keys and values:
181
+
```csharp
182
+
if (!context.HostingEnvironment.IsDevelopment())
183
+
{
184
+
...
185
+
}
186
+
```
187
+
188
+
In the `AzureAd` section of `appsettings.json`, add the following configuration keys and values:
210
189
211
190
* The `{VAULT URI}` placeholder is the key vault URI. Include the trailing slash on the URI.
212
191
* The `{SECRET NAME}` placeholder is the secret name.
@@ -220,10 +199,44 @@ Example:
220
199
221
200
```json
222
201
"VaultUri": "https://contoso.vault.azure.net/",
223
-
"SecretName": "BlazorSample_Entra"
202
+
"SecretName": "BlazorWebAppEntra"
224
203
```
225
204
226
-
Configuration is used to facilitate supplying values based on the app's environmental configuration files. For example, `appsettings.Development.json` for Development, `appsettings.Staging.json` for Staging, and `appsettings.Production.json` for Production can use dedicated key vaults and secret names for each environment.
205
+
Configuration is used to facilitate supplying dedicated key vaults and secret values based on the app's environmental configuration files. For example, you can supply different values for `appsettings.Development.json` in Development, `appsettings.Staging.json` when Staging, and `appsettings.Production.json` for the production deployment. For more information, see <xref:blazor/fundamentals/configuration>.
206
+
207
+
## Redirect to the home page on sign out
208
+
209
+
When a user navigates around the app, the `LogInOrOut` component (`Layout/LogInOrOut.razor`) sets a hidden field for the return URL (`ReturnUrl`) to the value of the current URL (`currentURL`). When the user signs out of the app, the identity provider returns them to the page from which they signed out.
210
+
211
+
If the user signs out from a secure page, they're returned back to the same secure page after signing out only to be sent back through the authentication process. This behavior is fine when users need to switch accounts frequently. However, a alternative app specification may call for the user to be returned to the app's home page or some other page after signing out. The following example shows how to set the app's home page as the return URL for sign-out operations.
212
+
213
+
The important changes to the `LogInOrOut` component are demonstrated in the following example. There's no need to provide a hidden field for the `ReturnUrl` set to the home page at `/` because that's the default path. <xref:System.IDisposable> is no longer implemented. The <xref:Microsoft.AspNetCore.Components.NavigationManager> is no longer injected. The entire `@code` block is removed.
0 commit comments