0
# Authentication Components
1
2
Core authentication and provider selection logic including selectors, resolvers, and transaction management components. These components handle the orchestration of MFA providers, authentication context management, and provider selection strategies.
3
4
## Capabilities
5
6
### MultifactorAuthenticationProviderSelector Components
7
8
Components responsible for selecting appropriate MFA providers from available options based on various criteria.
9
10
#### RankedMultifactorAuthenticationProviderSelector
11
12
Selects MFA providers based on ranking/priority order.
13
14
```java { .api }
15
/**
16
* Selects MFA providers based on ranking/priority order
17
*/
18
public class RankedMultifactorAuthenticationProviderSelector
19
implements MultifactorAuthenticationProviderSelector {
20
21
/**
22
* Constructor
23
*/
24
public RankedMultifactorAuthenticationProviderSelector();
25
26
/**
27
* Resolve appropriate MFA provider from available providers
28
* @param providers Collection of available MFA providers
29
* @param service Service being accessed (can be null)
30
* @param principal Principal requesting authentication
31
* @return Selected MultifactorAuthenticationProvider or null if none suitable
32
*/
33
@Override
34
public MultifactorAuthenticationProvider resolve(
35
Collection<MultifactorAuthenticationProvider> providers,
36
RegisteredService service,
37
Principal principal);
38
39
/**
40
* Select multifactor authentication provider for service
41
* @param service Service being accessed
42
* @param providers List of available providers
43
* @return Selected provider or null
44
*/
45
protected MultifactorAuthenticationProvider selectMultifactorAuthenticationProvider(
46
RegisteredService service,
47
List<MultifactorAuthenticationProvider> providers);
48
}
49
```
50
51
#### ChainingMultifactorAuthenticationProviderSelector
52
53
Creates chaining MFA providers when multiple providers are available.
54
55
```java { .api }
56
/**
57
* Creates chaining MFA providers when multiple providers are available
58
*/
59
public class ChainingMultifactorAuthenticationProviderSelector
60
implements MultifactorAuthenticationProviderSelector {
61
62
/**
63
* Constructor
64
* @param applicationContext Spring application context
65
* @param failureModeEvaluator Evaluator for handling failure modes
66
*/
67
public ChainingMultifactorAuthenticationProviderSelector(
68
ConfigurableApplicationContext applicationContext,
69
MultifactorAuthenticationFailureModeEvaluator failureModeEvaluator);
70
71
/**
72
* Resolve chaining provider from available providers
73
* @param providers Collection of available MFA providers
74
* @param service Service being accessed
75
* @param principal Principal requesting authentication
76
* @return Chaining provider or selected single provider
77
*/
78
@Override
79
public MultifactorAuthenticationProvider resolve(
80
Collection<MultifactorAuthenticationProvider> providers,
81
RegisteredService service,
82
Principal principal);
83
84
/**
85
* Select multifactor authentication provider for service (protected method)
86
* @param service Service being accessed
87
* @param providers List of available providers
88
* @return Selected provider
89
*/
90
protected MultifactorAuthenticationProvider selectMultifactorAuthenticationProvider(
91
RegisteredService service,
92
List<MultifactorAuthenticationProvider> providers);
93
}
94
```
95
96
#### GroovyScriptMultifactorAuthenticationProviderSelector
97
98
MFA provider selector that uses Groovy scripts for custom selection logic.
99
100
```java { .api }
101
/**
102
* MFA provider selector using Groovy scripts for custom selection logic
103
*/
104
public class GroovyScriptMultifactorAuthenticationProviderSelector
105
implements MultifactorAuthenticationProviderSelector {
106
107
/**
108
* Constructor
109
* @param groovyResource Resource containing the Groovy script
110
*/
111
public GroovyScriptMultifactorAuthenticationProviderSelector(Resource groovyResource);
112
113
/**
114
* Resolve provider using Groovy script logic
115
* @param providers Collection of available MFA providers
116
* @param service Service being accessed
117
* @param principal Principal requesting authentication
118
* @return Provider selected by Groovy script or null
119
*/
120
@Override
121
public MultifactorAuthenticationProvider resolve(
122
Collection<MultifactorAuthenticationProvider> providers,
123
RegisteredService service,
124
Principal principal);
125
}
126
```
127
128
**Groovy Script Example:**
129
130
```groovy
131
// Example Groovy script for custom provider selection
132
// Script receives: providers, service, principal, logger
133
134
import org.apereo.cas.authentication.MultifactorAuthenticationProvider
135
136
// Custom selection logic
137
def userAttributes = principal.getAttributes()
138
def userRole = userAttributes.get("role")
139
140
if (userRole?.contains("admin")) {
141
// Admins get highest security provider
142
return providers.find { it.getId() == "yubikey" } ?: providers.first()
143
} else if (service?.getServiceId()?.contains("banking")) {
144
// Banking services require specific provider
145
return providers.find { it.getId() == "sms" }
146
} else {
147
// Default to lowest friction provider
148
return providers.min { it.getOrder() }
149
}
150
```
151
152
### Authentication Transaction Management
153
154
#### FinalMultifactorAuthenticationTransactionWebflowEventResolver
155
156
Final resolver that handles authentication transaction completion and ticket granting.
157
158
```java { .api }
159
/**
160
* Final resolver handling authentication transaction completion and ticket granting
161
*/
162
public class FinalMultifactorAuthenticationTransactionWebflowEventResolver
163
extends BaseMultifactorAuthenticationProviderEventResolver {
164
165
/**
166
* Constructor
167
* @param webflowEventResolutionConfigurationContext Configuration context
168
*/
169
public FinalMultifactorAuthenticationTransactionWebflowEventResolver(
170
CasWebflowEventResolutionConfigurationContext webflowEventResolutionConfigurationContext);
171
172
/**
173
* Resolve events for transaction completion
174
* @param context The webflow request context
175
* @return Set of resolved events for transaction completion
176
*/
177
@Override
178
public Set<Event> resolveInternal(RequestContext context);
179
180
/**
181
* Resolve single event for transaction completion (audited method)
182
* @param context The webflow request context
183
* @return Single resolved event for transaction completion
184
*/
185
@Audit(action = AuditableActions.AUTHENTICATION_EVENT_RESOLVED,
186
actionResolverName = AuditActionResolvers.AUTHENTICATION_EVENT_RESOLVED_ACTION_RESOLVER,
187
resourceResolverName = AuditResourceResolvers.AUTHENTICATION_EVENT_RESOLVED_RESOURCE_RESOLVER)
188
public Event resolveSingle(RequestContext context);
189
}
190
```
191
192
**Configuration Examples:**
193
194
```java
195
@Configuration
196
public class MfaProviderSelectionConfiguration {
197
198
@Bean
199
@ConditionalOnMissingBean(name = "multifactorAuthenticationProviderSelector")
200
public MultifactorAuthenticationProviderSelector multifactorAuthenticationProviderSelector() {
201
return new RankedMultifactorAuthenticationProviderSelector();
202
}
203
204
@Bean
205
@ConditionalOnProperty(name = "cas.authn.mfa.provider-selector.groovy.location")
206
public MultifactorAuthenticationProviderSelector groovyProviderSelector(
207
@Value("${cas.authn.mfa.provider-selector.groovy.location}") Resource groovyScript) {
208
return new GroovyScriptMultifactorAuthenticationProviderSelector(groovyScript);
209
}
210
211
@Bean
212
@ConditionalOnProperty(name = "cas.authn.mfa.provider-selector.chaining.enabled", havingValue = "true")
213
public MultifactorAuthenticationProviderSelector chainingProviderSelector(
214
ConfigurableApplicationContext applicationContext,
215
MultifactorAuthenticationFailureModeEvaluator failureModeEvaluator) {
216
return new ChainingMultifactorAuthenticationProviderSelector(applicationContext, failureModeEvaluator);
217
}
218
}
219
```
220
221
### Provider Selection Usage Patterns
222
223
#### Custom Provider Selection Logic
224
225
```java
226
@Component
227
public class CustomProviderSelectionLogic {
228
229
@Bean
230
public MultifactorAuthenticationProviderSelector customProviderSelector() {
231
return new CustomProviderSelector();
232
}
233
234
private static class CustomProviderSelector implements MultifactorAuthenticationProviderSelector {
235
236
@Override
237
public MultifactorAuthenticationProvider resolve(
238
Collection<MultifactorAuthenticationProvider> providers,
239
RegisteredService service,
240
Principal principal) {
241
242
// Example: Select based on user attributes
243
val userAttributes = principal.getAttributes();
244
val department = userAttributes.get("department");
245
246
if (department != null && department.contains("finance")) {
247
// Finance users get hardware tokens
248
return providers.stream()
249
.filter(p -> "yubikey".equals(p.getId()))
250
.findFirst()
251
.orElse(null);
252
}
253
254
// Example: Select based on service properties
255
if (service != null) {
256
val serviceProperties = service.getProperties();
257
val requiredMfa = serviceProperties.get("requiredMfaProvider");
258
if (requiredMfa != null) {
259
return providers.stream()
260
.filter(p -> requiredMfa.getValue().equals(p.getId()))
261
.findFirst()
262
.orElse(null);
263
}
264
}
265
266
// Default: Select highest ranked available provider
267
return providers.stream()
268
.min(Comparator.comparing(MultifactorAuthenticationProvider::getOrder))
269
.orElse(null);
270
}
271
}
272
}
273
```
274
275
#### Transaction Completion Handling
276
277
```java
278
@Configuration
279
public class MfaTransactionConfiguration {
280
281
@Bean
282
public CasWebflowEventResolver finalMultifactorAuthenticationTransactionEventResolver(
283
@Qualifier("casWebflowConfigurationContext")
284
CasWebflowEventResolutionConfigurationContext context) {
285
return new FinalMultifactorAuthenticationTransactionWebflowEventResolver(context);
286
}
287
288
@EventListener
289
public void handleMfaTransactionCompletion(MultifactorAuthenticationTransactionCompleteEvent event) {
290
val authentication = event.getAuthentication();
291
val service = event.getService();
292
293
// Custom logic after MFA transaction completion
294
logger.info("MFA transaction completed for user {} accessing service {}",
295
authentication.getPrincipal().getId(),
296
service != null ? service.getId() : "unknown");
297
298
// Additional processing like audit logging, metrics, etc.
299
}
300
}
301
```
302
303
### Integration with Authentication Context
304
305
The authentication components integrate with the broader CAS authentication context:
306
307
```java
308
// Example of using components in authentication flow
309
public class CustomAuthenticationHandler implements AuthenticationHandler {
310
311
private final MultifactorAuthenticationProviderSelector providerSelector;
312
313
public CustomAuthenticationHandler(MultifactorAuthenticationProviderSelector providerSelector) {
314
this.providerSelector = providerSelector;
315
}
316
317
@Override
318
public AuthenticationHandlerExecutionResult authenticate(Credential credential) throws GeneralSecurityException {
319
// During authentication, select appropriate MFA provider
320
val availableProviders = getAvailableMfaProviders();
321
val service = getServiceFromContext();
322
val principal = extractPrincipal(credential);
323
324
val selectedProvider = providerSelector.resolve(availableProviders, service, principal);
325
326
if (selectedProvider != null) {
327
// Store selected provider for webflow to use
328
storeSelectedProvider(selectedProvider);
329
}
330
331
return createSuccessfulAuthenticationResult(credential);
332
}
333
}
334
```