1. Authentication

1.1. Concepts and Approach

All endpoints described in this Integration Guide can be found in the following available discovery documents:

1.1.1. Authentication Flows

In order to interact with this service, it is necessary to implement one of the three authorization flows defined by OpenID Connect 1.0 standard: implicit flow, authorization code flow and hybrid flow.

  • Implicit flow. This method is recommended for browser-based apps. Its main steps are:

    1. A request is made to the Authorization Endpoint. The Authorization Server will redirect the user to the sign-in page.

    2. The end-user will then authenticate with a set of required credentials.

    3. The Authorization Server will answer back with a redirection URI and an Access Token.

    4. The Access Token can be used to request information about the end-user via the User Info Endpoint.

  • Authorization Code flow. This method is recommended for apps running on a web server or native mobile applications. Its main steps are:

    1. A request is made to the Authorization Endpoint. The Authorization Server service will redirect the user to the sign-in page.

    2. The end-user will then authenticate with a set of credentials required.

    3. The Authorization Server will answer back with an authorization code.

    4. The Client can now use the received code to request an Access Token through the Token Endpoint.

    5. Once the client application has acquired an Access Token, it will be possible to request information about the end-user via the User Info Endpoint.

  • Hybrid Code flow. This method merges characteristic from both of the previously mentioned methods. Currently, the usage of this method is not recommended with the Authorization Server.

To implement any of the flows, it is necessary to specify the response type on the request to the Authorization Server. OpenID Connect specification indicates the combination of response types necessary to implement each flow:

oidc response types
Figure 1. Response Types on OpenID Connect

1.1.2. Client authentication

When accessing the Token Endpoint, clients using the implicit flow are not required to be authenticated, but if the client uses the Authorization Code Flow, it must provide its credentials.

These credentials will be provided by Triple-A: client_id and client_secret.

1.1.3. Request Endpoints for Authentication

All endpoints require a set of mandatory parameters in order to generate a valid response. Their URLs can be obtained by means of a Discovery URI that answers back with a set of endpoints and their URLs. All these URLs must be accessed by means of a GET request, and require a set of mandatory parameters:

  • Discovery URI: /.well-known/openid-configuration

  • Authorization Endpoint (GET): /oxauth/restv1/authorize Parameters:

    • scope: The request should include an array of scopes, with one of them being “openid”.

    • response_type: Its value should be desired combination according to the OpenID Connect response type table.

    • response_mode: use "form_post" by default

    • client_id: Provided by Triple-A.

    • redirect_uri: It should point to the client application and match the URI given on the acceptance request.

    • state (optional): Opaque value used to maintain state between the request and the callback. Typically, Cross-Site Request Forgery (CSRF, XSRF) mitigation is done by cryptographically binding the value of this parameter with a browser cookie.

    • nonce (optional/required for Implicit Flow): String value used to associate a Client session with an ID Token, and to mitigate replay attacks (it can have ANY value)

Example:
GET oxauth/restv1/authorize?scope=openid&client_id=@!5C7F.E36B.5DE3.15EE!0001!6B53.87B4!0008!A121.D32B.8BCD.4E14&redirect_uri=app://test&response_type=code&response_mode=form_post

If the application is trying to authenticate without user input, user credentials must be provided through the Authorization header. The code will be encoded as a parameter in the Location response header.

  • Token Endpoint (POST): /oxauth/restv1/token

    • grant_type: implicit / authorization_code (depending on the authorization flow).

    • Code*: Used only with grant_type=authorization_code

    • redirect_uri: It should point to the client application and match the URI given on the acceptance request.

    • scope: The request should include an array of scopes, with one of them being “openid”.

    • client_id*: Provided by Triple-A, only necessary with grant_type=authorization_code.

    • client_secret*: Provided by Triple-A, only necessary with grant_type=authorization_code

1.2. Client-side implementation

1.2.1. Registration

1.2.1.1. Static Registration

In order to allow a client application to delegate its sign-in function under the SSO system of the Authorization Server, it is necessary to provide the following parameters:

  • Application Type: An application could be either NATIVE or WEB.

  • Policy and ToS URI: These resources contain the application policies regarding the usage of user personal information.

  • Redirect Login/Logout URI: Only the first is mandatory. Indicates the URL or App Link where the sign-in service will redirect users after login. [1]

  • Required OAuth2 Scopes: These scopes indicate which kind of information and access the Client Application is able to grant to users. [2]

