AuthorizationContextHelper
The AuthorizationContextHelper class parses the x-cwms-auth-context header and provides methods to access user information and constraints.
Package: cwms.cda.helpers
Source: cwms-data-api/src/main/java/cwms/cda/helpers/AuthorizationContextHelper.java
Purpose
This helper class serves as the bridge between the Authorization Proxy and the Java API. It:
Parses the JSON authorization context from the request header
Extracts user identity information (id, username, email)
Provides access to user roles and office assignments
Exposes constraint values for filtering
Respects the enabled/disabled configuration
Configuration
The helper checks the cwms.dataapi.access.management.enabled property at class load time. When disabled, all methods return empty values regardless of header content.
Property |
Type |
Default |
Description |
|---|---|---|---|
|
boolean |
false |
Enable authorization header processing |
The property can be set via environment variable or system property:
# Environment variable
export cwms.dataapi.access.management.enabled=true
# System property
java -Dcwms.dataapi.access.management.enabled=true ...
Constructor
public AuthorizationContextHelper(Context ctx)
Creates a new helper instance by parsing the x-cwms-auth-context header from the Javalin context.
Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
|
The Javalin request context |
Behavior:
If authorization is disabled, all internal maps are empty
If header is missing or invalid, all internal maps are empty
Invalid JSON is logged as a warning and treated as missing
Static Methods
isEnabled
public static boolean isEnabled()
Returns whether authorization mode is enabled.
Returns: true if cwms.dataapi.access.management.enabled is set to true
User Context Methods
getUserId
public String getUserId()
Returns the user’s unique identifier from the user.id field.
Returns: User ID string, or null if not present
getUsername
public String getUsername()
Returns the user’s username from the user.username field.
Returns: Username string, or null if not present
getEmail
public String getEmail()
Returns the user’s email address from the user.email field.
Returns: Email string, or null if not present
getRoles
public List<String> getRoles()
Returns the list of roles assigned to the user from the user.roles array.
Returns: List of role names, or empty list if not present
getOffices
public List<String> getOffices()
Returns the list of offices the user has access to from the user.offices array.
Returns: List of office codes, or empty list if not present
getPrimaryOffice
public String getPrimaryOffice()
Returns the user’s primary office from the user.primary_office field.
Returns: Office code string, or null if not present
getPersona
public String getPersona()
Returns the user’s active persona from the user.persona field.
Returns: Persona name, or null if not present
getRegion
public String getRegion()
Returns the user’s region from the user.region field.
Returns: Region name, or null if not present
Constraint Methods
getAllowedOfficesConstraint
public String getAllowedOfficesConstraint()
Returns the allowed offices constraint value from constraints.allowed_offices.
Returns: Constraint value string, or null if not present
isEmbargoExempt
public boolean isEmbargoExempt()
Returns whether the user is exempt from embargo rules based on constraints.embargo_exempt.
Returns: true if user is embargo exempt, false otherwise
getTimezone
public String getTimezone()
Returns the user’s timezone preference from constraints.timezone.
Returns: Timezone string, or null if not present
Utility Methods
hasRole
public boolean hasRole(String role)
Checks if the user has a specific role.
Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
|
The role name to check |
Returns: true if the user has the specified role
hasOfficeAccess
public boolean hasOfficeAccess(String office)
Checks if the user has access to a specific office.
Parameters:
Parameter |
Type |
Description |
|---|---|---|
|
|
The office code to check |
Returns: true if user has access, or if no authorization header is present
buildOfficeFilter
public String buildOfficeFilter()
Builds a comma-separated string of allowed offices for use in queries.
Returns:
nullif no authorization header is presentnullif allowed offices constraint is*(all offices)Comma-separated office codes otherwise
isAuthorizationHeaderPresent
public boolean isAuthorizationHeaderPresent()
Checks if a valid authorization context header was present in the request.
Returns: true if the header was present and successfully parsed
getFullContext
public Map<String, Object> getFullContext()
Returns an unmodifiable view of the complete parsed authorization context.
Returns: Immutable map containing the full context, or empty map if not present
Usage Examples
Basic User Information
AuthorizationContextHelper auth = new AuthorizationContextHelper(ctx);
if (auth.isAuthorizationHeaderPresent()) {
String username = auth.getUsername();
String primaryOffice = auth.getPrimaryOffice();
List<String> roles = auth.getRoles();
logger.info("Request from {} at office {} with roles {}",
username, primaryOffice, roles);
}
Role-Based Access Check
AuthorizationContextHelper auth = new AuthorizationContextHelper(ctx);
if (!auth.hasRole("CWMS Users")) {
ctx.status(403).result("CWMS Users role required");
return;
}
Office Access Validation
AuthorizationContextHelper auth = new AuthorizationContextHelper(ctx);
String requestedOffice = ctx.queryParam("office");
if (!auth.hasOfficeAccess(requestedOffice)) {
ctx.status(403).result("Not authorized for office: " + requestedOffice);
return;
}
Conditional Authorization
if (AuthorizationContextHelper.isEnabled()) {
AuthorizationContextHelper auth = new AuthorizationContextHelper(ctx);
// Apply authorization logic
} else {
// Bypass authorization
}
Expected Header Format
The helper expects the x-cwms-auth-context header to contain JSON in the following structure:
{
"policy": {
"allow": true,
"decision_id": "proxy-12345"
},
"user": {
"id": "m5hectest",
"username": "m5hectest",
"email": "m5hectest@usace.army.mil",
"roles": ["cwms_user", "ts_id_creator"],
"offices": ["SWT", "SPK"],
"primary_office": "SWT",
"persona": "operator",
"region": "SWD"
},
"constraints": {
"allowed_offices": ["SWT", "SPK"],
"embargo_rules": {
"SPK": 168,
"SWT": 72,
"default": 168
},
"embargo_exempt": false,
"time_window": {
"restrict_hours": 8
},
"data_classification": ["public", "internal"],
"timezone": "America/Chicago"
}
}
Error Handling
The helper logs warnings for parsing errors but does not throw exceptions. Invalid headers result in empty contexts:
AuthorizationContextHelper auth = new AuthorizationContextHelper(ctx);
// Safe to call even if header was invalid
if (!auth.isAuthorizationHeaderPresent()) {
// Handle missing/invalid authorization
}