Skip to content

Commit 53af04c

Browse files
authored
Merge pull request #6802 from umbraco/cms13/twoFactor
13: Updating steps for adding Two Factor Authentication for Members
2 parents fc20a9e + 6fd9f5b commit 53af04c

File tree

3 files changed

+63
-15
lines changed

3 files changed

+63
-15
lines changed
Loading
Loading

13/umbraco-cms/reference/security/two-factor-authentication.md

Lines changed: 63 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ description: >-
66

77
# Two-factor Authentication
88

9-
Two-factor authentication (2FA) for Umbraco members is activated by implementing an `ITwoFactorProvider` interface and registering the implementation. The implementation can use third-party packages to archive for example support for authentication apps like Microsoft- or Google Authentication App.
9+
This article includes guides for implementing two-factor authentication options for both backoffice users and website members:
10+
11+
* [Two-Factor Authentication for Members](#two-factor-authentication-for-members)
12+
* [Two-Factor Authentication for Users](#two-factor-authentication-for-users)
1013

1114
{% hint style="info" %}
1215

@@ -16,11 +19,26 @@ If you are using [Umbraco Cloud](https://umbraco.com/products/umbraco-cloud/), y
1619

1720
## Two-factor authentication for Members
1821

19-
Since Umbraco does not control how the UI is for member login and profile edit. The UI for 2FA is shipped as part of the snippets for macros. These can be used as a starting point, before styling the page as you would like.
22+
Two-factor authentication (2FA) for Umbraco members is activated by implementing an `ITwoFactorProvider` interface and registering the implementation. The implementation can use third-party packages to support authentication apps like the Microsoft- or Google Authentication Apps.
2023

21-
### Example implementation for Authenticator Apps for Members
24+
The following guide will take you through implementing an option for your website members to enable two-factor authentication.
2225

23-
In the following example, we will use the [GoogleAuthenticator NuGet Package](https://www.nuget.org/packages/GoogleAuthenticator/). Despite the name, this package works for both Google and Microsoft authenticator apps. It can be used to generate the QR code needed to activate the app for the website.
26+
{% hint style="info" %}
27+
A setup for members needs to be implemented on your website in order for you to follow this guide. This setup should include:
28+
29+
* Login and logout options.
30+
* Public access restriction configured on at least 1 content item.
31+
32+
[Learn more about setting up a members section in Umbraco.](../../tutorials/members-registration-and-login.md)
33+
{% endhint %}
34+
35+
As an example, the guide will use the [GoogleAuthenticator NuGet Package](https://www.nuget.org/packages/GoogleAuthenticator/). This package works for both Google and Microsoft authenticator apps. It can be used to generate the QR code needed to activate the app for the website.
36+
37+
1. Install the GoogleAuthenticator Nuget Package on your project.
38+
2. Create a new file in your project: `QrCodeSetupData.cs`.
39+
3. Update the file with the following code snippet.
40+
41+
{% code title="QrCodeSetupData.cs" lineNumbers="true" %}
2442

2543
```csharp
2644
using System;
@@ -39,12 +57,12 @@ public class QrCodeSetupData
3957
/// <summary>
4058
/// The secret unique code for the user and this ITwoFactorProvider.
4159
/// </summary>
42-
public string Secret { get; init; }
60+
public string? Secret { get; init; }
4361

4462
/// <summary>
4563
/// The SetupCode from the GoogleAuthenticator code.
4664
/// </summary>
47-
public SetupCode SetupCode { get; init; }
65+
public SetupCode? SetupCode { get; init; }
4866
}
4967

5068
/// <summary>
@@ -85,8 +103,9 @@ public class UmbracoAppAuthenticator : ITwoFactorProvider
85103
{
86104
var member = _memberService.GetByKey(userOrMemberKey);
87105

106+
var applicationName = "My Application Name";
88107
var twoFactorAuthenticator = new TwoFactorAuthenticator();
89-
SetupCode setupInfo = twoFactorAuthenticator.GenerateSetupCode("My application name", member.Username, secret, false);
108+
SetupCode setupInfo = twoFactorAuthenticator.GenerateSetupCode(applicationName, member.Username, secret, false);
90109
return Task.FromResult<object>(new QrCodeSetupData()
91110
{
92111
SetupCode = setupInfo,
@@ -111,15 +130,17 @@ public class UmbracoAppAuthenticator : ITwoFactorProvider
111130
}
112131
```
113132

114-
First, we create a model with the information required to set up the 2FA provider. Then we implement the `ITwoFactorProvider` with the use of the `TwoFactorAuthenticator` from the GoogleAuthenticator NuGet package.
133+
{% endcode %}
134+
135+
4. Update `namespace` on line 7 to match your project.
136+
5. Customize the `applicationName` variable on line 63.
137+
6. Create a Composer and register the `UmbracoAppAuthenticator` implementation as shown below.
115138

116-
Now we need to register the `UmbracoAppAuthenticator` implementation. This can be done on the `IUmbracoBuilder` in your startup or a composer.
139+
{% code title="UmbracoAppAuthenticatorComposer.cs" lineNumbers="true" %}
117140

118141
```csharp
119142
using Umbraco.Cms.Core.Composing;
120-
using Umbraco.Cms.Core.DependencyInjection;
121143
using Umbraco.Cms.Core.Security;
122-
using Umbraco.Extensions;
123144

124145
namespace My.Website;
125146

@@ -133,8 +154,18 @@ public class UmbracoAppAuthenticatorComposer : IComposer
133154
}
134155
```
135156

157+
{% endcode %}
158+
136159
At this point, the 2FA is active, but no members have set up 2FA yet. The setup of 2FA depends on the type. In the case of App Authenticator, we will add the following to our view showing the edit profile of the member.
137160

161+
7. Add or choose a members-only page that should have the two-factor authentication setup.
162+
* The page needs to be behind the public access.
163+
* The page should not be using strongly types models.
164+
8. Open the view file for the selected page.
165+
9. Add the following code:
166+
167+
{% code title="ExampleMembersPage.cshtml" lineNumbers="true" %}
168+
138169
```csharp
139170
@using Umbraco.Cms.Core.Services
140171
@using Umbraco.Cms.Web.Website.Controllers
@@ -143,7 +174,7 @@ At this point, the 2FA is active, but no members have set up 2FA yet. The setup
143174
@inject MemberModelBuilderFactory memberModelBuilderFactory
144175
@inject ITwoFactorLoginService twoFactorLoginService
145176
@{
146-
// Build a profile model to edit
177+
// Build a profile model to edit, by fetching the member's unique key.
147178
var profileModel = await memberModelBuilderFactory
148179
.CreateProfileModel()
149180
.BuildForCurrentMemberAsync();
@@ -153,9 +184,13 @@ At this point, the 2FA is active, but no members have set up 2FA yet. The setup
153184
if (providerNames.Any())
154185
{
155186
<div asp-validation-summary="All" class="text-danger"></div>
187+
156188
foreach (var providerName in providerNames)
157189
{
158190
var setupData = await twoFactorLoginService.GetSetupInfoAsync(profileModel.Key, providerName);
191+
192+
// If the `setupData` is `null` for the specified `providerName` it means the provider is already set up.
193+
// In this case, a button to disable the authentication is shown.
159194
if (setupData is null)
160195
{
161196
@using (Html.BeginUmbracoForm<UmbTwoFactorLoginController>(nameof(UmbTwoFactorLoginController.Disable)))
@@ -164,6 +199,7 @@ At this point, the 2FA is active, but no members have set up 2FA yet. The setup
164199
<button type="submit">Disable @providerName</button>
165200
}
166201
}
202+
// If `setupData` is not `null` the type is checked and the UI for how to set up the App Authenticator is shown.
167203
else if(setupData is QrCodeSetupData qrCodeSetupData)
168204
{
169205
@using (Html.BeginUmbracoForm<UmbTwoFactorLoginController>(nameof(UmbTwoFactorLoginController.ValidateAndSaveSetup)))
@@ -182,11 +218,23 @@ At this point, the 2FA is active, but no members have set up 2FA yet. The setup
182218
}
183219
```
184220

185-
In this razor-code sample, we get the current member's unique key and list all registered `ITwoFactorProvider` implementations.
221+
10. [Optional] Customize the text fields and buttons to match your websites tone of voice.
222+
223+
{% endcode %}
224+
225+
![The QR Code is shown along with a field to enter a value to set up the two factor authentication.](images/2fa-Members-QR-code.png)
226+
227+
### Test the set up
228+
229+
1. Login to the website using a test member.
230+
2. Navigate to the page where the QR code was added.
231+
3. Scan the QR code and add the verification code.
232+
4. Logout of the website.
233+
5. Login and verify that it asks for the two factor authentication.
186234

187-
If the `setupData` is `null` for the specified `providerName` it means the provider is already set up. In this case, we show a disable button. Otherwise, we check the type and show the UI for how to set up the App Authenticator. We will show the QR Code and an input field to validate the code from the App Authenticator.
235+
You can also check that the **Two-factor Authentication** option is checked on the member in the Umbraco backoffice.
188236

189-
The last part required is to use the `Login` Partial Macro snippet.
237+
![Check the Member profile in the Umbraco backoffice to verify whether two-factor authentication is enabeld.](images/2fa-member-backoffice.png)
190238

191239
### Notification when 2FA is requested for a member
192240

0 commit comments

Comments
 (0)