After the application has been approved and configured, the following parameters, necessary to connect to the SSO service, will be provided to the client:

  • Client ID: Unique identification sequence for your client.

  • Client Secret: Necessary to perform Authentication on the Token Endpoint.

Client credentials can be passed either as an Authorization header (encoded as Basic) or in the form of the POST request. Only one of these options can be enabled at the same time for each client.

1.2.1.2. Dynamic Registration

Another way of registering clients is through the dynamic register method defined on the OAuth2.0 specification and extended to allow OpenID Connect parameters.

This method allows the client to automatically register itself, receiving all the necessary parameters in order to integrate to the security service. Clients registered using this method will inevitably have an expiration date and its usage implies the necessity of restricting the use of the functionality to avoid exploits or security breaches.

In order to register a new client, a call must be performed to the register API Endpoint. The only mandatory parameters are redirect_uris and client_name. The rest of the parameters on this request are completely optional, which means that the Authorization Server will fill in values by default. In any case, the client can initially create a client with default configuration and update it afterward using methods described in this section.

  • Register Endpoint (POST): /oxauth/restv1/register

    • redirect_uris (mandatory): array of strings containing the redirect_uris for the client

    • client_name (mandatory): string containing the client name

    • response_types: array of strings containing the desired response types

    • grant_types: array of strings containing the desired grant types

    • application_type: can either be "web" or "native"

    • subject_type: can either be pairwise (each user is assigned a unique "sub" parameter) or public

    • token_auth_method: identifies the authentication method when retrieving tokens from the Token Endpoint

    • default_max_age: indicates the max age for tokens obtained using this client

    • default_acr_values: there is no need to assign any value to this parameter, but if set to "passport", it will redirect the user to the mediation service.

    • [Other parameters]

There is a wide variety of parameters that can be configured on this request and all of them can be checked on the discovery document:

Disovery document JSON:
GET /.well-known/openid-configuration

For example, if the client wants to use signed JSON Web Tokens, it is necessary to include the corresponding parameter in the call to the Register Endpoint. The discovery document has a field named "id_token_signed_response_alg_values_supported" with several signing methods. One of them can be selected by the client and passed through the parameter "id_token_signed_response_alg".

There is only ONE parameter that is not configurable through this dynamic method and that is the "scopes" parameter. These are filled in by the authorization server for security purposes based on the parameters received on the request. Testbed-14 behavior will be to assign the same limited scopes to all dynamic clients, but it is possible to restrict scopes based on domain, grant_types or any other parameter.

Any call to the Register Endpoint will have the Authorization Server answer back with a JSON document that indicates metadata about the recently generated client. In particular, there will be two additional fields that can be of use to the client and those are:

  • registration_access_token: a bearer token that allows the requester to list or modify metadata about a specific client

  • registration_client_uri: a URI assigned to a specific client for further interactions

There are mainly two more actions that can be performed with these parameters:

Client metadata retrieval:
GET <registration_client_uri> -H "Authorization: Bearer registration_access_token"
Client metadata update:
PUT <registration_client_uri> -H "Authorization: Bearer registration_access_token" + JSON_BODY
1.2.1.3. Basic example

The most basic example for dynamic client registration would be:

Example:
POST /oxauth/restv1/register
{
         "redirect_uris": [
              "https://client.example.org/callback",
              "https://client.example.org/callback2"
          ],
         "client_name": "Basic Client"
}

The Authorization Server would respond with the following information (example):

