# User Mapping
The user mapping configuration defines how OAG tells the backend which the user is. There are currently three types of user mapping supported. The default one is the jwt-mapping which transports the user information in a signed jwt token. This has the advantage that the user information cannot be forged by anyone who does not have access to the key. With the jwtToken
, the backend system must validate the token. The jwtToken
mapping is the recommended method.
If the backend does not validate the token, the no
mapping can be used, which does not add any user information to the request. This might be useful for a server that hosts only public static files like a SPA frontend and does not need any authentication.
If the backend does not support jwt based authentication, the header-mapping
can be used, which transports the user information as plain HTTP headers. In that case, one must make sure that the backend can only be reached by the OAG because anyone could add the same header to the request who has access to the backend.
# JWT-Mapping
securityProfiles:
webapplication:
userMapping:
type: "jwtToken"
settings:
headerName: "Authorization"
headerPrefix: "Bearer "
audience: "<<route-url>>"
issuer: "<<hostUri>>"
tokenLifetimeSeconds: 30
signatureImplementation: "rsa"
signatureSettings: {}
mappings:
provider: <session.provider>
email_verified: <mappings.email_verified>
email: <mappings.email>
proxy: "OWASP Application Gateway"
# Settings
headerName
: Defines the header in which the jwt will be transported to the backend.headerPrefix
: Prefix that is added before the jwt.audience
: Value of the audience claim of the jwt. Can be any string or <<route-url>> which will use the url of the route as audience value.issuer
: Issuer value for all strings. The special value <<hostUri>> will use the URI of OAG as defined in the main configuration.tokenLifetimeSeconds
: Defines how long the jwt tokens are valid. The token are cached and used for multiple request to the backend.signatureImplementation
: Defines which implementation for the jwt signature provider is used. Currently the supported values are:rsa
,hmac
.
See Key Management section Jwt signer.signatureSettings
: Settings for the jwt signature provider.mappings
: List of additional claims. Key is the name of the claim in the jwt token.
See Mapping Syntax.
# Mappings
The following claims are always added to the jwt token:
sub
: Id of the useraud
: Audience value as defined in the settings aboveiat
,nbf
: Time when the jwt token was issued by OAGexp
: Expiry time of the jwt token. (iat + tokenLifetime)iss
: Issuer value as defined in the settings abovejti
: Random 64bit hex value as token identifierprovider
: The name of the login provider that the user used as defined in the loginProviders settings.
The above configuration would create a JWT token that looks more or less like the following:
{
"alg": "HS256"
}.{
"sub": "0000000000000000000000",
"aud": "https://backendurl.org",
"proxy": "OWASP Application Gateway",
"nbf": 1615794294,
"email_verified": "true",
"provider": "google",
"iss": "http://localhost:8080",
"exp": 1615794324,
"iat": 1615794294,
"jti": "d537dae82ef13f16",
"email": "user@email.com"
}.[Signature]
Note: For algorithms such as RS256 OAG would provide additional headers kid (key id of the signing key) and jku (url where the public key matching kid can be loaded from)
# No-Mapping
If OAG should not attach any information about the user to the request the following setting can be used:
securityProfiles:
webapplication:
userMapping:
type: "no"
settings: {}
# RequestHeader-Mapping
If transporting the user information in a jwt token is not an option, the requestHeader
mapping can be used as an alternative.
WARNING
Please be careful when using this mapping because it's less secure than the jwtToken
mapping.
When the request header mapping is used, the following two additional security measures are needed:
- Make sure the backend can only be reached by OAG through network configuration (Anyone can craft headers that look like this)
- Add a shared secret (api key) to the request and verify it's presence on the backend.
securityProfiles:
webapplication:
userMapping:
type: "requestHeader"
settings:
mappings:
X-USER-PROVIDER: <<login-provider>>
X-USER-ID: <<user-id>>
Authorization: env:APIKEY
# Mapping Syntax
You can define custom mappings with a string templating syntax. Under the hood jwtToken
mapping and requestHeader
mapping use stringtemplate4 (opens new window). But please be aware that complex mapping (conditionals and so on) are not tested yet. The available objects are session
and mappings
where the session object hold information about the user session and mappings contains all mappings from the user model.
Examples:
- Simple strings are interpreted as constants:
OWASP Application Gateway
-> "OWASP Application Gateway" - Name of the login provider:
<session.provider>
-> e.g. "Google" - User Mapping:
<mappings.email>
-> user email - Complex mapping:
provider=<session.provider>
-> e.g. "provider=Google"" You can also use if/else statements and functions in the mapping syntax if needed.
See stringtemplate4 cheatsheet (opens new window).
The session object contains the following values:
<session.sessionExpSeconds>
: Session expiry time (unix timestamp)<session.remainingTimeSeconds>
Remaining session time in seconds<session.provider>
Name of the used login provider<session.id>
Id of the session<session.userId>
Id of the user
The mappings object contains all mappings from the UserModel. Depends of the information for the login provider. i.e.: The oidc login provider class adds the following values to the user model if the are in the idToken from the authorization server:
<mappings.sub>
<mappings.name>
<mappings.given_name>
<mappings.family_name>
<mappings.middle_name>
<mappings.nickname>
<mappings.preferred_username>
<mappings.profile>
<mappings.picture>
<mappings.website>
<mappings.email>
<mappings.email_verified>
<mappings.gender>
<mappings.birthdate>
<mappings.zoneinfo>
<mappings.locale>
<mappings.phone_number>
<mappings.phone_number_verified>
<mappings.address>
<mappings.updated_at>