Skip to content

Commit b6bd78d

Browse files
committed
Add OIDC authentication documentation and update related resources
Introduced a comprehensive OIDC implementation guide (doc/OIDC_Implementation.md) and linked it from the documentation index and setup guide. Updated environment variable examples and explanations in doc/Setup.md for OIDC configuration. Improved resource strings and logging for OIDC user management, including clarifying admin actions required for existing accounts and moving OIDC-related messages between resource files.
1 parent 1450324 commit b6bd78d

File tree

6 files changed

+214
-12
lines changed

6 files changed

+214
-12
lines changed

Resources/SharedResource.en-GB.resx

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,4 @@
172172
<data name="EMLFormatDescription" xml:space="preserve">
173173
<value>Creates individual .eml files organised in folders.</value>
174174
</data>
175-
<data name="OidcUserCannotHavePassword" xml:space="preserve">
176-
<value>OIDC users cannot have a password. They authenticate through the OIDC provider.</value>
177-
</data>
178-
<data name="OidcUserCannotChangeUsername" xml:space="preserve">
179-
<value>OIDC user usernames cannot be changed as they are linked to the OIDC provider identity.</value>
180-
</data>
181-
<data name="OidcUserCannotChangePassword" xml:space="preserve">
182-
<value>OIDC users cannot change their password. Password management is handled by your OIDC provider.</value>
183-
</data>
184175
</root>

Resources/SharedResource.resx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2347,8 +2347,17 @@
23472347
<data name="SignInWithOAuth" xml:space="preserve">
23482348
<value>Login with OAuth</value>
23492349
</data>
2350+
<data name="OidcUserCannotHavePassword" xml:space="preserve">
2351+
<value>OIDC users cannot have a password. They authenticate through the OIDC provider.</value>
2352+
</data>
2353+
<data name="OidcUserCannotChangeUsername" xml:space="preserve">
2354+
<value>OIDC user usernames cannot be changed as they are linked to the OIDC provider identity.</value>
2355+
</data>
2356+
<data name="OidcUserCannotChangePassword" xml:space="preserve">
2357+
<value>OIDC users cannot change their password. Password management is handled by your OIDC provider.</value>
2358+
</data>
23502359
<data name="OidcAccountAlreadyExists" xml:space="preserve">
2351-
<value>An account with this email already exists. Please login with your password and link your OIDC account in your profile settings.</value>
2360+
<value>An account with this email already exists. Please contact your administrator to remove or modify the existing local account before using OIDC authentication.</value>
23522361
</data>
23532362
<data name="OidcAccountPendingApproval" xml:space="preserve">
23542363
<value>Your account is pending admin approval. Please contact an administrator.</value>
@@ -2362,4 +2371,4 @@
23622371
<data name="OidcClaimLengthExceeded" xml:space="preserve">
23632372
<value>Claim values exceed maximum allowed length</value>
23642373
</data>
2365-
</root>
2374+
</root>