Example of registration response:
{
  "client_id": "@!27B7.E085.07A1.6DE7!0002!F5E4.0B8E!0008!C14A.232C.E89C.C514",
  "client_secret": "b2a5fc13-3593-4100-8287-db844b4845f2",
  "registration_access_token": "dee762cf-b134-4e2b-81fd-1238c9299135",
  "registration_client_uri": "https://testbed14-sso.elecnor-deimos.com/oxauth/restv1/register?client_id=@!27B7.E085.07A1.6DE7!0002!F5E4.0B8E!0008!C14A.232C.E89C.C514",
  "client_id_issued_at": 1533812916,
  "client_secret_expires_at": 1533816516,
  "redirect_uris": [
    "https://client.example.org/callback",
    "https://client.example.org/callback2"
  ],
  "response_types": ["code"],
  "grant_types": [
    "authorization_code",
    "refresh_token"
  ],
  "application_type": "web",
  "client_name": "Basic Client",
  "subject_type": "pairwise",
  "id_token_signed_response_alg": "RS256",
  "token_endpoint_auth_method": "client_secret_basic",
  "require_auth_time": false,
  "frontchannel_logout_session_required": false,
  "scopes": [
    "openid",
    "uma_protection",
    "permission",
    "user_name",
    "email",
    "profile"
  ]
}

Behavior by default is to utilize the Authorization Code grant, allowing refresh tokens, and the default set of scopes can be seen in the example. The client secret has also been randomly generated.

1.2.1.4. End-User clients
POST /oxauth/restv1/register
{
      "redirect_uris": [
        "https://client.example.org/callback",
        "https://client.example.org/callback2"],
      "client_name": "D142 Client",
      "token_endpoint_auth_method": "client_secret_post",
      "response_types": ["token", "id_token", "code"],
      "default_acr_values": ["passport"],
}

The "default_acr_values" set to "passport" allows the service to be redirected through a mediation service (with federation options).

1.2.1.5. Testing client (for service implementers)
POST /oxauth/restv1/register
{
      "redirect_uris": [
        "https://client.example.org/callback"],
      "client_name": "WFS Service Example",
      "token_endpoint_auth_method": "client_secret_post",
      "grant_types": ["password"]
}

1.3. Implementation Solutions for JS Clients

For web-based clients, there are several Free and Open Source JavaScript solutions available that could implement the implicit flow. In general, all of them perform a call against the Authorization Endpoint:

  • Authorization Endpoint (GET): /oxauth/restv1/authorize

    • scope: “openid geoss_user”.

    • response_type: “id_token token”.

    • client_id: Provided by Triple-A.

    • redirect_uri: <TBD>

Example:
GET /oxauth/restv1/authorize?scope=openid%20geoss_user&client_id=<TBD>&redirect_uri=<TBD>&response_type=id_token%20token

1.4. Implementation Solutions for Clients with Back-end

For back-end powered clients, there are several Free and Open Source solutions available that could implement the authorization code flow. In general, all of them perform a call against the Authorization Endpoint to retrieve a code and then exchange it for a token on the Token Endpoint:

  • Authorization Endpoint (GET): /oxauth/restv1/authorize

    • scope: “openid geoss_user”.

    • response_type: “code”.

    • response_mode: “form_post”.

    • client_id: Provided by Triple-A.

    • redirect_uri: <TBD>

Example:
GET /oxauth/restv1/authorize?scope=openid%20geoss_user&client_id=<TBD>&redirect_uri=<TBD>&response_type=code&response_mode=form_post
  • Token Endpoint (POST): /oxauth/restv1/token

    • scope: “openid geoss_user”.

    • grant_type: authorization_code.

    • code: Obtained on the previous request.

    • client_id: Provided by Triple-A.

    • client_secret: Provided by Triple-A

    • redirect_uri: <TBD>

Example:
POST /oxauth/restv1/token -d 'scope=openid%20geoss_user&client_id=<TBD>&client_secret=<TBD>&redirect_uri=<TBD>&grant_type=authorization_code&code=<CODE>

2. Authorization

2.1. Token Validation and End-user Authorization

Use this Endpoint to acquire user information:

  • User-Info Endpoint (GET): /oxauth/restv1/userinfo

    • access_token: Acquired via Token or Authorization endpoints.

Example:
GET oxauth/restv1/userinfo?access_token=<TOKEN>
The "sub" parameter

When using the openid scope, the Authorization Server will always answer with a "sub" parameter that is supposed to identify an End-User with a unique string. This will only be the case for the Authorization Grants mentioned in this Integration Guide. Other flows might collapse all subs into the client_id to avoid unintentionally leaking user information with non-OpenID grants.

2.2. Authorization: User Managed Access (UMA)

2.2.1. Authorization Flow

As a summarized flow, Authorization on UMA architectures is implemented with the following workflow:

