lemonldap-ng/doc/sources/admin/testopenidconnect.rst

133 lines
5.5 KiB
ReStructuredText

Test OpenID Connect with command line tools
===========================================
We present here how to test the OpenID Connect protocol (authorization code flow) with commande line tools, like `curl`.
We use in this example a public OIDC provider based on LL::NG: `<https://oidctest.wsweet.org>`_
Authentication
--------------
The first step is to obtain a valid SSO session on the portal. Several solutions:
* Use a web browser and log into the portal, then get the value of the SSO cookie
* Use portal REST API, and adapt the `requireToken` configuration to get cookie value in JSON response (see :doc:`REST services<restservices>`)
Example of REST service usage, with credentials `dwho`/`dwho`:
.. code-block:: shell
curl -X POST -d user=dwho -d password=dwho -H 'Accept: application/json' 'https://oidctest.wsweet.org/oauth2/'
The session id is displayed in JSON response:
.. code-block:: javascript
{
"error" : "0",
"id" : "0640f95827111f00ba7ad5863ba819fe46cfbcecdb18ce525836369fb4c8350b",
"result" : 1
}
Authorization code
------------------
In the first step of authorization code flow, we request a temporary code, ont the `authorize` end point.
Parameters needed:
* SSO session id (will be passed in `lemonldap` cookie, adapt the name if needed)
* Client ID: given by your OIDC provider, we use here `private`
* Scope: depends on which information you need, we will use here `openid profile email`
* Redirect URI: shoud match the value registered in your OIDC provider, we will use here `http://localhost`
The OIDC provide will return the code in the location header, so we just output this reponse header:
.. code-block:: shell
curl -s -D - -o /dev/null -b lemonldap=0640f95827111f00ba7ad5863ba819fe46cfbcecdb18ce525836369fb4c8350b 'https://oidctest.wsweet.org/oauth2/authorize?response_type=code&client_id=private&scope=openid+profile+email&redirect_uri=http://localhost' | grep '^location'
The value of the location header is:
.. code-block:: shell
location: http://localhost?code=294b0facd91a0fa92762edc48d18369e99c330ba2b8fb05ab2c45999fcef6e17&session_state=BpB8KRMBEDUs%2B7lAjsz4DRk3E0RJImxgUbMsCFFAUa8%3D.N3dVOFg3a2RpNXVJK3ltSldrYXZjUjhtU0tvd29sWkpuWWJJbll5ZGs5NzhZMnh5bmQwd0IxRmJVWUxJSTlkWDBnSWZ2SWFVZmU0UnRaMkVJVjNUY3c9PQ
So we get the code value: `94b0facd91a0fa92762edc48d18369e99c330ba2b8fb05ab2c45999fcef6e17`
This code has a short lifetime, we will use it to get access token and ID token in the next step
Tokens
------
In this step, we exchange the authorization code against tokens:
* Access token
* ID token
* Refresh token (optional)
Parameters needed:
* Authorization code: see previous step
* Grant type: we use here `authorization_code`
* Redirect URI: same value as the one used in the previous step
* Client ID and Client Secret: given by your OIDC provider, we use here `private`/`tardis`
.. code-block:: shell
curl -X POST -d grant_type=authorization_code -d 'redirect_uri=http://localhost' -d code=94b0facd91a0fa92762edc48d18369e99c330ba2b8fb05ab2c45999fcef6e17 -u 'private:tardis' 'https://oidctest.wsweet.org/oauth2/token' | json_pp
The JSON response looks like this:
.. code-block:: javascript
{
"access_token" : "a88b8dde538719e55c3cb8fbd14d06ed77853c685a62abf6ecb88d86228a9c64",
"expires_in" : 3600,
"id_token" : "eyJhbGciOiJSUzI1NiIsImtpZCI6Im9pZGN0ZXN0IiwidHlwIjoiSldUIn0.eyJhdXRoX3RpbWUiOjE2MTQxNjAwMDYsImlhdCI6MTYxNDE2MzIxOCwiaXNzIjoiaHR0cHM6Ly9vaWRjdGVzdC53c3dlZXQub3JnLyIsImF0X2hhc2giOiJIVGswOVNjSjRObEFua3k5SGFFX2VRIiwiYWNyIjoibG9hLTIiLCJleHAiOjE2MTQxNjY4MTgsInN1YiI6ImR3aG8iLCJhenAiOiJwcml2YXRlIiwiYXVkIjpbInByaXZhdGUiXX0.N3TNufjKLzKM3qiIitA7JHUei4L572XjF6AcVl7UAFB6efdGUCiAL7amlUl0FgjZfzW9bzvulBVDidoYSicIaysIdI4KkjmjpVN0Z3gOSu0ecuk5p8fD1KbX6-tmA3txeR18nzfhdckq-S-6Lx7wrWpPNyrzGx-FImbOaUPN2yeVhKPXhdyHJbzI0RqJETxnBkyW-CLEzAJyq3rCUVX-D8kHADvg6a42QQyPdxvBuGrdBfyDDDb_Py13H1qhn40NnuFknR1wSahsY6U97uUooyk-0_U4J3XJAHySjCtivtSeP0fM_5eblMuh6WdVjrfnUF0xnCTbCa2gYRlTS38BkqcsWY26PXoRAOo31a1cmB5sMSZyPtRF9UZcmGiNBIymMMdFgVAJONb6uliiTS5j9-nkmHOqVC-XJ6tuiU3ZSBQ8nCRyNW2LaCzpJ5c3ytP9yYQtyT8HmhN0VnXob3K1uJEA_Xcu4sADjtrm-LbrGiwaVMkfu-C6YIrbuC9riOW6TneV2gAzAjXPOW_UZeXrCrx66GHIJPsJIq29UfbTN5Pxo9SH2yKw6PSfxevkZhBIhEXCOMaIUHrlWz2jDBBzPIWeiSRbK_MRtejQmdRUs8nqdq-McVwnFiUMDt1KZXxqScTtMDF_Lo9oK2RaCijEJ7MSPEscr_YOyp3KIq2FLVg",
"refresh_token" : "19434440ed4da2803e8ba9d91cb2eabd5b8bd12af2609429bda03ed487e6ef57",
"token_type" : "Bearer"
}
The access token will be used for the last step, to get information about the user.
The ID Token is a JWT (JSON Web Token) and can be parsed easily, as this is the concatenation of 3 JSON strings encoded in base 64: `base64(header).base64(payload).base64(signature)`.
Decoding the payload gives:
.. code-block:: javascript
{
"acr" : "loa-2",
"at_hash" : "HTk09ScJ4NlAnky9HaE_eQ",
"aud" : [
"private"
],
"auth_time" : 1614160006,
"azp" : "private",
"exp" : 1614166818,
"iat" : 1614163218,
"iss" : "https://oidctest.wsweet.org/",
"sub" : "dwho"
}
User info
---------
This step is optional and allows to fetch user information linked to scopes requested in the first step.
Parameters needed:
* Access token, used as bearer authorization
.. code-block:: shell
curl -H 'Authorization: Bearer a88b8dde538719e55c3cb8fbd14d06ed77853c685a62abf6ecb88d86228a9c64' 'https://oidctest.wsweet.org/oauth2/userinfo' | json_pp
JSON response:
.. code-block:: javascript
{
"email" : "dwho@badwolf.org",
"name" : "Doctor Who",
"preferred_username" : "dwho",
"sub" : "dwho"
}