-
Notifications
You must be signed in to change notification settings - Fork 0
The Services
There are seven OIDC services available in the library. Each of the service is a tool to access a single OIDC endpoint or a service.
The services are linked together by ServiceContext carrying the state of the services, each service accumulating the information carried. See full conversation on how the interaction with OP ideally moves forward, leaving developer (only) the responsibility of making those actual HTTP calls and directing user to Authorization endpoint.
Eventhough all the services are independent of eachother, they do rely on information provided by ServiceContext usually stored there by other services. On this page among other things we document how the services apply the ServiceContext. This will help you to adapt the library to your use cases.
The use pattern of a service is fairly simple. Let's see the default use of a service, how it works. Let's take Registation service, but please note, all the services follow this same pattern.
First step, initialize the service, pass the ServiceContext instance to it. Call getRequestParameters
Registration registration = new Registration(serviceContext, null, null);
httpArguments = registration.getRequestParameters(null);
Now, as a response you will get HttpArguments that you will use to make HTTP call to OP. The response of that is given back to service to parse it and to update the ServiceContext..
registration.updateServiceContext(registration.parseResponse(response));
.. and you are done. ServiceContext instance contains now information like client_id and client_secret. It is fairly obvious that there has to be quite a lot of information already in the ServiceContext instance for getRequestParameters to form correct request, with no other arguments from the developer. The trick here is to leave the responsibility of updating the ServiceContext instance to services. The full conversation example shows with how minimal configuration library adopter may perform the full flow. However, based on the information provided on this page, you should be able to initialize Registration - or any other service - even by yourself from scratch, and run it without relying to other services.
You may add new request parameters or override the parameters service would automatically create. This may be done by to ways, either passing them directly in getRequestParameters call
Map<String, Object> requestParams = new HashMap<>();
requestParams.put("scope", "openid email");
authentication.getRequestParameters(requestParams);
or already with the help of the ServiceConfig as you instantiate the Service.
ServiceConfig config = new ServiceConfig();
Map<String, Object> requestParams = new HashMap<>();
requestParams.put("scope", "openid email");
config.setRequestParameters(requestParams);
Authentication authentication = new Authentication(serviceContext, stateDb, config);
httpArguments = authentication.getRequestParameters(null);
If you looked already at the full conversation you noticed that scope parameter value was never set there by the user. That is because the service makes sure the scope parameter always has atleast value 'openid'. The general principle is that if you set the request parameter using one of the two mentioned methods, the service will not try to create the value of the parameter automatically. Furthermore, if the same parameter is set with both methods, the parameter in serviceConfig.getRequestParameters() will have the precedence over parameter set by getRequestParameters(requestParams).
The services read directives also from Post and Pre Constructor arguments. Each service will list on this page which of the arguments are supported. The parameters are set by setPreConstructorArgs and setPostConstructorArgs calls.
Here we use Post Constructor argument 'request_method' to instruct Authentication service to create a request object by value.
Authentication authentication = new Authentication(serviceContext, stateDb, null);
Map<String, Object> postConstructorArgs = new HashMap<String, Object>();
postConstructorArgs.put("request_method", "request");
accessToken.setPostConstructorArgs(postConstructorArgs);
httpArguments = authentication.getRequestParameters(null);
As with request parameters, we are also able to use ServiceConfig to perform the same operation:
ServiceConfig config = new ServiceConfig();
config.getPostConstructorArgs.put("request_method", "request");
Authentication authentication = new Authentication(serviceContext, stateDb, config);
httpArguments = authentication.getRequestParameters(null);
The power of ServiceConfig comes from it's ability to be deserialized from JSON. You are able to fully configure the behaviour of the service using JSON configuration files. The previous examples using ServiceConfig could have been also done in following way:
ServiceConfig config = ServiceConfig.fromJson("configuration.json");
parsing a file with contents:
{
"request_params":{"scope":"openid email"},
"post_construct":{"request_method":"request"}
}
Now we list all services and the relevant parameters to operate with them.
OpenID Provider Issuer discovery is the process of determining the location of the OpenID Provider as described in https://openid.net/specs/openid-connect-discovery-1_0.html#IssuerDiscovery.
The only input required by the service is 'resource' parameter. Webfinger host is parsed automatically from resource parameter. Also 'rel' parameter is set automatically and need not to be set by caller.
- resource: Identifier for the target End-User that is the subject of the discovery request.
- rel: URI identifying the type of service whose location is being requested. Expected to be http://openid.net/specs/connect/1.0/issuer and this value is automatically used by service unless overriden by this request parameter.
Obtaining OpenID Provider Configuration Information is decribed in https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig. The service will obtain and validate the information. The validated information is stored to ServiceContext.
The service expects that ServiceContext contains OP Issuer identifier. That is all the input it needs.
Registration service register client dynamically as described in https://openid.net/specs/openid-connect-registration-1_0.html#ClientRegistration.
Following parameters may be left out of request parameter map as they have alternate sources:
- redirect_uris: If not set as request parameter, the value is located from in ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior(). If value still does not exist it is located from ServiceContext.getCallBack() or from ServiceContext.getRedirectUris() giving precedence to getCallBack().
- response_types: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- grant_types: Value set automatically based on response_type value.
- application_type: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- contacts: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- client_name: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- logo_uri: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- client_uri: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- policy_uri: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- tos_uri: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- jwks: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- jwks_uri: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- sector_identifier_uri: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- subject_type: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- id_token_signed_response_alg: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- id_token_encrypted_response_alg: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- id_token_encrypted_response_enc: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- userinfo_signed_response_alg: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- userinfo_encrypted_response_alg: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- userinfo_encrypted_response_enc: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- request_object_signing_alg: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- request_object_encryption_alg: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- request_object_encryption_enc: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- token_endpoint_auth_method: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- token_endpoint_auth_signing_alg: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- default_max_age: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- require_auth_time: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- default_acr_values: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- initiate_login_uri: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- request_uris: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior().
- post_logout_redirect_uris: If not set as request parameter, the value is located from ServiceContext.getBehavior() or from ServiceContext.getClientPreferences() giving precedence to getBehavior(). If value still does not exist it is located from ServiceContext.getPostLogoutRedirectUris()
- request_uris: Generated automatically if required by OP configuration i.e. require_request_uri_registration is true.
The Authorization Endpoint performs Authentication of the End-User as decribed in https://openid.net/specs/openid-connect-core-1_0.html#Authentication. This is done by sending the User Agent to the Authorization Server’s Authorization Endpoint for Authentication and Authorization, using request parameters defined by OAuth 2.0 and additional parameters and parameter values defined by OpenID Connect.
Following parameters may usually be left out of request parameter map as they have also alternate sources:
- client_id: If not set as request parameter the value is located from ServiceContext.
- state: If not set as request parameter the value is created automatically.
- redirect_uri: If not set as request parameter the value is located from ServiceContext. If ServiceContext has no ServiceContext.getCallBack() per response mode / response type callback map defined, we pick first generally listed redirect uri from ServiceContext.getRedirectUris(). If there is per response mode / response type callback map available we apply it in following order. 1) If response_mode is form_post, we use redirect uri value mapped for it if it exists. 2) If response_type is code, we use redirect uri value mapped for it if it exists. 3) For other response types we use redirect uri value mapped for response_type implicit if it exists. This evaluation may end in not setting redirect_uri value as the value cannot just be created and thus leading to error as it is also a mandatory parameter.
- response_type: If not set as request parameter the value is located from ServiceContext.getBehavior() as the first item in array claim 'response_types'.
- scope: If not set as request parameter value of 'openid' is used. If scope request parameter exists and does not contain value 'openid', it is appended there.
- nonce: If not set as request parameter the value is created automatically.
The initial formed request may be further adjusted with post constructor directives set with map implemeted by all services, Map<String, Object> getPostConstructorArgs().
- request_method: If value equals to 'request' a request object by value is created. If value equals to 'request_uri' a request object by reference is created. TODO: Instructions on file locations vs url value
- request_object_signing_alg: Request object signing algorithm. If not set a value from ServiceContext().getBehavior() is used, defaulting to RS256.
- request_object_encryption_alg: Request object encryption key transport algorithm. If not set a value from ServiceContext().getBehavior() is used, defaulting to none.
- request_object_encryption_enc: Request object encryption content encryption algorithm. If not set a value from ServiceContext().getBehavior() is used, defaulting to none. Value must exist if request object encryption key transport algorithm is defined.
- key: Key for signing the request. If not set, KeyJar is used for locating suitable key.
- sig_kid: May be used to locate specific signing key from KeyJar.
- keytransport_key: Key for encrypting the request. If not set, KeyJar is used for locating suitable key of the issuer.
To obtain an Access Token, an ID Token, and optionally a Refresh Token, the RP sends a Token Request to the Token Endpoint to obtain a Token Response. This is described in https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint.
As with other services request parameters may be set as an argument to getRequestParameters in Map<String, Object> request parameter map. The service however gives precedence to values located from state database and common use cases do not require user to set any request parameters.
- grant_type: Precedence given to value located from state database.
- code: Precedence given to value located from state database.
- redirect_uri: Precedence given to value located from state database.
- client_id: Precedence given to value located from state database.
The forming of request may be further adjusted with post constructor directives set with map implemeted by all services, Map<String, Object> getPostConstructorArgs().
- state: Key to locate request parameters from state database.
To refresh an Access Token, the RP sends a Refresh Token Request to the Token Endpoint to obtain a Token Response. This is described in https://openid.net/specs/openid-connect-core-1_0.html#RefreshingAccessToken.
As with other services request parameters may be set as an argument to getRequestParameters in Map<String, Object> request parameter map. The service however gives precedence to values located from state database and common use cases do not require user to set any request parameters.
- grant_type: Precedence given to value located from state database.
- refresh_token: Precedence given to value located from state database.
- scope: Precedence given to value located from state database.
- client_id: Precedence given to value located from state database.
The forming of request may be further adjusted with post constructor directives set with map implemeted by all services, Map<String, Object> getPostConstructorArgs().
- state: Key to locate request parameters from state database.
The UserInfo Endpoint is an OAuth 2.0 Protected Resource that returns Claims about the authenticated End-User. To obtain the requested Claims about the End-User, the Client makes a request to the UserInfo Endpoint using an Access Token obtained through OpenID Connect Authentication. This is described in https://openid.net/specs/openid-connect-core-1_0.html#UserInfo.
- access_token: If not set as request parameter the value is located from state database. In the latter case, the post constructor argument 'state' must be set.
The forming of request may be further adjusted with post constructor directives set with map implemeted by all services, Map<String, Object> getPostConstructorArgs().
- state: Key to locate access token from state database in the case access_token is not set as request parameter.