0
# Authentication Backends
1
2
Multiple authentication backend support including database, LDAP, OAuth, OpenID, and remote user authentication with configurable options and provider-specific implementations. Each backend provides comprehensive authentication capabilities tailored to different enterprise environments.
3
4
## Capabilities
5
6
### Database Authentication
7
8
Username/password authentication using the local database with password hashing and validation.
9
10
```python { .api }
11
def auth_user_db(self, username: str, password: str) -> User | None:
12
"""
13
Authenticate user using database credentials.
14
15
Parameters:
16
- username: Username or registered email address
17
- password: Plain text password to verify against hashed password
18
19
Returns:
20
User object if authentication successful, None otherwise
21
22
Features:
23
- Case-insensitive username matching (if configured)
24
- Email address login support
25
- Password hash verification using Werkzeug
26
- Brute force protection with fail counters
27
- Session ID rotation on successful login
28
"""
29
```
30
31
### LDAP Authentication
32
33
Enterprise LDAP and Active Directory authentication with extensive configuration options.
34
35
```python { .api }
36
def auth_user_ldap(self, username: str, password: str) -> User | None:
37
"""
38
Authenticate user using LDAP/Active Directory.
39
40
Parameters:
41
- username: LDAP username
42
- password: LDAP password
43
44
Returns:
45
User object if authentication successful, None otherwise
46
47
Features:
48
- Direct bind and indirect bind (search first) modes
49
- TLS/SSL support with certificate validation
50
- User attribute mapping (name, email, groups)
51
- Group-based role mapping
52
- User auto-registration from LDAP attributes
53
- Role synchronization at login
54
"""
55
```
56
57
### OAuth Authentication
58
59
OAuth 2.0 authentication supporting multiple providers with comprehensive provider integrations.
60
61
```python { .api }
62
def auth_user_oauth(self, userinfo: dict) -> User | None:
63
"""
64
Authenticate user using OAuth provider information.
65
66
Parameters:
67
- userinfo: Dictionary containing user information from OAuth provider
68
Keys should match User model columns (username, email, first_name, etc.)
69
70
Returns:
71
User object if authentication successful, None otherwise
72
73
Supported Providers:
74
- GitHub/GitHub Enterprise
75
76
- Microsoft Azure AD
77
- OpenShift
78
- Okta
79
- Keycloak
80
81
82
- Custom OAuth providers
83
"""
84
85
def get_oauth_user_info(self, provider: str, resp: dict) -> dict:
86
"""
87
Extract user information from OAuth provider response.
88
89
Parameters:
90
- provider: OAuth provider name ('github', 'google', 'azure', etc.)
91
- resp: OAuth provider response containing user data
92
93
Returns:
94
Dictionary with standardized user information:
95
- username: Unique username for the user
96
- email: User's email address
97
- first_name: User's first name (if available)
98
- last_name: User's last name (if available)
99
- role_keys: List of external role identifiers for role mapping
100
"""
101
```
102
103
### OpenID Authentication
104
105
OpenID authentication for identity provider integration.
106
107
```python { .api }
108
def auth_user_oid(self, email: str) -> User | None:
109
"""
110
Authenticate user using OpenID.
111
112
Parameters:
113
- email: User's email address from OpenID provider
114
115
Returns:
116
User object if authentication successful, None otherwise
117
118
Features:
119
- Email-based user identification
120
- Integration with Flask-OpenID
121
- User account validation and activation checks
122
"""
123
```
124
125
### Remote User Authentication
126
127
Authentication for users pre-authenticated by web server or proxy (e.g., Kerberos, SAML).
128
129
```python { .api }
130
def auth_user_remote_user(self, username: str) -> User | None:
131
"""
132
Authenticate user using remote user authentication.
133
134
Parameters:
135
- username: Username from remote authentication system (e.g., REMOTE_USER header)
136
137
Returns:
138
User object if authentication successful, None otherwise
139
140
Features:
141
- Trusted authentication from upstream systems
142
- User auto-registration with default role assignment
143
- No password verification (trust upstream authentication)
144
"""
145
```
146
147
## OAuth Provider Configurations
148
149
### GitHub Integration
150
151
```python { .api }
152
# GitHub OAuth configuration example
153
OAUTH_PROVIDERS = [{
154
'name': 'github',
155
'token_key': 'access_token',
156
'icon': 'fa-github',
157
'remote_app': {
158
'client_id': 'your_github_client_id',
159
'client_secret': 'your_github_client_secret',
160
'server_metadata_url': 'https://github.com/.well-known/oauth_authorization_server',
161
'client_kwargs': {
162
'scope': 'user:email'
163
}
164
}
165
}]
166
```
167
168
### Google OAuth Integration
169
170
```python { .api }
171
# Google OAuth configuration example
172
OAUTH_PROVIDERS = [{
173
'name': 'google',
174
'icon': 'fa-google',
175
'token_key': 'access_token',
176
'remote_app': {
177
'client_id': 'your_google_client_id',
178
'client_secret': 'your_google_client_secret',
179
'server_metadata_url': 'https://accounts.google.com/.well-known/openid_configuration',
180
'client_kwargs': {
181
'scope': 'openid email profile'
182
}
183
}
184
}]
185
```
186
187
### Azure AD Integration
188
189
```python { .api }
190
# Azure AD OAuth configuration example
191
OAUTH_PROVIDERS = [{
192
'name': 'azure',
193
'icon': 'fa-windows',
194
'token_key': 'access_token',
195
'remote_app': {
196
'client_id': 'your_azure_client_id',
197
'client_secret': 'your_azure_client_secret',
198
'server_metadata_url': 'https://login.microsoftonline.com/your_tenant_id/v2.0/.well-known/openid_configuration',
199
'client_kwargs': {
200
'scope': 'openid email profile'
201
}
202
}
203
}]
204
```
205
206
## LDAP Configuration Options
207
208
### Basic LDAP Setup
209
210
```python { .api }
211
# Basic LDAP configuration
212
AUTH_TYPE = AUTH_LDAP
213
AUTH_LDAP_SERVER = "ldap://ldap.company.com"
214
AUTH_LDAP_SEARCH = "ou=people,dc=company,dc=com"
215
AUTH_LDAP_UID_FIELD = "uid"
216
AUTH_LDAP_FIRSTNAME_FIELD = "givenName"
217
AUTH_LDAP_LASTNAME_FIELD = "sn"
218
AUTH_LDAP_EMAIL_FIELD = "mail"
219
```
220
221
### Advanced LDAP Configuration
222
223
```python { .api }
224
# Advanced LDAP with TLS and group mapping
225
AUTH_LDAP_USE_TLS = True
226
AUTH_LDAP_TLS_DEMAND = True
227
AUTH_LDAP_TLS_CACERTFILE = "/path/to/ca.crt"
228
AUTH_LDAP_BIND_USER = "cn=airflow,ou=service,dc=company,dc=com"
229
AUTH_LDAP_BIND_PASSWORD = "service_password"
230
AUTH_LDAP_SEARCH_FILTER = "(objectClass=person)"
231
AUTH_LDAP_GROUP_FIELD = "memberOf"
232
233
# Role mapping from LDAP groups
234
AUTH_ROLES_MAPPING = {
235
"cn=airflow-admins,ou=groups,dc=company,dc=com": ["Admin"],
236
"cn=airflow-users,ou=groups,dc=company,dc=com": ["User"],
237
}
238
```
239
240
## Authentication Flow Helpers
241
242
### Session Management
243
244
```python { .api }
245
def _rotate_session_id(self) -> None:
246
"""
247
Rotate session ID upon successful authentication when using database sessions.
248
Prevents session fixation attacks.
249
"""
250
251
def update_user_auth_stat(self, user: User, success: bool = True) -> None:
252
"""
253
Update user authentication statistics.
254
255
Parameters:
256
- user: User object to update
257
- success: Whether authentication was successful
258
259
Updates:
260
- login_count: Incremented on successful login
261
- last_login: Set to current timestamp on success
262
- fail_login_count: Incremented on failure, reset to 0 on success
263
"""
264
```
265
266
### Role Calculation
267
268
```python { .api }
269
def _ldap_calculate_user_roles(self, user_attributes: dict[str, list[bytes]]) -> list[Role]:
270
"""
271
Calculate user roles from LDAP attributes using AUTH_ROLES_MAPPING.
272
273
Parameters:
274
- user_attributes: LDAP user attributes dictionary
275
276
Returns:
277
List of Role objects for the user
278
"""
279
280
def _oauth_calculate_user_roles(self, userinfo: dict) -> list[Role]:
281
"""
282
Calculate user roles from OAuth userinfo using role_keys and AUTH_ROLES_MAPPING.
283
284
Parameters:
285
- userinfo: OAuth user information dictionary
286
287
Returns:
288
List of Role objects for the user
289
"""
290
291
def get_roles_from_keys(self, role_keys: list[str]) -> set[Role]:
292
"""
293
Map external role keys to internal roles using AUTH_ROLES_MAPPING.
294
295
Parameters:
296
- role_keys: List of external role identifiers
297
298
Returns:
299
Set of Role objects mapped from the keys
300
"""
301
```
302
303
## Configuration Constants
304
305
### Authentication Types
306
307
```python { .api }
308
AUTH_DB = 0 # Database authentication
309
AUTH_OID = 1 # OpenID authentication
310
AUTH_LDAP = 2 # LDAP authentication
311
AUTH_REMOTE_USER = 3 # Remote user authentication
312
AUTH_OAUTH = 4 # OAuth authentication
313
```
314
315
### Default Configuration Values
316
317
```python { .api }
318
# Default security configuration
319
AUTH_ROLE_ADMIN = "Admin"
320
AUTH_ROLE_PUBLIC = "Public"
321
AUTH_USER_REGISTRATION = False
322
AUTH_USER_REGISTRATION_ROLE = "Public"
323
AUTH_USERNAME_CI = True
324
AUTH_ROLES_SYNC_AT_LOGIN = False
325
AUTH_API_LOGIN_ALLOW_MULTIPLE_PROVIDERS = False
326
```
327
328
## Usage Examples
329
330
### Database Authentication Setup
331
332
```python
333
from airflow.www.fab_security.manager import AUTH_DB
334
335
# Configure database authentication
336
app.config['AUTH_TYPE'] = AUTH_DB
337
app.config['AUTH_ROLE_ADMIN'] = 'Admin'
338
app.config['AUTH_ROLE_PUBLIC'] = 'Viewer'
339
340
# Authenticate user
341
user = security_manager.auth_user_db('john_doe', 'password123')
342
if user:
343
print(f"Authenticated: {user.get_full_name()}")
344
```
345
346
### LDAP Authentication Setup
347
348
```python
349
from airflow.www.fab_security.manager import AUTH_LDAP
350
351
# Configure LDAP authentication
352
app.config.update({
353
'AUTH_TYPE': AUTH_LDAP,
354
'AUTH_LDAP_SERVER': 'ldaps://ldap.company.com:636',
355
'AUTH_LDAP_SEARCH': 'ou=employees,dc=company,dc=com',
356
'AUTH_LDAP_UID_FIELD': 'sAMAccountName',
357
'AUTH_LDAP_USE_TLS': True,
358
'AUTH_USER_REGISTRATION': True,
359
'AUTH_ROLES_SYNC_AT_LOGIN': True,
360
'AUTH_ROLES_MAPPING': {
361
'CN=AirflowAdmins,OU=Groups,DC=company,DC=com': ['Admin'],
362
'CN=AirflowUsers,OU=Groups,DC=company,DC=com': ['User']
363
}
364
})
365
366
# Authenticate LDAP user
367
user = security_manager.auth_user_ldap('john.doe', 'ldap_password')
368
```
369
370
### OAuth Authentication Setup
371
372
```python
373
from airflow.www.fab_security.manager import AUTH_OAUTH
374
375
# Configure OAuth with Google
376
app.config.update({
377
'AUTH_TYPE': AUTH_OAUTH,
378
'OAUTH_PROVIDERS': [{
379
'name': 'google',
380
'icon': 'fa-google',
381
'token_key': 'access_token',
382
'remote_app': {
383
'client_id': 'your_google_client_id',
384
'client_secret': 'your_google_client_secret',
385
'server_metadata_url': 'https://accounts.google.com/.well-known/openid_configuration',
386
'client_kwargs': {'scope': 'openid email profile'}
387
}
388
}]
389
})
390
391
# OAuth userinfo processing
392
oauth_userinfo = {
393
'username': 'google_123456789',
394
'email': 'john@company.com',
395
'first_name': 'John',
396
'last_name': 'Doe'
397
}
398
user = security_manager.auth_user_oauth(oauth_userinfo)
399
```
400
401
## Error Handling and Security
402
403
- **Failed Authentication**: All methods return `None` on failure and log appropriate messages
404
- **Brute Force Protection**: Failed login attempts are tracked per user
405
- **Session Security**: Session IDs are rotated on successful authentication
406
- **Password Security**: Database passwords are hashed using Werkzeug's secure methods
407
- **TLS Support**: LDAP connections support TLS encryption and certificate validation
408
- **Token Security**: OAuth tokens are securely stored in encrypted session cookies