-
-
Notifications
You must be signed in to change notification settings - Fork 331
Single Page Applications
Currently available only in the "feature" branch as version 2.1.7rc0
For Single Page Applications (SPAs) and other Clients that require access to the access_token or other information related to an authenticated user session, mod_auth_openidc has the ability to return "session info" to the caller when a valid session cookie is presented on an HTTP request to the following endpoint:
<redirect_uri>?info=json
The session info is returned as a JSON object and the information returned in that is configurable through OIDCInfoHook:
# (Optional)
# Define the data that will be returned upon calling the info hook (i.e. <redirect_uri>?info=json)
# iat (int) : Unix timestamp indicating when this data was created
# access_token (string) : the access token
# access_token_expires (int) : the Unix timestamp which is a hint about when the access token will expire (as indicated by the OP)
# id_token (object) : the claims presented in the ID token
# userinfo (object) : the claims resolved from the UserInfo endpoint
# refresh_token (string) : the refresh token (if returned by the OP)
# session (object) : (for debugging) mod_auth_openidc specific session data such as "remote user", "session expiry", "session id" and a "state" object
# When not defined the session hook will not return any data but a HTTP 404
OIDCInfoHook [iat|access_token|access_token_expires|id_token|userinfo|refresh_token|session]+Calling this hook will also reset the session inactivity timer.
The Client calling the hook can indicate requirements on the "freshness" of the access_token by providing the parameter access_token_refresh_interval:
<redirect_uri>?info=json&access_token_refresh_interval=<seconds>
Providing a value of "0" will refresh the current access_token, but only when a refresh_token was provided as part of the initial authentication flow and was stored in the session.
Providing a value greater than "0" will not refresh the access token unless more than "<seconds>" have elapsed since the last refresh.
Note that the update frequency of the information returned from the UserInfo endpoint at the OpenID Connect Provider can be configured through the OIDCUserInfoRefreshInterval configuration primitive and that accessing that endpoint may in itself lead to a refresh of the access_token and possibly the refresh_token.
In certain SPA use cases content may be served to browsers (i.e. as HTML) and Javascript clients (i.e. as JSON) from the same path. In that case the mod_auth_openidc needs to be able to consume and validate both OAuth 2.0 bearer Access Tokens as well as session cookies on the same path. In Apache speak this means specifying both AuthType oauth20 and AuthType openid-connect in the same Location or Directory. This is handled by a 3rd directive AuthType auth-openidc.
Caveat: use this "mixed mode" with care as one typically wants to avoid to accept just any bearer token that was issued by your authorization server, so don't use just Require valid-user!
A secure configuration would be:
<Location /example>
AuthType auth-openidc
Require claim client_id:xxx
Require claim aud:xxx
</Location>Where the first Require directive restricts the (Javascript) OAuth 2.0 Client having access to this path and the second Require directive ensures that browsers present a session cookie to this Relying Party instance of mod_auth_openidc.
Note that just including Require valid-user for the latter would defeat the first Require. Hence you must identify sessions more specifically based on the claims in the id_token or obtained from the UserInfo endpoint. In multi-provider setups you may need to add multiple Require claim aud:xxx" directives since typically different client_id`'s would be used with different Providers. Alternatively you can base it on a claim that is issued by all Providers but is NOT part of Access Tokens issued to other Clients than the your SPA's Javascript client.
By default all Clients presenting an valid session cookie will receive the information configured in OIDCInfoHook. Further refinement of that can be done by using Require directives on the hook itself, i.e. the OIDCRedirectURI, e.g. restricting it to the module's Client identifier for a specific Provider when multiple Providers are used:
<Location /redirect_uri>
AuthType openid-connect
Require claim aud:ac_oic_client
</Location>Or a more advanced example using the Apache 2.4 "<If>" primitive to apply fine-grained authorization only when the session info hook is called:
<Location /redirect_uri>
<If "%{QUERY_STRING} =~ /.*info=json.*/" >
Require claim aud:ac_oic_client
</If>
<Else>
Require valid-user
</Else>
</Location>