Skip to content

Commit b3223a8

Browse files
committed
refresh content
1 parent 33b5818 commit b3223a8

3 files changed

Lines changed: 70 additions & 52 deletions

File tree

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
---
22
author: tdykstra
33
ms.author: tdykstra
4-
ms.date: 10/16/2024
4+
ms.date: 05/14/2026
55
ms.topic: include
66
---
77
> [!WARNING]
8-
> This article shows the use of connection strings. When using a local database for development and testing, database user authentication via the connection string isn't required. In production environments, connection strings sometimes include a password to authenticate database access or database operations. A resource owner password credential (ROPC) in a connection string is a security risk to avoid in production apps. Production apps should use the most secure authentication flow available. For more information on authentication for apps deployed to test or production environments, see <xref:security/index#secure-authentication-flows>.
8+
> This article shows the use of connection strings. When a local database is used for development and testing, database user authentication via the connection string isn't required.
9+
> In production environments, connection strings sometimes include a password for authenticating database access or database operations. A resource owner password credential (ROPC) in a connection string is a security risk that should be avoided in production apps. Production apps should use the most secure authentication flow available.
10+
> For more information on authentication for apps deployed to test or production environments, see <xref:security/index#secure-authentication-flows>.
Lines changed: 58 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
---
2-
title: Enable QR code generation for TOTP authenticator apps in ASP.NET Core
2+
title: Enable QR code generation for TOTP authentication
33
ai-usage: ai-assisted
44
author: wadepickett
5-
description: Discover how to enable QR code generation for TOTP authenticator apps that work with ASP.NET Core two-factor authentication.
5+
description: Discover how to enable QR code generation for time-based one-time password (TOTP) authenticator apps that work with ASP.NET Core two-factor authentication.
66
monikerRange: '>= aspnetcore-2.1'
77
ms.author: wpickett
8-
ms.date: 04/21/2026
8+
ms.date: 05/14/2026
99
ms.reviewer: wpickett
1010
uid: security/authentication/identity-enable-qrcodes
11+
12+
# customer intent: As an ASP.NET developer, I want to enable QR code generation for TOTP authenticator apps, so I can support two-factor authentication.
1113
---
1214

1315
# Enable QR code generation for TOTP authenticator apps in ASP.NET Core
@@ -19,7 +21,7 @@ ASP.NET Core includes support for authenticator applications for individual auth
1921
- An authenticator app provides a 6 to 8 digit code that users enter after confirming their username and password.
2022
- Typically, users install an authenticator app on a smartphone.
2123

22-
> [!WARNING]
24+
> [!IMPORTANT]
2325
> Keep an ASP.NET Core TOTP code secret because it can be used to authenticate successfully multiple times before it expires.
2426
2527
:::moniker range=">= aspnetcore-8.0"
@@ -37,56 +39,59 @@ The ASP.NET Core web app templates support authenticators but don't provide supp
3739
3840
:::moniker-end
3941

40-
Two-factor authentication doesn't happen by using an external authentication provider, such as [Google](xref:security/authentication/google-logins) or [Facebook](xref:security/authentication/facebook-logins). External logins are protected by whatever mechanism the external login provider provides. For example, the [Microsoft](xref:security/authentication/microsoft-logins) authentication provider requires a hardware key or another 2FA approach. If the default templates required 2FA for both the web app and the external authentication provider, users would need to satisfy two 2FA approaches. Requiring two 2FA approaches deviates from established security practices, which typically rely on a single, strong 2FA method for authentication.
42+
Two-factor authentication doesn't happen by using an external authentication provider, such as [Google](xref:security/authentication/google-logins) or [Facebook](xref:security/authentication/facebook-logins). External sign ins are protected by whatever mechanism the external sign-in provider supports. For example, the [Microsoft](xref:security/authentication/microsoft-logins) authentication provider requires a hardware key or another 2FA approach. If the default templates required 2FA for both the web app and the external authentication provider, users need to satisfy two 2FA approaches. Requiring two 2FA approaches deviates from established security practices, which typically rely on a single, strong 2FA method for authentication.
4143

42-
## Adding QR codes to the 2FA configuration page
44+
## Add QR codes to the 2FA configuration page
4345