uma
Figure 2. Authorization Flow using UMA

2.2.2. Resource Managing

Resource servers (RS) can register and list their registered resources using the API Endpoint (i.e: https://triple-a.elecnor-deimos.com/oxauth/restv1/host/rsrc/resource_set)

In order to interact with the UMA API, an access token must be requested to the Token Endpoint (which is the same as OpenID Connect Token Endpoint) including an additional scope: uma_protection. This special access token is named PAT (Protection API Token).

If a RS wants to register a resource, first a POST request must be issued to the token endpoint:

Example:
POST /oxauth/restv1/token -H 'Authorization: Bearer <PAT>' -H 'Content-type: application-json'

Body (JSON)

Example:
{
              "name": "<Resource name>",
              "uri": "<Location of the resource>",
              "type": "<Optional>",
              "resource_scopes": [<SCOPE_ARRAY (strings)>],
              "icon_uri": "<ICON_URI>"
}

The answer to this request will be a JSON with the ID of the resource under the key “_id”.

In addition, in case information about registered resources needs to be retrieved the following method is available:

GET /oxauth/restv1/host/rsrc/resource_set/<resourceId>

The parameter “resourceId” must be replaced by the ID of any registered resource. If no resource ID is passed to this Endpoint, the result will be a list of registered resources by the specific RS that performed the request.

Additionally, RS owners should manually provide the policies (set of claims) which apply to the resource so they can be registered by an admin on the UMA service. This method will be replaced by a dynamic registration of necessary claims per resource.

2.2.3. Policy Enforcement (PEP)

On the server side, 2 steps must be performed: PAT acquisition and Ticket request generation

  • PAT acquisition. will be the same request as the one mentioned on the “Resource Managing” section.

  • Ticket request.

POST /oxauth/restv1/host/rsrc_pr -H 'Authorization: Bearer <PAT_Token>' -H 'Content-type: application-json'

Body (JSON)

{
       "resource_id": "<RS_ID>",
       "resource_scopes": [<SCOPE_ARRAY (strings)>]
}

The result to this request will be a simple JSON (201 Created) with a “ticket” field. On the other hand, if the PAT token is not valid, a 401 Unauthorized response will be issued.

This ticket field will be included in a 400 or 403 response by the Resource Server, indicating where it can be exchanged for an Resource Access Token.

2.2.4. Policy Decision (PDP).

When acquiring a resource token using a ticket, the UMA service will try to check user claims (such as attributes, user ID, client ID). Some of those claims can’t be gathered using the service itself and the parameters on the request, so it might be necessary to gather those claims and get a new ticket.

POST /oxauth/restv1/token

Body (Form)

    scope=<scopes> (separated by a space)
    client_secret=<secret>
    ticket=<ticket>
    client_id=<client_id>
    grant_type=urn:ietf:params:oauth:grant-type:uma-ticket

If the ticket is valid and the user claims are matched, a Resource Token a JSON response with the field “access_token” will be issued. If not, a 403 (Forbidden) response will be issued.

This response can have another JSON attached explaining the error. If the error matches the “need_info” string, it is possible to extract an URL from the field “redirect_user” to gather any remaining claims.

GET  <redirect_user_URI>?ticket=<ticket>&client_id=<client_id>&claims_redirect_uri=<redirect_uri>

The redirect_uri in this request must be specified on the client configuration. This request will result will redirect the user to another location with the response parameters parsed in the URL. One of this parameters should be a new “ticket” that can be used to request the token again, taking into account the gathered claims.

In any case, with or without claims, the token endpoint can issue a 403 Forbidden response indicating that the policies in place forbid access to the resource. Resource Access Grant (Server side)

2.2.5. Token Introspection

A Resource Server should expect a resource token for each access request. If no token is provided, a redirection to the UMA client service should be implemented. If a token is provided, it is possible to “introspect” this token to determine if access to the resource should be granted. The RS should acquire a PAT with the same method used to manage resources.

 POST /oxauth/restv1/rpt/status -H ' Authorization: Bearer <PAT>'

Body (Form)

    Token=<Resource_Access_Token>

1. The logic implemented on this webpage should retrieve the token from the URL
2. OpenID scope is mandatory (but its use is optional) and geoss_user is default for this system