Services/UserService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public async Task<User> GetOrCreateUserFromRemoteIdentity(
8484

8585
if (existingEmailUser != null)
8686
{
87-
_logger.LogWarning("OIDC login attempted with email {Email} that already exists for user {Username}. Automatic linking is disabled for security. User must manually link their account.",
87+
_logger.LogWarning("OIDC login attempted with email {Email} that already exists for user {Username}. Automatic linking is disabled for security. Administrator must remove or modify the existing local account before using OIDC authentication.",
8888
email, existingEmailUser.Username);
8989
throw new InvalidOperationException(_localizer["OidcAccountAlreadyExists"]);
9090
}

doc/Index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Mail Archiver is a comprehensive application designed to archive emails from var
1818
### ⚙️ Configuration & Usage
1919
- [Access Logging](Logs.md)
2020
- [Docker Compose Logs Guide](DockerComposeLogs.md)
21+
- [OpenID Connect (OIDC) Authentication](OIDC_Implementation.md)
2122
- [Retention Policies](RetentionPolicies.md)
2223
- [Mailbox Migration](MailboxMigration.md)
2324
- [Mail Search Guide](Search.md)

doc/OIDC_Implementation.md

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
# 🔐 OpenID Connect (OIDC) Authentication Guide
2+
3+
[← Back to Documentation Index](Index.md)
4+
5+
## 📋 Overview
6+
7+
This guide provides comprehensive instructions for setting up OpenID Connect (OIDC) authentication in the Mail Archiver application, with specific examples for Microsoft Entra ID (Azure AD) integration. OIDC enables secure single sign-on (SSO) authentication using external identity providers.
8+
9+
## 📚 Table of Contents
10+
11+
1. [Overview](#overview)
12+
2. [Prerequisites](#prerequisites)
13+
3. [OIDC Configuration](#oidc-configuration)
14+
- [Enable OIDC in Configuration](#enable-oidc-in-configuration)
15+
- [Environment Variables](#environment-variables)
16+
4. [Microsoft Entra ID Setup](#microsoft-entra-id-setup)
17+
- [Create App Registration](#create-app-registration)
18+
- [Configure Authentication](#configure-authentication)
19+
- [Set Token Configuration](#set-token-configuration)
20+
5. [Testing and Validation](#testing-and-validation)
21+
6. [User Management with OIDC](#user-management-with-oidc)
22+
7. [Troubleshooting](#troubleshooting)
23+
24+
## 🌐 Overview
25+
26+
The Mail Archiver application supports OpenID Connect (OIDC) authentication, allowing users to authenticate using external identity providers such as Microsoft Entra ID and other OIDC-compliant providers. This feature enhances security by leveraging enterprise identity management systems and enables single sign-on (SSO) capabilities.
27+
28+
## 🛠️ Prerequisites
29+
30+
- Administrative access to your chosen OIDC identity provider (e.g., Microsoft Entra ID)
31+
- Mail Archiver application already deployed and accessible via HTTPS
32+
- DNS name configured for your Mail Archiver instance (required for callback URLs)
33+
- Administrative access to the Mail Archiver application and host system for configuration
34+
35+
## ⚙️ OIDC Configuration
36+
37+
### Enable OIDC in Configuration
38+
39+
To enable OIDC authentication, you need to configure the OAuth section in your `appsettings.json` file or environment variables for the docker deployment (see [Installation and Setup](Setup.md)).
40+
41+
#### Example Configuration (appsettings.json)
42+
43+
```json
44+
{
45+
"OAuth": {
46+
"Enabled": true,
47+
"Authority": "https://sts.windows.net/{TENANT-ID}/",
48+
"ClientId": "YOUR-CLIENT-ID",
49+
"ClientSecret": "YOUR-CLIENT-SECRET",
50+
"ClientScopes": [
51+
"openid",
52+
"profile",
53+
"email"
54+
]
55+
}
56+
}
57+
```
58+
59+
### Environment Variables
60+
61+
When using Docker Compose or environment variables, configure the following variables in your `docker-compose.yml` file under the `mailarchive-app` service environment section:
62+
63+
```yaml
64+
environment:
65+
# OIDC Configuration
66+
- OAuth__Enabled=true
67+
- OAuth__Authority=https://sts.windows.net/{TENANT-ID}/
68+
- OAuth__ClientId=YOUR-CLIENT-ID
69+
- OAuth__ClientSecret=YOUR-CLIENT-SECRET
70+
- OAuth__ClientScopes__0=openid
71+
- OAuth__ClientScopes__1=profile
72+
- OAuth__ClientScopes__2=email
73+
```
74+
75+
### Configuration Parameters Explained
76+
77+
- **OAuth__Enabled**: Set to `true` to enable OIDC authentication
78+
- **OAuth__Authority**: The OpenID Connect authority URL of your identity provider
79+
- **OAuth__ClientId**: The client ID assigned by your identity provider
80+
- **OAuth__ClientSecret**: The client secret assigned by your identity provider
81+
- **OAuth__ClientScopes**: Array of scopes requested from the identity provider
82+
83+
> ⚠️ **Important**: The Client Secret should be kept secure. Use Docker secrets or environment variables in production environments.
84+
85+
## ☁️ Microsoft Entra ID Setup
86+
87+
This section provides step-by-step instructions for configuring Microsoft Entra ID (formerly Azure AD) as an OIDC identity provider for Mail Archiver.
88+
89+
### 🚀 Create App Registration
90+
91+
1. Navigate to the [Microsoft Entra Admin Center](https://entra.microsoft.com)
92+
2. Sign in with your administrator account
93+
3. In the left navigation pane, select **App registrations**
94+
4. Click **+ New registration** at the top of the App registrations page
95+
5. Fill in the following details:
96+
- **Name**: Enter a descriptive name (e.g., "Mail Archiver OIDC")
97+
- **Supported account types**: Select **Accounts in this organizational directory only**
98+
- **Redirect URI**: Select **Web** and enter your Mail Archiver callback URL:
99+
```
100+
https://your-mail-archiver-domain/oidc-signin-completed
101+
```
102+
Replace `your-mail-archiver-domain` with your actual domain (e.g., `mailarchiver.example.com`)
103+
104+
6. Click **Register**
105+
106+
### 🔐 Configure Authentication
107+
108+
1. After registration, note down the following values from the **Overview** page:
109+
- **Application (client) ID** - You'll need this as `OAuth__ClientId`
110+
- **Directory (tenant) ID** - You'll need this in the Authority URL
111+
112+
2. In the left menu, select **Authentication**
113+
3. Click **Settings**
114+
4. Under **Implicit grant and hybrid flows**, ensure **ID tokens** is checked
115+
5. Under **Supported account types**, verify your selection matches your requirements
116+
6. Under **Redirect URIs**, ensure your callback URL is listed correctly
117+
118+
### 🎯 Configure API Permissions
119+
120+
1. In the left menu, select **API permissions**
121+
2. Click **+ Add a permission**
122+
3. Select **Microsoft Graph**
123+
4. Choose **Delegated permissions**
124+
5. Add the following permissions (if needed for additional features):
125+
- **openid** - Sign users in
126+
- **email** - View users' email address
127+
- **profile** - View users' basic profile
128+
6. Click **Add permissions**
129+
7. Click **Grant admin consent for [Your Organization]** if you want to pre-authorize the application
130+
131+
### 🔑 Generate Client Secret
132+
133+
1. Navigate to **Certificates & secrets** in the left menu
134+
2. Under **Client secrets**, click **+ New client secret**
135+
3. Provide a description (e.g., "Mail Archiver Auth Secret")
136+
4. Select an expiration period
137+
5. Click **Add**
138+
6. **Important**: Copy the **Value** immediately and store it securely. This secret will not be shown again. It's needed as the `OAuth__ClientSecret`
139+
140+
## 🧪 Testing and Validation
141+
142+
### Initial Setup Testing
143+
144+
1. Restart your Mail Archiver application after configuring OIDC settings
145+
2. Navigate to your Mail Archiver login page
146+
3. You should see a new "Login with OAuth" button alongside the regular login form
147+
4. Click the "Login with OAuth" button to initiate the OIDC flow
148+
5. You should be redirected to your identity provider's login page
149+
6. After successful authentication, you should be redirected back to Mail Archiver
150+
151+
### User Provisioning Validation
152+
153+
- First-time OIDC users will be automatically created in the Mail Archiver database
154+
- Users will be created with the default "User" role and will need admin approval for access
155+
156+
## 👥 User Management with OIDC
157+
158+
### User Roles and Permissions
159+
160+
OIDC users follow the same role-based access control as local users:
161+
- **Admin**: Full system access (requires manual assignment by existing admin)
162+
- **User**: Standard user access to assigned mail accounts
163+
- **Self-Manager**: Can manage their own account and add new accounts
164+
165+
### Password Management
166+
167+
OIDC users cannot have or change passwords within Mail Archiver since authentication is handled by the external identity provider:
168+
- The "Change Password" option will be disabled for OIDC users
169+
- Password reset must be handled through the OIDC provider
170+
- Local password fields will remain empty for OIDC users
171+
172+
---
173+
174+
**Note**: This guide is current as of 2025. Identity provider services regularly update their interfaces and features, so some UI elements may differ. Always refer to the latest documentation from your identity provider for the most up-to-date information.

doc/Setup.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,18 @@ services:
7070
- Logging__LogLevel__Default=Information
7171
- Logging__LogLevel__Microsoft_AspNetCore=Warning
7272
- Logging__LogLevel__Microsoft_EntityFrameworkCore_Database_Command=Warning
73+
74+
# Security Settings
75+
- AllowedHosts=mailarchiver.example.com;www.mailarchiver.example.com
76+
77+
# OIDC Configuration (see OIDC_Implementation.md for detailed setup)
78+
- OAuth__Enabled=true
79+
- OAuth__Authority=https://example.com
80+
- OAuth__ClientId=YOUR-CLIENT-ID
81+
- OAuth__ClientSecret=YOUR-CLIENT-SECRET
82+
- OAuth__ClientScopes__0=openid
83+
- OAuth__ClientScopes__1=profile
84+
- OAuth__ClientScopes__2=email
7385
ports:
7486
- "5000:5000"
7587
networks:
@@ -183,6 +195,21 @@ docker compose restart
183195
- `Logging__LogLevel__Microsoft_AspNetCore`: Log level for ASP.NET Core framework messages. Default is `Warning`.
184196
- `Logging__LogLevel__Microsoft_EntityFrameworkCore_Database_Command`: Log level for Entity Framework database commands. Default is `Warning`.
185197

198+
### 🛡️ Security Settings
199+
- `AllowedHosts`: A semicolon-separated list of host names that the application is allowed to serve. This helps prevent HTTP Host header attacks. Example: `AllowedHosts=mailarchiver.example.com;www.mailarchiver.example.com`. **Important**: Do not use `*` in production environments as it disables host header validation.
200+
201+
### 🔐 OIDC Configuration
202+
203+
For detailed setup instructions for OpenID Connect authentication, see [OIDC Implementation Guide](OIDC_Implementation.md).
204+
205+
- `OAuth__Enabled`: Enable or disable OIDC authentication (true/false)
206+
- `OAuth__Authority`: The OpenID Connect authority URL (e.g., https://sts.windows.net/{TENANT-ID}/ for Azure AD)
207+
- `OAuth__ClientId`: The client ID assigned by your identity provider
208+
- `OAuth__ClientSecret`: The client secret assigned by your identity provider
209+
- `OAuth__ClientScopes__0`: First scope requested from the identity provider (openid)
210+
- `OAuth__ClientScopes__1`: Second scope requested from the identity provider (profile)
211+
- `OAuth__ClientScopes__2`: Third scope requested from the identity provider (email)
212+
186213
## 🔐 Kestrel HTTPS Configuration (Optional)
187214

188215
While the application is meant to be accessed through a reverse proxy with HTTPS, you can also configure the Kestrel web server to use SSL/TLS certificates. This provides end-to-end encryption between the reverse proxy and the application container.

0 commit comments

Comments
 (0)