Introduction

The Single Sign-On (SSO) API enables you to let your users connect to your application using their hospital credentials.

Access Control

The Lifen Platform Solution Architects provide you with :

  • specific identifiers (client_id, client_secret) to consume the SSO API. They are different from the identifiers used to retrive a machine-to-machine token for other Lifen APIs.
  • identifiers pointing to each IdentityProvider * with which the app is connected (cf acr_values)

*An IdentityProvider is the AzureAD (or other provider) of the hospital. For example, the AzureAD of the Nîmes CHU.

You don't need a Machine To Machine Communications to use this API.

SSO Workflow

The standard Oauth2 / OIDC protocol must be executed with the following steps.

We provide an OIDC discovery mechanism: https://api.lifen.fr/sso/v1/.well-known/openid-configuration.

Step 1

Call the following url with adequate parameters :

GET api.lifen.fr/sso/v1/authorize

Since the Lifen SSO API respects the Oauth2 / OIDC protocol, we highly recommand to call it via an appropriate library which will help to abstract the procotol details. You will need to setup the library with the following parameters :

ParameterValue typeDescription & Restrictions
client_idstring$your_client_id
client_secretstring$your_client_secret
response_typestringcode
scopestringopenid email profile
redirect_uristring_Callback location where the user agent is directed to along _with the code.
statestringOpaque value to maintain state between request and callback.
acr_valuesstringThe IdP identifier, required so that we know on which IdP we should redirect the authentication request. Possible values are provided by the LifenPlatform.
login_hintstringThe user identifier. It will be used to prefill the identifier at the login step.

📘

You decide when you want to trigger a user authentication via the Lifen SSO API.

For example, in the Lifen Sending application, we have chosen to implement the Lifen SSO API in the following way : when a user fills an email linked to a hospital's SSO, we enforce a call to the Lifen SSO API.

11461146

Step 2
The user must authenticate directly via the hospital's identity provider. For example :

📘

When the user session is still active, the user skips the credentials step

If the user session is still active (the session of the hospital), the user doesn't need to fill in his password, he is directly redirected and connected to the application (via the Lifen SSO API).

Step 3
We direct you towards the redirect_uriof your application with a code (Authorization Code Flow).

Step 4
You use the code in exchange for tokens.

curl --request POST \
  --url api.lifen.fr/sso/v1/token \
  --data 'grant_type=authorization_code&redirect_uri=$redirect_uri&code=$code

Step 5
You use the id_token to define the session of the user. It is also possible to get the user information via the standard userinfo endpoint.

Example

Let's take the example of a Ruby/Rails app that would call the Lifen SSO API via a standard library (e.g. OmniAuth::OpenIDConnect).

# The configuration is centralised in the Omniauth gem and it helps abstract the protocol # :

provider :openid_connect, {
    name: :platform_sso,
    setup: lambda { |env|
      request = ActionDispatch::Request.new(env)

        env['omniauth.strategy'].options.merge!({
          issuer: config['issuer'],
          discovery: true, # (optional) OIDC standard: urls do no have to be specified manually, they can be "discovered" on a public endpoint.
          scope: [:openid, :email, :profile], # These are the defaults scopes. Custom claims (such as AzureAd groups) have to be discussed.
          response_type: :code, # Authorization Code Flow is standard (and is the only flow we support).
          state: # some_sate
          client_options: {
            identifier: $your_client_id, # client_id, provided by Lifen
            secret: $your_client_secret, # client_secret, provided by Lifen
            redirect_uri: config['redirect_uri'], # Decided by the application, shared with Lifen - that's were the user will be redirected once authenticated, with the "code"
          },
        })
      end
    },
  }

///

# The "login" view triggers the call to the library and passes the following parameters #
<%= link_to "Login with Chu-Nîmes SSO", "/auth/platform_sso?login_hint=#{user_email}&acr_values=chu-nimes", method: :post,
# login_hint and acr_values are mandatory parameters.

///

# All the protocol is handled under the hood by the library ; you retrieve all the info linked to the user after the authentication on the callback url :

class SessionsController < ApplicationController

  def create
    user_info = request.env['omniauth.auth']
        
        # Here, the app can access to the user data (or IdP session)...

        # {
        #   nbf: 1664881690,
        #   aio: "ATQAy/8TAAAAHSB7GNJ/Bj6Ed9BZbCsKUuJi2ettytPVc2nqQZXyDmUzIeOuLCTOqV6EPXyVWe54",
        #   family_name: "Martin",
        #   given_name: "Jean",
        #   groups: "["85b8c33a-412b-45ad-81fd-863335c148bf","53e64ca3-8db0-4a13-9524-59854c77b453","5d92306e-459a-4f05-972c-352612003307","8c4734d2-9010-4963-b230-fc59a5187b16"]",
        #   ipaddr: "89.207.171.76",
        #   name: "Jean Martin",
        #   oid: "a1b819fe-4372-40b8-85b2-97449d85d5f9",
        #   rh: "0.AYEABugMQPag4E24Yk6rdBRdCUn7bAS9yiRMsW1gOyF11h6BANA.",
        #   sub: "d64iPNqQBYObpISUkcnB4iP6Dkkb3DfytSz1VhqHg1o",
        #   tid: "400ce806-a0f6-4de0-b862-4eab74145d09",
        #   unique_name: "[email protected]",
        #   upn: "[email protected]",

        # And create its local session:
        @user = User.find_or_create_by(sso_id: user_info[:email]
        # etc.
  end

Log out

When a user logs out of your application, this ends the user's SSO session at the Lifen API level, not on the hospital's SSO level (AzureAD…).
For a user to log out, please use :

GET https://api.lifen.fr/sso/v1/session/logout

with the following parameters :

ParameterValue typeDescription
id_token_hintstringThe ID token to use to identify which SSO session to terminate.
statestringThe state will be returned in the final redirect.
post_logout_redirect_uristringThe URL that the user is redirected at the end of logout from Curity.
client_idstringThe client id of the requestor.

Error management

Whenever you encounter an error, please check that the acr_values parameter is correctly filled and valid.

Status codeTypeDefinition
400Bad RequestIt is likely that one of your parameters client_id or redirect_uri is invalid. Otherwise, please reach out to [email protected] with the Error identifier that appears on the error page.
401UnauthorizedIt is likely that your client_secret is invalid.

Testing environment

You can test our SSO API on our post-prod environment : api.post-prod.lifen.fr/sso/v1

In order to test the workflow from end to end (and trigger a user authentication) you need to provide us with your internal test AzureAD.