44-
These instructions use `qrcode.js` from the [https://davidshimjs.github.io/qrcodejs/](https://davidshimjs.github.io/qrcodejs/) repo.
46+
The following instructions use the _qrcode.js_ file from the [https://davidshimjs.github.io/qrcodejs/](https://davidshimjs.github.io/qrcodejs/) repo.
4547

46-
* Download the [`qrcode.js` JavaScript library](https://davidshimjs.github.io/qrcodejs/) to the `wwwroot\lib` folder in your project.
47-
* Follow the instructions in [Scaffold Identity](xref:security/authentication/scaffold-identity) to generate `/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml`.
48-
* In `/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml`, locate the `Scripts` section at the end of the file:
48+
1. Download the ['qrcode.js' JavaScript library](https://davidshimjs.github.io/qrcodejs/) to the _wwwroot\lib_ folder in your project.
4949

50-
```cshtml
51-
@section Scripts {
52-
<partial name="_ValidationScriptsPartial" />
53-
}
54-
```
55-
* Create a new JavaScript file called `qr.js` in `wwwroot/js` and add the following code to generate the QR code:
56-
57-
```javascript
58-
window.addEventListener("load", () => {
59-
const uri = document.getElementById("qrCodeData").getAttribute('data-url');
60-
new QRCode(document.getElementById("qrCode"),
61-
{
62-
text: uri,
63-
width: 150,
64-
height: 150
65-
});
66-
});
67-
```
50+
1. Follow the instructions in [Scaffold Identity](xref:security/authentication/scaffold-identity) to generate the _/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml_ file.
6851

69-
* Update the `Scripts` section to add a reference to the `qrcode.js` library you previously downloaded.
70-
* Add the `qr.js` file with the call to generate the QR code:
52+
1. In the _/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml_ file, locate the `Scripts` section at the end of the file:
7153

72-
```cshtml
73-
@section Scripts {
74-
<partial name="_ValidationScriptsPartial" />
54+
```cshtml
55+
@section Scripts {
56+
<partial name="_ValidationScriptsPartial" />
57+
}
58+
```
7559

76-
<script type="text/javascript" src="~/lib/qrcode.js"></script>
77-
<script type="text/javascript" src="~/js/qr.js"></script>
78-
}
79-
```
60+
1. Create a new JavaScript file named _qr.js_ in the _wwwroot/js_ folder, and add the following code that generates the QR code:
8061

81-
* Delete the paragraph that links you to these instructions.
62+
```javascript
63+
window.addEventListener("load", () => {
64+
const uri = document.getElementById("qrCodeData").getAttribute('data-url');
65+
new QRCode(document.getElementById("qrCode"),
66+
{
67+
text: uri,
68+
width: 150,
69+
height: 150
70+
});
71+
});
72+
```
8273

83-
Run your app and ensure that you can scan the QR code and validate the code the authenticator provides.
74+
1. Update the `Scripts` section to add a reference to the `qrcode.js` library you previously downloaded.
75+
76+
1. Add the _qr.js_ file with the call that generates the QR code:
77+
78+
```cshtml
79+
@section Scripts {
80+
<partial name="_ValidationScriptsPartial" />
81+
<script type="text/javascript" src="~/lib/qrcode.js"></script>
82+
<script type="text/javascript" src="~/js/qr.js"></script>
83+
}
84+
```
85+
86+
1. Delete the paragraph that links you to these instructions.
87+
88+
1. Run your app. Confirm you can scan the QR code and validate the code the authenticator provides.
8489

8590
## Change the site name in the QR code
8691

87-
The site name in the QR code comes from the project name you choose when initially creating your project. You can change it by looking for the `GenerateQrCodeUri(string email, string unformattedKey)` method in the `/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml.cs`.
92+
The site name in the QR code comes from the project name you select when you create your project. You can change it by looking for the `GenerateQrCodeUri(string email, string unformattedKey)` method in the _/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml.cs_ file.
8893

89-
The default code from the template looks as follows:
94+
Here's the default code from the template:
9095

9196
```csharp
9297
private string GenerateQrCodeUri(string email, string unformattedKey)
@@ -99,17 +104,22 @@ private string GenerateQrCodeUri(string email, string unformattedKey)
99104
}
100105
```
101106

102-
The second parameter in the call to `string.Format` is your site name, taken from your solution name. You can change it to any value, but it must always be URL encoded.
107+
The second parameter in the call to `string.Format` is your site name, which is obtained from your solution name. You can change it to any value, but it must always be URL encoded.
103108

104-
## Using a different QR code library
109+
## Use a different QR code library
105110

106111
You can replace the QR code library with your preferred library. The HTML contains a `qrCode` element into which you can place a QR code by whatever mechanism your library provides.
107112

108-
You can find the correctly formatted URL for the QR code in the:
113+
You can find the correctly formatted URL for the QR code in the following locations:
114+
115+
* `AuthenticatorUri` property of the model
116+
* `data-url` property in the `qrCodeData` element
117+
118+
## Check TOTP client and server times
109119

110-
* `AuthenticatorUri` property of the model.
111-
* `data-url` property in the `qrCodeData` element.
120+
TOTP (Time-based One-Time Password) authentication depends on both the server and authenticator device having an accurate time. Tokens only last for 30 seconds. If TOTP 2FA sign-in fails, confirm the server time is accurate, and preferably synchronized to an accurate NTP service.
112121

113-
## TOTP client and server time skew
122+
## Related content
114123

115-
TOTP (Time-based One-Time Password) authentication depends on both the server and authenticator device having an accurate time. Tokens only last for 30 seconds. If TOTP 2FA logins fail, check that the server time is accurate, and preferably synchronized to an accurate NTP service.
124+
- <xref:blazor/security/qrcodes-for-authenticator-apps>
125+
- <xref:blazor/security/webassembly/standalone-with-identity/qrcodes-for-authenticator-apps>

aspnetcore/security/data-protection/consumer-apis/password-hashing.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,19 @@ uid: security/data-protection/consumer-apis/password-hashing
1313

1414
This article shows how to call the [KeyDerivation.Pbkdf2](/dotnet/api/microsoft.aspnetcore.cryptography.keyderivation.keyderivation.pbkdf2) method, which allows hashing a password with the PBKDF2 algorithm, as described in [RFC 2898, Section 5.2](https://datatracker.ietf.org/doc/html/rfc2898#section-5.2).
1515

16+
The `KeyDerivation.Pbkdf2` API is a low-level cryptographic primitive. The intended use is for integrating apps into an existing protocol or cryptographic system.
17+
1618
> [!WARNING]
17-
> The `KeyDerivation.Pbkdf2` API is a low-level cryptographic primitive. The intended use is for integrating apps into an existing protocol or cryptographic system. `KeyDerivation.Pbkdf2` shouldn't be used in new apps that support password-based sign in and which need to store hashed passwords in a datastore. New apps should use the [PasswordHasher](/dotnet/api/microsoft.aspnetcore.identity.passwordhasher-1) class. For more information, see [Exploring the ASP.NET Core Identity PasswordHasher](https://andrewlock.net/exploring-the-asp-net-core-identity-passwordhasher/).
19+
> `KeyDerivation.Pbkdf2` shouldn't be used in new apps that support password-based sign in and which need to store hashed passwords in a datastore. New apps should use the [PasswordHasher](/dotnet/api/microsoft.aspnetcore.identity.passwordhasher-1) class. For more information, see [Exploring the ASP.NET Core Identity PasswordHasher](https://andrewlock.net/exploring-the-asp-net-core-identity-passwordhasher/).
1820
1921
The data protection code base includes a NuGet package [Microsoft.AspNetCore.Cryptography.KeyDerivation](https://www.nuget.org/packages/Microsoft.AspNetCore.Cryptography.KeyDerivation/) that contains cryptographic key derivation functions. This package is a standalone component and has no dependencies on the rest of the data protection system. The package can be used independently. The source exists alongside the data protection code base as a convenience.
2022

23+
## Generate key with 'KeyDerivation.Pbkdf2'
24+
25+
The following code shows how to use the `KeyDerivation.Pbkdf2` method to generate a shared secret key.
26+
2127
> [!WARNING]
22-
> The following code shows how to use `KeyDerivation.Pbkdf2` to generate a shared secret key. It shouldn't be used to hash a password for storage in a datastore.
28+
> Don't call the `KeyDerivation.Pbkdf2` method to hash a password for storage in a datastore.
2329
2430
<!-- See https://github.com/dotnet/AspNetCore.Docs/pull/26253#issuecomment-1187984822 for detailed reasoning -->
2531

0 commit comments

Comments
 (0)