Authorization Code Flow
Authenticator handling authorization code flows in OIDC.
About
No identification is done by this authenticator. It acts as a controller for issuing Json Web Tokens (JWT). Typically this authenticator is the first point of contact coming from an OpenID Connect Relying Party, requesting identification.
This authentication controller can be considered a start and end touch point. The main purpose is to handle OpenID Connect specifics.
Actual user identification is done elsewhere.
When using this authenticator, the ID token is fetched from the token endpoint.
Configuration
Common Authenticator configuration can be found here.
chain
List of authenticators performing the actual authentication.
N/A
token_code_ttl
Time to live in milliseconds for the generated code. Previous parameter name token_endpoint_ttl is deprecated.
60000
access_token_ttl
Access token time to live in millisesonds. Previous parameter name userinfo_endpoint_ttl is deprecated.
60000
enable_refresh_token
Enables the use of refresh tokens.
false
refresh_token_ttl
Refresh token time to live in millisesonds.
1800000
id_token_ttl
ID token time to live in minutes.
5
id_token_headers
ID token headers. Previous parameter name jwt_headers is deprecated.
N/A
id_token_claims
ID token claims. Previous parameter name jwt_claims is deprecated.
N/A
access_token_headers
Access Token headers. ONLY used when sending access tokens as JWTs.
N/A
access_token_claims
Access Token claims. Previous parameter name userinfo_claims is deprecated.
N/A
use_jwt_access_tokens
Enables access tokens as JWT.
false
jwt_access_token_ttl
Access Token time to live in minutes.
5
keystore
Keystore reference or json object. Used for JWT signing. If no alias is configured, the first alias will be used.
N/A
required_request_parameters
Required parameters.
["response_type", "client_id", "redirect_uri", "scope", "nonce"]
no_prompt_pass_through
If the prompt request parameter is missing and a user session exists, the user is silently authenticated. Enables the same behaviour as if prompt=none and a user session exists.
false
{
    "id": "auth00",
    "type": "OIDCAuthCodeFlow",
    "config": {
        "base_path": "/test/authn",
        "failure_location": "/authn/failure.html",
        "chain": [
            {
            "id" : "select",
            "required" : true
            }
        ],
        "token_code_ttl": 90000,
        "access_token_ttl": 90000,
        "id_token_ttl": 6,
        "required_request_parameters": [
            "response_type",
            "client_id",
            "redirect_uri",
            "scope",
            "nonce"
        ],
        "keystore": {
            "path": "/fortified_test/keystore.p12",
            "password": "secret",
            "alias": "jwt",
            "type": "PKCS12"
        },
        "id_token_headers": {
            "kid": ""
        },
        "id_token_claims": {
            "test_claim": "static_claim",
            "email": "${item.mail}",
            "nonce": "${request.nonce}"
        },
        "access_token_claims": {
            "userinfo_claim_test": "static_claim",
            "email": "${item.mail}",
            "email_verified": true,
            "address": {
                "street_address": "my address",
                "postal_code": "my postal code"
            },
            "given_name": "${item.givenName}",
            "subject": "${item.subject}"
        },
        "rps": [
            {
                "client_id": "provided",
                "client_secret": "provided",
                "redirect_uri": [
                    "https://auth.organisation.com/authenticate/oidcrp"
                ],
                "post_logout_redirect_uris": [
                    "https://auth.organisation.com/authenticate/oidcrp/loggedout"
                ],
                "pipe_id": "optional_pipe_id"
            }
        ]
    }
}Refresh Tokens
Refresh tokens can be described as "token granting token", which means they are sent to the OIDC server to obtain new ones.
Enable by setting the enable_refresh_token configuration parameter to true. 
Optionally configure the refresh_token_ttl configuration parameter. 
Default value is 1800000 milliseconds. This will enable refresh tokens valid for 30 minutes.
Persisting refresh tokens  
There is an option to send the newly created refresh token to a pipe which can be used to store the refresh token without keeping it in memory.
Enable the pipe by configuring the refresh_token_persist_pipe_id  configuration parameter on the relying party section. 
Loading refresh tokens
Refresh tokens are used with the token endpoint by setting the grant_type request parameter to refresh_token. I the refresh token was persisted in a pipe, use  refresh_token_resolve_pipe_id configuration parameter on the relying party section to resolve/load the refresh token, create a new refresh token and persist that new refresh token. 
The pipe must return a new refresh_token (string), access_token (string),  id_token (string) and expires_in (long) in pipe response. All controls are done in the pipe.
Using the client_credentials grant
When using the token endpoint with the client_credentials grant (M2M) a couple of things needs to be in place:
In the discovery_meta section on the OIDC module add client_credentials:
"grant_types_supported": [ "authorization_code", "refresh_token", "client_credentials" ],
"grant_types_supported": [ 
    "authorization_code", 
    "refresh_token", 
    "client_credentials"
],In the Relying Party configuration add:
"client_credentials_pipe_id": "client_credentials_pipe",Add corresponding "client_credentials_pipe":
// Example pipe for JWT access token with ttl of 60 minutes
{
    "id": "client_credentials_pipe",
    "config": {
        "valves": [
            {
                "name": "CreateJwt",
                "enabled": true,
                "config": {
                    "dest": "access_token",
                    "jwt_ttl": 60,
                    "jwt_headers": {
                        "test_header": "test_header",
                        "typ": "at+jwt"
                    },
                    "jwt_claims": {
                        "test_claim": "test_claim",
                        "sub": "Anna_Auth"
                    },
                    "keystore": {
                        "path": "/fortified_test/config/keystore.p12",
                        "password": "supersecret",
                        "type": "PKCS12"
                    },
                    "keystore_password": "supersecret",
                    "keystore_alias": "jwt"
                }
            },
            {
                "name": "JsonObjectCreate",
                "enabled": true,
                "config": {
                    "src": {
                        "access_token": "${item.access_token}",
                        "token_type": "Bearer",
                        "expires_in": 3600,
                        "scope": "read"
                    },
                    "dest": "client_credentials"
                }
            }
        ]
    }
}// Example pipe for opaque access token with ttl of 60 minutes
{
    "id": "client_credentials_pipe",
    "config": {
        "valves": [
            {
                "name": "CreateItem",
                "enabled": true,
                "config": {
                    "id": "temp",
                    "properties": {}
                }
            },
            {
                "name": "JsonObjectCreate",
                "enabled": true,
                "config": {
                    "src": {
                        "access_token": "",
                        "token_type": "Bearer",
                        "expires_in": 3600,
                        "scope": "read"
                    },
                    "dest": "client_credentials"
                }
            }
        ]
    }
}Logging
On a successful authentication, an event is logged containing the following:
WEB_100101
IDENTIFIER (user traceid)
DESTINATION_SERVICE_NAME (redirect URI)
SOURCE_ADDRESS (user IP address)
Data sent to PIPE
All data put into the shared authentication state along with the HTTP headers are exposed and sent into the pipe.
Data put into the state by this authenticator is:
OIDC request data
Expected data from PIPE
In order to use data from PIPE the response must contain one item. All data from that item will be available when creating the ID token and access token.
Available data for ID_token and Access Token claims
Data is extracted with the help of expansions.
The following scopes are available:
request
The current authentication request including HTTP headers and params
${request.client_id}
item
Item properties AND the current authentication state (includes both local and global properties).
${item.mail}
session
The current session.
${session.sub}
exports
Exports data.
${exports.sub}
