Oauth2 Authentication

Introduction

The API supports OAUTH2 authentication from version 11.16 .

This feature allows a user to connect with an external account to obtain a JWT token to call the API services. The API is designed to support OpenID Connect, but can by used with some non OpenID servers.

Configuring a OAuth2 authentication server (provider)

configuration

To configurate an authenticiation server, go to REST API administration, in the OAuth2 Set-up section, then create a new configuration from scratch, or duplicate a provided preconfigured one.

The following default configurations are provided as standard:

In the default configuration, the tenant is pre-positioned by the {tenant} pattern that will have to be replaced by the appropriate tenant identifier

  • linkedin: (as a non openid example), to connect with LinkedIn

properties

Configuring an authentication server consists of:

  • set up a description

    • name of the configuration is the ID of the authentication server. user a simple alphanumeric string without accent or special characters

    • description, string

      A short description

    • activated, boolean

      The configuration of an authentication server must be enabled to be used to authenticate a user by this authentication server. If you try to use a disabled configuration, you will get a status 'Not found' (404).

  • set up the URLs that will be used for the authentication process

    • authorizationEndPoint, URL, mandatory, authorization end point

      This end point is used in an authorization protocol by login form whose validation redirects to the appropriate sign in url to provide an access code to the server

    • tokenEndPoint, URL, mandatory, token end point

      This end point converts the access code to a token

    • userInfoEndPoint, URL, mandatory, information end point

      This end point is used to retrieve user information

    • tokenValidationEndPoint, URL, validation end point

      This end point is used to validate a token.

    • introspectionEndPoint, URL, introspection end point (RFC 7662)

      This end point is used to validate a token and retrieve information.

    • revocationEndPoint, URL, revocation end point

      This end point is used to revoke the token after a JWT token is produced (this behavior can be disable even the end poitn URL is configured)

    • configurationEndPoint, URL, Configuration end point

      This end point is not used at the moment, but will be used later to automatically configure an authentification server

    • jwkSetEndPoint, URL, JWK end point

      This end point is used to get validation key for an internal validation (currently not implemented)

  • set up an API key

    • clientID, string, mandatory

      The API client ID provided by the authentication server

    • clientSecret, string, mandatory

      The API client secret provided by the authentication server

  • set up connection behavior

    • scopes, array of strings, scopes

      The list of scopes the REST API can request to the authentication server. Usually, the scopes are the following opendid claims:

      • email, to get the email, usually used for pivot (common single property involving both users)

      • profile, to get name, locale…​

      • openid, to get the open_id token

    Without these scopes, it can be tricky to configure a completely discrete mapping, or to enable automatic user creation.

    • autorevoke, boolean, default is true if revocationEndPoint is set

      activate revocation of token at the end of authentication process

    • prompt, string (as comma separated values)

      a standard OAuth2 prompt mode, that must be supported by the authentication server

      Example values are:

    • organization, object

      the configuration of the token property that contains the organization ID (corresponding to the tenant for Microsoft Azure AD), if you want to check its value

      • propertyName, string, mandatory

        the name of the property in the token

      • parameterName, string,

        the name of the parameter, if the organization ID must be sent in URL

      • sendInAuthRequest, a boolean (default false).

        If set to true, it means the organization ID must be add as parameter in URL

      • id, string

        the value of the organization, to be checked

    • includeIdToken, boolean (default is false)

      if true, the open_id token will be sent back in the sign in request.

    • loginhint, array of strings

      The list of properties used the list of properties used to determine the login hints. The first one found is returned in the sign in response, and can be read invoking the whoami end point also. It can be used by a caller within the parameter login_hint.

  • Set up presentation,

    Allows Web client application to automatically generates its login form (with data retrieved from the end point https://application/api/rest/auth/config)

    • providerName, string

      The human readable name of the authentication server, used by example in the text of the "Sign in with <provider name>" button

    • icons, object

      Different icons (FontAwesome) or images that can be used to decorate a "Connect with" button

  • usermappings

    How to select an existing user, create a new one, or refuse connection, based on the token information.

Building client side login form

End point: https://application/api/rest/auth/config

This end point, which does not require any authorization, allows you to obtain a configuration that allows you to customize a client login form, and perform the URL invocations necessary for the connection workflow (authentication and authorizations) of your client application, in order to invoke the REST API.

Example:

{ "providers":[ { "id":"authlete", "name":"Authlete", "label":"Sign in with Authlete", "loginHref":"https://application/api/rest/auth/login/authlete", "signinHref":"https://application/api/rest/signin/authlete", "icons":{ "main":{ "type":"url", "url":"https://application/api/rest/auth/rsc/authlete/main", "backgroundcolor":"black" } } }, { "id":"facebook", "name":"Facebook", "label":"Sign in with Facebook", "loginHref":"https://application/api/rest/auth/login/facebook", "signinHref":"https://application/api/rest/signin/facebook", "icons":{ "main":{ "type":"url", "url":"https://application/api/rest/auth/rsc/facebook/main", "backgroundcolor":null }, "fa":{ "type":"fontawesome", "name":"fa-facebook", "color":"white", "backgroundcolor":"#3B5998" } } }, { "id":"google", "name":"Google", "label":"Sign in with Google", "loginHref":"https://application/api/rest/auth/login/google", "signinHref":"https://application/api/rest/signin/google", "icons":{ "main":{ "type":"url", "url":"https://application/api/rest/auth/rsc/google/main", "backgroundcolor":null }, "bitmap_light":{ "type":"url", "url":"https://application/api/rest/auth/rsc/google/bitmap_light", "backgroundcolor":null }, "bitmap_dark":{ "type":"url", "url":"https://application/api/rest/auth/rsc/google/bitmap_dark", "backgroundcolor":null }, "fa":{ "type":"fontawesome", "name":"fa-google", "color":"#DB4437", "backgroundcolor":null } } }, { "id":"microsoft", "name":"Microsoft", "label":"Sign in with Microsoft", "loginHref":"https://application/api/rest/auth/login/microsoft", "signinHref":"https://application/api/rest/signin/microsoft", "icons":{ "main":{ "type":"fontawesome", "name":"fa-microsoft", "color":"#00a1f1", "backgroundcolor":null }, "svg":{ "type":"url", "url":"https://application/api/rest/auth/rsc/microsoft/svg", "backgroundcolor":null }, "bitmap":{ "type":"url", "url":"https://application/api/rest/auth/rsc/microsoft/bitmap", "backgroundcolor":null } } } ], "version":"1.0", "status":200, "time":14 }

The array providers lists every available oauth2 authentication server. For each of them, you’ll get:

  • id: an unique ID

  • name: a name

  • label a standard label for a button

  • loginHref: the URL of the login end point

  • signinHref: the URL of the signin end point

  • icons: a list of icon descriptions

    Each icon has an identifier from the configuration.

The configuration does not impose a nomenclature, but to manage automation more easily, recommendations are given (see configuration)

  • type: the type of icon

    Types:

    • url: the image can be displayed via an <IMG> tag, from the provided URL

      The specific parameters are:

      • url: the url of the image

    • fontawesome: then image is an Font Awesome icon.

      The specific parameters are:

      • name: the Font Awesome name

      • color: (optional, could be null) a value for the CSS Color property.

    • backgroundcolor: (optional, could be null) a value for the CSS Background-Color property.

Not all icons may be viewable depending on the version of Font Awesome used on the client. It is possible to test the existence of an icon with the following JavaScript function (checkFontAwesome("fa-totest") returns true if icon exists, false else).

Example for FontAwesome 4.7:

function checkFontAwesome(name) { return faUnicode(name)!=null; } function faUnicode(name) { var testI = document.createElement('i'); var char; testI.className = 'fa ' + name; document.body.appendChild(testI); char = window.getComputedStyle( testI, ':before' ) .content.replace(/'|"/g, ''); testI.remove(); if ( char==='none' ) { return null; } return char.charCodeAt(0); }

token introspection or decoding

Authentication end point

End Point : https://application/api/rest/signin/{providerId}

This end point provides valid connection data (JWT tokens) for using the REST API.

There are many and varied ways of using it :

  • by passing token (produced by the authentication server), as parameters access_token, token_type and expires_in (including multipart/form-data).

  • via the Authorization header as a Bearer,

  • in the content as a response to the invocation of the corresponding end point of the authentication server, i. e. as:

    { "access_token": "the access token...", "token_type": "Bearer", "expires_in": number of seconds before expiration }
  • by passing a code (produced by the authentication server) as parameter code. This is the mode used while redirection from the authentication server login page.

When a code is provided, it is first transformed into a token. The token is validated and the user data are extracted. If code and token are provided, it is also checked that they are consistent with each other.

Client side login workflow handled by server

End Point : https://application/api/rest/auth/login/{providerId}

This endPoint displays the HTML login form associated with the authentication server. When the user is authenticated, the form redirects to the end authentication point of the REST API (https://application/api/rest/signin/{providerId}).

It is possible at the end to get back the REST API JWT tokens:

  • as request response (not recommended, particularly within Web MPA)

  • as request parameter

  • as session attribute

  • as URL fragment

request response

As the answer will be displayed directly in the browser, it is not easy to follow the standard navigation of the site. In addition, cross-domain protection prevents window events from being listened to. The only solution is to polling the login window until the location and content-type are readable, then close this window and pass the contents of the window back to the main window to continue on to the authenticated navigation on the site.

This method is not recommended because:

  • it requires to open a second window for the login specific to the authentication provider

  • this window remains visible for a short time with the entire response visible (due to the polling period and the reaction time of the navigator)

  • on some browsers, the answer will not be displayed in the window and will cause the workflow type of file downloading

  • the implementation in JavaScript is not very elegant

request parameter

When invoking the login end point, add the following parameters :

  • redirectUrl: String. The URL of your login page (the one where your "Sign in with…​" buttons are displayed). At the end of the authentication process, it will be invoked by passing the connection data (refresh and access JWT tokens and other related data - see JWT token authentication for more details) the authresponse parameter.

  • redirectUrlMode: with the value parameter

It is easy to retrieve the parameter in JSP or JavaScript. This method is not recommended if the web application is internal to the Wedia system because the setting is visible in the address bar. It is possible to remove it in JavaScript, but this requires reloading the page. Be careful not to use direction window.document.location.href as a value for the parameter redirectUrl, if you have not deleted the parameter: indeed, the url will at some point be passed in the Referer header and it happens that the server servlet causes an error because of its excessive size.

session attribute

When invoking the login end point, add the following parameters :

  • redirectUrl: String.

    The URL of your login page (the one where your "Sign in with…​" buttons are displayed). At the end of the authentication process, it will be invoked by passing the connection data (refresh and access JWT tokens and other related data - see JWT token authentication for more details) the authresponse parameter.

  • redirectUrlMode: (optional, default value is attribute) with the value attribute

    This mode passes connection data through a session attribute that can be easily retrieved in JSP (normally, the one that generates the login page of your application) and without this data being visible in the URL. The defect of this method is that it can only be used in an application hosted by the Wedia server.

URL fragment

This is a variation a the request parameter, but as the value is in the fragment, you can get easily in your Web client application in JavaSCript, but this data will never be send to server if the URL is invoked.

Client side login handled by application

End Point : https://application/api/rest/signin/{providerId}

Just as the authentication server will provide a code or token to the end authentication point of the REST API by redirection, it is possible to invoke the URL directly from a client.

The authorization modes that pass through the server only support the response type code, but a client implementation can use the mode it wants (code, token, code token, credentials (not recommended)…​) as long as it respects at the end one of the processing modes implemented by this end point.

The state parameter

The state parameter can be passed to login URI end point (https://application/api/rest/auth/login/{providerId}) to verify the token when it is obtained. It’s a random string your application will generate and the final response will return you as it stands, allowing you to check if the response matches the request.

Dealing with errors

Use the same methods to handle errors as any other end point of the REST API. Sometimes, the error can go directly from the authentication server: in this case, it is mapped to an internal error but its documentation can be external.

User mapping

The configuration of each OAuth2 provider allows to configure how a Wedia user (internal user) is mapped with the external user.

There are 2 phases: selection and mapping.

selection

The configuration of the selection phase allows to indicate how a mapping will be selected or not according to the user’s information.

You can configure directly in the configuration form which properties or parts of properties should be used and which values they should have to select which mapping. Or you can do this with a component coded in Java (loaded from your own plug-in).

If no mapping is selected, the user is denied access to the API

mapping

Mapping consists in associating an internal user with the user who has authenticated himself (external user), using properties of the internal user and the external user to bind them (same email, same name, etc.). Mappings can be configured directly in the configuration form or done via a component coded in Java (loaded from your own plug-in).

With the mapping, in the configuration form, you can:

  • bind an existing internal user corresponding to the external user

  • create a new internal user (or deny access to user that hasn’t any internal user corresponding)

  • bind to a dedicated reserved user (limited rights for example). This mode does not prevent the connection from associating the external user’s personal information (e. g. e-mail or name) with the connection.

trigger post connection

It is possible to set up a component coded in Java (loaded from your own plug-in) that will be invoked when the connection is effective.

Support of protocol and limitations

Java coded extensions

To code Java extensions, you only to get from WXM-RESTAPI plug-in the jar restapibs.jar and put in your own plug-in. Then implement the interface you need and build the class into a jar you’ll include to the plug-in. Then activate the plug-in. That’s all for usual cases: some times, you’ll have to select the plugin and the class in a configuration form.

Available interfaces:

  • com.noheto.restapi.OAuth2UserBinding: this interface allows you to code the selection of mapping, the mapping or both processes in Java. The data of user and provider can be get from the invocation context with the interface com.noheto.restapi.OAuth2UserBindingContext.

It is better to use the abstract base provided than to fully implement the interface (com.noheto.restapi.OAuth2UserBindingAdapter). You will only have to implement the parts that interest you without thinking about the rest..

  • com.noheto.restapi.OAuth2IdTokenValidation: this interface allows you to validate a token by Java code. This is useful if you the provider provides a Java API to validate token. The data of user and provider can be get from the invocation context with the interface com.noheto.restapi.OAuth2IdTokenValidationContext.

It is better to use the abstract base provided than to fully implement the interface (com.noheto.restapi.OAuth2IdTokenValidationAdapter). You will only have to implement the parts that interest you without thinking about the rest.

mapping

Example of selection and mapping Java-coded extension

This is the one use for google authentication in ClubWed demo.

Example of trigger post connection

Send a mail with data from a user: