or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdspring-integration.mdtenant-extraction.mdtenant-management.mdtenant-policies.md

tenant-extraction.mddocs/

0

# Tenant Extraction

1

2

System for extracting tenant context from HTTP requests using configurable URL patterns and request processing. This enables automatic tenant identification based on request characteristics, particularly URL structure.

3

4

## Capabilities

5

6

### TenantExtractor Interface

7

8

Core interface for extracting tenant information from various request contexts.

9

10

```java { .api }

11

/**

12

* Interface for extracting tenant information from requests

13

*/

14

public interface TenantExtractor {

15

String BEAN_NAME = "tenantExtractor";

16

Pattern PATTERN_TENANTS = Pattern.compile("tenants/(.+)/(.+)", Pattern.CASE_INSENSITIVE);

17

18

/**

19

* Get the associated tenants manager

20

* @return TenantsManager instance used for tenant lookups

21

*/

22

TenantsManager getTenantsManager();

23

24

/**

25

* Extract tenant definition from HTTP servlet request

26

* Uses the request's flow ID to determine tenant context

27

* @param request HttpServletRequest to extract tenant from

28

* @return Optional containing tenant definition if found

29

*/

30

default Optional<TenantDefinition> extract(HttpServletRequest request);

31

32

/**

33

* Extract tenant definition from Spring WebFlow request context

34

* @param requestContext Spring WebFlow RequestContext

35

* @return Optional containing tenant definition if found

36

*/

37

default Optional<TenantDefinition> extract(RequestContext requestContext);

38

39

/**

40

* Extract tenant definition from request path string

41

* @param requestPath the request path to analyze

42

* @return Optional containing tenant definition if found

43

*/

44

Optional<TenantDefinition> extract(String requestPath);

45

46

/**

47

* Static utility method to extract tenant ID from path string

48

* Uses PATTERN_TENANTS regex to find tenant ID in URL structure

49

* @param requestPath the request path to analyze

50

* @return tenant ID string if found, null otherwise

51

*/

52

static String tenantIdFromPath(String requestPath);

53

}

54

```

55

56

### DefaultTenantExtractor Implementation

57

58

Default implementation of TenantExtractor that uses CAS configuration properties to control extraction behavior.

59

60

```java { .api }

61

/**

62

* Default implementation of TenantExtractor

63

* Uses CAS configuration properties to determine extraction behavior

64

*/

65

public class DefaultTenantExtractor implements TenantExtractor {

66

67

/**

68

* Constructor requiring tenants manager and CAS configuration

69

* @param tenantsManager TenantsManager for tenant lookups

70

* @param casProperties CAS configuration properties controlling extraction behavior

71

*/

72

public DefaultTenantExtractor(TenantsManager tenantsManager, CasConfigurationProperties casProperties);

73

74

/**

75

* Get the tenants manager (inherited from TenantExtractor)

76

* @return TenantsManager instance

77

*/

78

@Override

79

public TenantsManager getTenantsManager();

80

81

/**

82

* Extract tenant from request path (inherited from TenantExtractor)

83

* Checks if multitenancy is enabled before attempting extraction

84

* @param requestPath the request path to analyze

85

* @return Optional containing tenant definition if found and enabled

86

*/

87

@Override

88

public Optional<TenantDefinition> extract(String requestPath);

89

}

90

```

91

92

**Usage Examples:**

93

94

```java

95

import org.apereo.cas.multitenancy.*;

96

import org.apereo.cas.configuration.CasConfigurationProperties;

97

import jakarta.servlet.http.HttpServletRequest;

98

import org.springframework.webflow.execution.RequestContext;

99

100

// Create tenant extractor

101

TenantsManager tenantsManager = new DefaultTenantsManager(resource);

102

CasConfigurationProperties casProperties = new CasConfigurationProperties();

103

TenantExtractor extractor = new DefaultTenantExtractor(tenantsManager, casProperties);

104

105

// Extract from request path

106

Optional<TenantDefinition> tenant1 = extractor.extract("/tenants/org1/login");

107

Optional<TenantDefinition> tenant2 = extractor.extract("/tenants/company2/validate");

108

109

if (tenant1.isPresent()) {

110

System.out.println("Found tenant: " + tenant1.get().getId());

111

}

112

113

// Extract from HTTP request

114

HttpServletRequest httpRequest = ...; // from servlet context

115

Optional<TenantDefinition> tenantFromHttp = extractor.extract(httpRequest);

116

117

// Extract from WebFlow context

118

RequestContext webflowContext = ...; // from Spring WebFlow

119

Optional<TenantDefinition> tenantFromFlow = extractor.extract(webflowContext);

120

121

// Use static utility method

122

String tenantId = TenantExtractor.tenantIdFromPath("/tenants/myorg/authenticate");

123

// Returns: "myorg"

124

```

