or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication-components.mdevent-resolution.mdindex.mdprovider-selection.mdwebflow-actions.mdwebflow-configuration.mdwebflow-utilities.md

authentication-components.mddocs/

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

```