This chapter covers OpenAM support for OpenID Connect 1.0. OpenID Connect 1.0 extends OAuth 2.0 so the client can verify claims about the identity of the end user, get profile information about the end user, and log the user out at the end of the OpenAM session. OpenID Connect also makes it possible to discover the provider for an end user, and to register client applications dynamically. OpenID connect services are built on OAuth 2.0, JSON Web Token (JWT), WebFinger and Well-Known URIs.
In its role as OpenID Provider, OpenAM lets OpenID Connect clients discover its capabilities, handles both dynamic and static registration of OpenID Connect clients, responds to client requests with authorization codes, access tokens, and user information according to the Basic and Implicit Client Profiles of OpenID Connect, and manages sessions.
This section describes how OpenAM fits into the OpenID Connect picture in terms of the roles that it plays in basic and implicit client profiles, provider discovery, client registration, and session management.
The OpenID Connect Basic Client Profile specifies how the client application interacts with the provider, in this case OpenAM, based on use of the OAuth 2.0 authorization grant. The following sequence diagram shows successful processing from the authorization request, through grant of the authorization code, access token, and ID token, and optional use of the access token to get information about the end user.
In addition to what OAuth 2.0 specifies, OpenID Connect uses an ID token so the client can validate claims about the end user. It also defines how to get user information such as profile, email, address, and phone details from the UserInfo endpoint with a valid access token.
The OpenID Connect Implicit Client Profile specifies how the client application interacts with the provider, in this case OpenAM, based on use of the OAuth 2.0 implicit grant. The following sequence diagram shows successful processing from the authorization request, through grant of the access and ID tokens, and optional use of the access token to get information about the end user.
As for the Basic Client Profile, the Implicit Client Profile specifies an ID token so the client can validate claims about the end user. It also defines how to get user information such as profile, email, address, and phone details from the UserInfo endpoint with a valid access token.
OpenID Connect defines how a client application can discover the OpenID connect provider and corresponding OpenID Connect configuration for an end user. The discovery mechanism relies on WebFinger to get the information based on the end user's identifier. The server returns the information in JSON Resource Descriptor (JRD) format.
OpenID Connect clients can register with OpenAM as a provider both statically, as for other OAuth 2.0 clients, and also dynamically as specified by OpenID Connect. To allow dynamic registration, you register an initial client that other clients can use to get access tokens for registration.
OpenID Connect lets the client track whether the end user is logged in at the provider, and also initiate end user logout at the provider. The specification has the client application monitor session state using an invisible iframe and communicate status using the HTML 5 postMessage API.
You can configure OpenAM's OAuth 2.0 authorization service to double as an OpenID Connect 1.0 Provider. To do so, make sure that the Response Type Plugins list includes at least the default plugin classes.
See Configuring the OAuth 2.0 Authorization Service for detailed instructions on configuring the service.
In order to allow clients to discover the provider for an end user, OpenAM supports OpenID Connect Discovery 1.0. In addition to discovering the provider for an end user, the client can also request the OpenID Connect Provider configuration.
OpenAM as OpenID Connect Provider exposes two endpoints for discovery:
/.well-known/webfinger |
/.well-known/openid-configuration |
A client needs to be able to discover the provider for an end user. In
this case you should consider redirecting requests to URIs at the server root,
such as http://www.example.com/.well-known/webfinger
and http://www.example.com/.well-known/openid-configuration,
to these Well-Known URIs in OpenAM's space.
Discovery relies on WebFinger, a protocol to discover information about people and other
entities using standard HTTP methods. WebFinger uses Well-Known URIs,
which defines the path prefix /.well-known/ for the
URLs defined by OpenID Connect Discovery.
Unless you deploy OpenAM in the root context of a container listening
on port 80 on the primary host for your domain, clients need to find
the right host:port/deployment-uri combination
to locate the well-known endpoints. Therefore you must manage the redirection
to OpenAM. If you are using WebFinger for something else than OpenID Connect
Discovery, then you probably also need proxy logic to route the requests.
To retrieve the provider for an end user, the client needs the following.
hostThe server where the client can access the WebFinger service.
Notice that this is a host name rather than a URL to the endpoint, which is why you might need to redirect clients appropriately as described above.
resourceIdentifies the end user that is the subject of the request.
The client must percent-encode the resource value when using it in
the query string of the request, so when using the "acct" URI scheme and
the resource is acct:user@example.com, then the value
to use is acct%3Auser%40example.com.
relURI identifying the type of service whose location is requested.
In this case http://openid.net/specs/connect/1.0/issuer,
which is http%3A%2F%2Fopenid.net%2Fspecs%2Fconnect%2F1.0%2Fissuer.
Ignoring the question of redirection, you can test the endpoint for the demo user account (output lines folded to make them easier to read).
$ curl "https://openam.example.com:8443/openam/.well-known/webfinger
?resource=acct%3Ademo%40example.com
&rel=http%3A%2F%2Fopenid.net%2Fspecs%2Fconnect%2F1.0%2Fissuer"
{
"subject": "acct:demo@example.com",
"links": [
{
"rel": "http://openid.net/specs/connect/1.0/issuer",
"href": "https://openam.example.com:8443/openam"
}
]
}This shows that the OpenID Connect Provider for the OpenAM demo user is indeed the OpenAM server.
The client can also discover the provider configuration. Ignoring the question of redirection, you can test this (output lines folded to make them easier to read).
{
"response_types_supported": [
"id_token|org.forgerock.restlet.ext.oauth2.flow.responseTypes.IDTokenResponseType",
"token|org.forgerock.restlet.ext.oauth2.flow.responseTypes.TokenResponseType",
"code|org.forgerock.restlet.ext.oauth2.flow.responseTypes.CodeResponseType"
],
"registration_endpoint": "https://openam.example.com:8443/openam/oauth2/connect/register",
"token_endpoint": "https://openam.example.com:8443/openam/oauth2/access_token",
"end_session_endpoint": "https://openam.example.com:8443/openam/oauth2/connect/endSession",
"version": "3.0",
"userinfo_endpoint": "https://openam.example.com:8443/openam/oauth2/userinfo",
"subject_types_supported": [
"pairwise",
"public"
],
"issuer": "https://openam.example.com:8443/openam",
"jwks_uri": "",
"id_token_siging_alg_values_supported": [
"HmacSHA256",
"HmacSHA512",
"HmacSHA384"
],
"check_session_iframe": "https://openam.example.com:8443/openam/oauth2/connect/checkSession",
"claims_supported": [
"phone",
"email",
"address",
"openid",
"profile"
],
"authorization_endpoint": "https://openam.example.com:8443/openam/oauth2/authorize"
}OpenID Connect Clients can register with OpenAM both statically through OpenAM console for example, and also dynamically using OpenID Connect 1.0 Dynamic Registration.
Registering a client by using the OpenAM console consists of first creating an OAuth 2.0 Client agent profile, and then editing the profile to indicate the client settings pertinent to OpenID Connect 1.0.
In the OpenAM console under Access Control > Realm
Name > Agents > OAuth 2.0 Client > Agent, click
New..., then provide the client identifier and client password, and
finally click Create to create the profile.
Follow the hints in the section, Configuring OAuth 2.0 & OpenID Connect 1.0 Clients to edit the profile to match the client configuration.
In order to read and edit the client configuration dynamically later without using OpenAM console, be sure to set an access token in the field titled, "The access token used to update the client."
For dynamic registration you need the client configuration metadata, and an access token to write the configuration to OpenAM by HTTP POST. To obtain the access token, register an initial client statically after creating the provider, as described in Procedure 14.1, “To Register a Client With OpenAM Console”. Other clients can then use that client to obtain the access token needed to perform dynamic registration.
On successful registration, OpenAM responds with information including an access token to allow the client subsequently to read and edit its profile.
Register an initial OAuth 2.0 client statically with a client ID
such as masterClient and client secret such as
password.
Obtain an access token using the client you registered.
For example, if you created the client as described in the previous
step, and OpenAM administrator amadmin has password
password, you can use the OAuth 2.0 resource owner
password grant as in the following example.
$ curl
--request POST
--user "masterClient:password"
--data "grant_type=password&username=amadmin&password=password"
https://openam.example.com:8443/openam/oauth2/access_token
{
"expires_in": 59,
"token_type": "Bearer",
"refresh_token": "26938cd0-6870-4e31-ade9-df31afc37ee1",
"access_token": "515d6551-4512-4279-98b6-c0ef3f03a722"
}HTTP POST the client registration profile to the
/oauth2/connect/register endpoint, using bearer token
authorization with the access token you obtained from OpenAM.
For an example written in JavaScript, see the registration page in the examples available online. Successful registration shows a response that includes the client ID and client secret.
{
"issued_at": 1376916775,
"expires_at": 0,
"client_secret": "5a1f50db-ed93-4a9b-bf37-c1cb3c74ca16",
"com.forgerock.openam.oauth2provider.redirectionURIs": [
"https://openam.example.com:8443/openid/cb-basic.html",
"https://openam.example.com:8443/openid/cb-implicit.html"
],
"client_id": "c1e5c60a-9fd4-4780-a283-ec89580b6cc1",
"registration_client_uri":
"https://openam.example.com:8443/openam/oauth2/connect/register
?client_id=c1e5c60a-9fd4-4780-a283-ec89580b6cc1"
}OpenID Connect Session Management 1.0 allows the client to manage OpenID Connect sessions, making it possible to know when the end user should be logged out.
As described in the OpenID Connect Session Management 1.0 specification, OpenAM's OpenID Connect provider exposes both a "check_session_iframe" URL that allows the client to receive notifications when the end user's session state changes at the provider, and also an "end_session_endpoint" URL to which to redirect an end user for logout.
When registering your client that uses session management, you set the OAuth 2.0 client agent profile properties Post Logout Redirect URI and Client Session URI, described in Configuring OAuth 2.0 & OpenID Connect 1.0 Clients. The Post Logout Redirect URI is used to redirect the end user user-agent after logout. The Client Session URI is the client URI where OpenAM sends notifications when the end user's session state changes.
OpenID Connect Basic and Implicit Client Profiles define how clients interact with the provider to obtain end user authorization and profile information. Although you can run the simple example clients mentioned in this section without setting up Transport Layer Security, do not deploy clients in production without securing the transport.
Code for the client examples shown here is available online. Clone the example project to deploy it in the same web container as OpenAM. Edit the configuration at the outset of the .js files in the project, register a corresponding profile for the example client as described in Section 14.4, “Registering OpenID Connect Clients”, and browse the deployment URL to see the initial page.
OpenID Connect Basic Client Profile 1.0 is designed for web-based relying parties that use the OAuth 2.0 Authorization Code grant type. This grant type makes it possible for the client to get the access code by using the authorization code directly, without passing through the end user's browser. To protect its client secret (password), part of the client must run on the server.
In the example, the Basic Client Profile Start Page describes the prerequisite configuration, which must be part of the client profile stored in the OpenAM realm where you set up the OpenID Provider. In OpenAM console, check that the OAuth 2.0 agent profile matches the settings described.
Logout of OpenAM, and click the link at the bottom of the page to
request authorization. The link sends an HTTP GET request asking for
openid profile scopes to the OpenID Connect provider
authorization URI.
If everything is configured correctly, OpenAM's OpenID Connect provider
has you authenticate as an end user, such as the demo user with username
demo and password changeit, and
grant (Allow) the client access to your profile.
If you successfully authenticate and allow the example client access to your profile, OpenAM returns an authorization code to the example client. The example client then uses the authorization code to request an access token and an ID token. It shows the response to that request, and also decodes the ID token to show the content and to perform some validation. Finally it uses the access token to request information about the end user who authenticated, and displays the result.
Notice that in addition to the standard payload, the ID token indicates
the end user's OpenAM realm, in this case "realm": "/".
OpenID Connect Implicit Client Profile 1.0 is designed for relying parties that use the OAuth 2.0 Implicit grant type. This grant type is designed for clients implemented in a browser. Rather than protect a client secret, the client profile must register a protected redirect URI in advance with the OpenID Provider.
In the example, the Implicit Client Profile Start Page describes the prerequisite configuration, which must be part of the client profile stored in the OpenAM realm where you set up the OpenID Provider. In OpenAM console, check that the OAuth 2.0 agent profile matches the settings described. If you have already configured the agent profile for the Basic Client Profile then you still need to add the redirect URI for the Implicit Client Profile.
Logout of OpenAM, and click the link at the bottom of the page to
request authorization. The link sends an HTTP GET request asking for
id_token token response types and openid
profile scopes to the OpenID Connect provider authorization
URI.
If everything is configured correctly, OpenAM's OpenID Connect provider
has you authenticate as an end user, such as the demo user with username
demo and password changeit, and
grant (Allow) the client access to your profile.
If you successfully authenticate and allow the example client access
to your profile, OpenAM returns the access token and ID token directly in
the fragment (after #) of the redirect URI. The client
does not get an authorization code. The client shows the response to the
request, and also decodes the ID token to show the content and to perform
some validation (though it does not check the ID token signature). Finally
the client uses the access token to request information about the end user
who authenticated, and displays the result.
As for the Basic Client Profile, the ID Token indicates the end user's OpenAM realm in addition to the standard information.
As for other OAuth 2.0 applications, you must protect messages going across the network. OpenID Connect 1.0 requires Transport Layer Security (TLS). The chapter on Managing Certificates includes some discussion of protecting traffic in the container where OpenAM runs. Also see the documentation for your web application container.
Also take into account the points developed in the section on Security Considerations in the OpenID Connect Messages draft specification.