125

126

## URL Pattern Matching

127

128

The tenant extraction system uses a predefined regex pattern to identify tenant information in URLs:

129

130

### Pattern Definition

131

132

```java { .api }

133

Pattern PATTERN_TENANTS = Pattern.compile("tenants/(.+)/(.+)", Pattern.CASE_INSENSITIVE);

134

```

135

136

### Pattern Matching Behavior

137

138

The pattern `tenants/(.+)/(.+)` matches URLs with the structure:

139

- `/tenants/{tenantId}/{operation}`

140

- Case-insensitive matching

141

- First capture group contains the tenant ID

142

- Second capture group contains the operation/endpoint

143

144

**Example URL Matches:**

145

146

```java

147

// These URLs will match and extract tenant IDs:

148

"/tenants/organization1/login" // → "organization1"

149

"/tenants/company-a/validate" // → "company-a"

150

"/tenants/TENANT123/authenticate" // → "TENANT123"

151

"/app/tenants/myorg/logout" // → "myorg"

152

153

// These URLs will NOT match:

154

"/login" // No tenant structure

155

"/tenant/org1/login" // Missing 's' in 'tenants'

156

"/tenants/org1" // Missing operation part

157

"/tenants/" // Missing both parts

158

```

159

160

### Static Extraction Method

161

162

```java

163

/**

164

* Extract tenant ID from path using static method

165

*/

166

String tenantId = TenantExtractor.tenantIdFromPath("/tenants/acme-corp/validate");

167

// Returns: "acme-corp"

168

169

if (tenantId != null) {

170

// Use tenant ID for further processing

171

System.out.println("Extracted tenant: " + tenantId);

172

}

173

```

174

175

## Configuration Control

176

177

The DefaultTenantExtractor respects CAS configuration properties to control extraction behavior:

178

179

### Multitenancy Enable/Disable

180

181

```java

182

// Extraction behavior is controlled by configuration property:

183

// cas.multitenancy.core.enabled = true/false

184

185

// When disabled, extract() always returns Optional.empty()

186

// When enabled, normal pattern matching is performed

187

```

188

189

### Configuration Example

190

191

```yaml

192

# CAS Configuration (application.yml)

193

cas:

194

multitenancy:

195

core:

196

enabled: true

197

json:

198

location: "classpath:tenants.json"

199

```

200

201

## Request Processing Flow

202

203

The tenant extraction follows this processing flow:

204

205

1. **Configuration Check**: Verify if multitenancy is enabled

206

2. **Path Analysis**: Extract flow ID or use provided path string

207

3. **Pattern Matching**: Apply PATTERN_TENANTS regex to identify tenant ID

208

4. **Tenant Lookup**: Use TenantsManager to find tenant definition

209

5. **Result Return**: Return Optional with tenant or empty if not found

210

211

**Flow Diagram:**

212

213

```

214

HTTP Request → Flow ID Extraction → Pattern Matching → Tenant ID → Manager Lookup → Tenant Definition

215

```

216

217

## Integration Points

218

219

### Servlet Integration

220

221

```java

222

// Extract from HttpServletRequest

223

public Optional<TenantDefinition> extractFromServlet(HttpServletRequest request) {

224

return extractor.extract(request);

225

}

226

```

227

228

### Spring WebFlow Integration

229

230

```java

231

// Extract from Spring WebFlow RequestContext

232

public Optional<TenantDefinition> extractFromWebFlow(RequestContext context) {

233

return extractor.extract(context);

234

}

235

```

236

237

### Custom Path Processing

238

239

```java

240

// Direct path-based extraction for custom scenarios

241

public Optional<TenantDefinition> extractFromCustomPath(String customPath) {

242

return extractor.extract(customPath);

243

}