Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This page contains information, code snippets and other information regarding using Keycloak with mod_auth_openidc.

Running on Azure

HEE fork of Keycloak repository;

https://github.com/Health-Education-England/keycloak

The code for the HEE Docker container is here;

...

There is a Jenkins job that will rebuild the Keyclock Docker image;

https://build-hee.tis.transformcloudnhs.netuk/jenkins/job/keycloak-docker/

When this job completes, docker-compose runs to restart the stack on the dev server;

https://build-hee.tis.transformcloudnhs.netuk/jenkins/job/keycloak-dev-deploy/

The service should then be available at this address;

https://dev-apps.lintis.nhs.uk/auth/

Running locally

Keycloak is available from keycloak.org.  It is an application embedded in a JBoss WildFly JEE container.  The easiest way to get it working is to use an existing docker container.  This container is set up to use with a MySQL datastore.  To run Keycloak with a dockerized version of MySQL

  1. Run MySQL, if you don't have a local MySQL server running then you can create one with the following commands;

    Code Block
    $ docker run --name mysql -e MYSQL_DATABASE=keycloak -e MYSQL_USER=keycloak -e MYSQL_PASSWORD=29UTYZ735L0T8i7h6657Di71H -e MYSQL_ROOT_PASSWORD=password -d mysql


  2. If you want to create a database in an existing instead MySQL database then try the following; 

    Code Block
    create database keycloak;
    grant all on keycloak.* to keycloak@'%' identified by '29UTYZ735L0T8i7h6657Di71H';
    flush privileges;


  3. Add a DNS entry in your /etc/hosts file pointing to mysql.lintis.nhs.uk  where aaa.bbb.ccc.ddd is the IP address that your MySQL server is listening on.

    Code Block
    $ echo "aaa.bbb.ccc.ddd mysql.lintis.nhs.uk " >> /etc/hosts


  4. Start Keycloak using the docker-compose file for the stack https://github.com/Health-Education-England/TIS-DEVOPS/blob/master/docker/stacks/keycloak/docker-compose.yml 

    Code Block
    $ cd $TIS-DEVOPS/docker/stacks/keycloak
    $ docker-compose up -d


...

DirectiveValue
OIDCProviderMetadataURL

The URL for the OpenID Connect configuration on Keycloak. 

https://dev-apps.lintis.nhs.uk/auth/realms/heeadmin/.well-known/openid-configuration

OIDCClientIDThe name of the client created when setting up Keycloak
OIDCClientSecretThe secret for the client (available from the client's credentials page).
OIDCRedirectURIA redirect URL within the area of the redirect URL set up on the Keycloak client page
ServerNameThe Apache virtual host.  (Apache will default to the first virtual host in a file if no virtual host name matches)
ProxyPassThe URL of the back-end application you want to protect
ProxyPassReverseThe same as ProxyPass.  (This is used by Apache to change the Location header in 302 responses)

...

Code Block
GET /test/ HTTP/1.1
Host: dev-api.transformcloud.net
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36
Referer: https://dev-api.transformcloud.net/auth/realms/lin/protocol/openid-connect/auth?response_type=code&scope=openid&client_id=revalidation&state=B0Lm2UsfMwGy_9sy5C62ymqxONQ&redirect_uri=https%3A%2F%2Fdev-api.transformcloud.net%2Ftest%2Ftest&nonce=iFCESi2NDbvM2xcBQJ7jrLLbxP5szHCZa7k5rwQwwfY
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: session=592cebb9-85db-48ae-9483-b065f86649ec
OIDC_CLAIM_family_name: Hudson
OIDC_CLAIM_sub: b1702d1c-c8bb-4882-99f7-2c7760681b05
OIDC_CLAIM_roles: [view-profile, manage-account, judges, admin, uma_authorization, offline_access]
OIDC_CLAIM_name: James Hudson
OIDC_CLAIM_groups: East of England
OIDC_CLAIM_given_name: James
OIDC_CLAIM_preferred_username: jamesh
OIDC_CLAIM_nbf: 0
OIDC_CLAIM_jti: 268c6c62-05f9-4d8d-b2b2-04cd353cf162
OIDC_CLAIM_session_state: 55ba70b9-2f15-4068-8f4f-4fd23564e24c
OIDC_CLAIM_typ: ID
OIDC_CLAIM_exp: 1476971360
OIDC_CLAIM_iss: https://dev-api.transformcloud.net/auth/realms/lin
OIDC_CLAIM_iat: 1476971060
OIDC_CLAIM_aud: revalidation
OIDC_CLAIM_auth_time: 1476971060
OIDC_CLAIM_azp: revalidation
OIDC_CLAIM_nonce: iFCESi2NDbvM2xcBQJ7jrLLbxP5szHCZa7k5rwQwwfY
OIDC_CLAIM_acr: 1
OIDC_access_token: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJHVFNIYkRwN0JSeVhORTQ2cWZtVFFvZ1lrOFF2MERldENNSEVjNkFFeDhzIn0.eyJqdGkiOiJlYzFkMjU1Mi1lNDJjLTRhMWUtYmIyOC0yMTlkNGM3MTY5M2IiLCJleHAiOjE0NzY5NzEzNjAsIm5iZiI6MCwiaWF0IjoxNDc2OTcxMDYwLCJpc3MiOiJodHRwczovL2Rldi1hcGkudHJhbnNmb3JtY2xvdWQubmV0L2F1dGgvcmVhbG1zL2xpbiIsImF1ZCI6InJldmFsaWRhdGlvbiIsInN1YiI6ImIxNzAyZDFjLWM4YmItNDg4Mi05OWY3LTJjNzc2MDY4MWIwNSIsInR5cCI6IkJlYXJlciIsImF6cCI6InJldmFsaWRhdGlvbiIsIm5vbmNlIjoiaUZDRVNpMk5EYnZNMnhjQlFKN2pyTExieFA1c3pIQ1phN2s1cndRd3dmWSIsImF1dGhfdGltZSI6MTQ3Njk3MTA2MCwic2Vzc2lvbl9zdGF0ZSI6IjU1YmE3MGI5LTJmMTUtNDA2OC04ZjRmLTRmZDIzNTY0ZTI0YyIsImFjciI6IjEiLCJjbGllbnRfc2Vzc2lvbiI6ImJlNjQ4ODY0LWE3Y2UtNDBlMS05MGQ4LTNkY2VkOWZlYTY5MSIsImFsbG93ZWQtb3JpZ2lucyI6WyJodHRwczovL2Rldi1hcGkudHJhbnNmb3JtY2xvdWQubmV0Il0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJhZG1pbiIsInVtYV9hdXRob3JpemF0aW9uIiwianVkZ2VzIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsInZpZXctcHJvZmlsZSJdfX0sInJvbGVzIjoiW3ZpZXctcHJvZmlsZSwgbWFuYWdlLWFjY291bnQsIGp1ZGdlcywgYWRtaW4sIHVtYV9hdXRob3JpemF0aW9uLCBvZmZsaW5lX2FjY2Vzc10iLCJuYW1lIjoiSmFtZXMgSHVkc29uIiwiZ3JvdXBzIjpbIkVhc3Qgb2YgRW5nbGFuZCJdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJqYW1lc2giLCJnaXZlbl9uYW1lIjoiSmFtZXMiLCJmYW1pbHlfbmFtZSI6Ikh1ZHNvbiJ9.VxPtvyu8jlgsHumUEKEttM27jsOirn26KokGEp9MfoiOe-Z1L_IiEs-KYsdzW2J2Fwx7amgGidlvfD0uU_EuEaoU0Wrt1uuWRHMzaVztbc1ekl0vIqk7YYvz9I84ngKug8YITgTg3ZlKLOhBUrSVeT9Pz9mFTrJZhKfX7XARVsOc2HZJqgmMG5IYitZfD5uti0enuD9EfYNqnCv_6cEbc45lFNSAMjcyJWSkNN9VPEo-_NSZQrLVmOB3oNZ5vetsw5ijb6y9TQUcrDzUu6qu74_J3n2w9PrrRXVmYeYphetNZGE2LyBScJyMuYvzu6oAik2banzLc9jGiw22tGEuQQ
OIDC_access_token_expires: 1476971360
X-Forwarded-Proto: https
X-Forwarded-Port: 443
X-Forwarded-For: 89.16.226.104
X-Forwarded-Host: dev-api.transformcloud.net
X-Forwarded-Server: dev-api.transformcloud.net
Connection: Keep-Alive


Programmatic Access

The following script show how a JWT token can be To access an API programmatically, a new Keycloak user needs to be added to the LIN realm. The username and password can then be exchanged for a JWT token to make a request to a protected service. The following script show how a JWT token can be acquired and how that token is used to make an authenticated request, in this case, our jamesh user;

Code Block
#! /bin/bash

# Step3Step 1
export TOKEN=$(curl -s 'https://dev-apps.lintis.nhs.uk/auth/realms/lin/protocol/openid-connect/token' \
  -d "client_id=adminapi-clitokens&username=jamesh&password=j4m3srul3z&grant_type=password" | jq -r .access_token)

# Step 2 - optional
curl https://dev-apps.lintis.nhs.uk/auth/realms/lin/protocol/openid-connect/token/introspect \
	-d client_id=<client id> \
	-d client_secret=<client secret> \
	-d "token=${TOKEN}" \
	| python -m json.tool

# Step 3
curl -i -H "Authorization: bearer ${TOKEN}" \
 	https://dev-apps.lintis.nhs.uk/api/revalidation/health 
  1. Use use a password grant to exchange a username and password for a JWT token. The response from this command will be a JSON document with the access token with it;

    Code Block
    {
        "access_token": "<long string value>",
        "expires_in": 300,
        "id_token": "<long string value>",
        "not-before-policy": 0,
        "refresh_expires_in": 1800,
        "refresh_token": "<long string value>",
        "session_state": "<uuid>",
        "token_type": "bearer"
    }
  2. In this step, we show how the token is validated using a client id and secret. This step will be completed by mod_auth_openidc and is included for completeness.
  3. In this step, we add the "Authorization: Bearer <access token>" header to our call. Apache will intercept the call, extract the JWT and validate it before forwarding the request to the target API.

LIN Keycloak Theme

We have updated the Keycloak theme for the login screens, the new code is held in https://github.com/Health-Education-England/TIS-KEYCLOAK-THEME

To update the theme, the customised Docker image needs to be updated to include that code. There is a job to rebuild in Jenkins https://build-hee.transformcloud.net/jenkins/job/keycloak-docker/NB for testing and debugging locally, use a token generated using:

curl -s 'https://dev-apps.tis.nhs.uk/auth/realms/lin/protocol/openid-connect/token'  -d "client_id=api-tokens&username=jamesh&password=j4m3srul3z&grant_type=password" | jq -r .access_token

Or

curl -s 'http://localhost:8087/auth/realms/lin/protocol/openid-connect/token' -d "client_id=api-tokens&username=jamesh&password=j4m3srul3z&grant_type=password" | jq -r .access_token

Note: the client_id = api-tokens. This will bring back user roles etc

  1. Use use a password grant to exchange a username and password for a JWT token. The response from this command will be a JSON document with the access token with it;

    Code Block
    {
        "access_token": "<long string value>",
        "expires_in": 300,
        "id_token": "<long string value>",
        "not-before-policy": 0,
        "refresh_expires_in": 1800,
        "refresh_token": "<long string value>",
        "session_state": "<uuid>",
        "token_type": "bearer"
    }


  2. In this step, we show how the token is validated using a client id and secret. This step will be completed by mod_auth_openidc and is included for completeness.
  3. In this step, we add the "Authorization: Bearer <access token>" header to our call. Apache will intercept the call, extract the JWT and validate it before forwarding the request to the target API. 

    Code Block
    GET /test/ HTTP/1.1
    Host: dev-apps.tis.nhs.uk
    User-Agent: curl/7.49.1
    Accept: */*
    Authorization: bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJrcEk5UC1hQ3JaTXJ4cG5aeWNnNnlISk9VZ3g0a2hUYS04TlJyMkRhY0g0In0.eyJqdGkiOiI4MTNhNzUzMS04NmIzLTRjOTgtODY4ZS01NzA5M2E4NDY2MmQiLCJleHAiOjE0ODA2MDkyNzQsIm5iZiI6MCwiaWF0IjoxNDgwNjA4OTc0LCJpc3MiOiJodHRwczovL2Rldi1hcHBzLmxpbi5uaHMudWsvYXV0aC9yZWFsbXMvbGluIiwiYXVkIjoiYWRtaW4tY2xpIiwic3ViIjoiNGY5YWRhY2MtZjEyNC00M2FmLTkyZDMtYjVlZDc3NjhlYTU0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYWRtaW4tY2xpIiwiYXV0aF90aW1lIjowLCJzZXNzaW9uX3N0YXRlIjoiZDM0M2ZiYmUtZjYxMS00YTg3LWE0ZTktODg0ODI0ZTYzN2VkIiwiYWNyIjoiMSIsImNsaWVudF9zZXNzaW9uIjoiODZkZTk0NTQtYmY1Ny00ZDM2LThjYjItOWU0ZjllMDA3MTQ2IiwiYWxsb3dlZC1vcmlnaW5zIjpbXSwicmVzb3VyY2VfYWNjZXNzIjp7fSwibmFtZSI6IkphbWVzIEh1ZHNvbiIsInByZWZlcnJlZF91c2VybmFtZSI6ImphbWVzaCIsImdpdmVuX25hbWUiOiJKYW1lcyIsImZhbWlseV9uYW1lIjoiSHVkc29uIn0.F_wFf1T_kEdcZDlG_H45lk5uukN26trTsPHcko-RF7Zk9VXLjPX6HcExASUmxMqMTBRrbYuLDDPWGZ7OoKHIp-bG-3wR3XqGDTVgQ-DbzarAtEDKsNbAzReh008uo_U3j9biwKHcWNOAFuSde5ZUma5qWS6jvpV750lwCb7WU8xikci9lD_WK6xW_H1B_KW8WJ4SpoH7qNI1OITFtMOQBx06z2q-DQVc_3bISwDKx-sFj6MFOr-0OcXz935H1OJICFYjljquY5q-6ZkB0bwVKVpOKd22q7cnAT50bzAbXCQifja0Jr9qVUytq79QxEDeGeAo40WzPO_a7PPTkfvHdw
    OIDC_CLAIM_name: James Hudson
    OIDC_CLAIM_allowed-origins: 
    OIDC_CLAIM_typ: Bearer
    OIDC_CLAIM_azp: admin-cli
    OIDC_CLAIM_jti: 813a7531-86b3-4c98-868e-57093a84662d
    OIDC_CLAIM_sub: 4f9adacc-f124-43af-92d3-b5ed7768ea54
    OIDC_CLAIM_nbf: 0
    OIDC_CLAIM_auth_time: 0
    OIDC_CLAIM_session_state: d343fbbe-f611-4a87-a4e9-884824e637ed
    OIDC_CLAIM_exp: 1480609274
    OIDC_CLAIM_client_session: 86de9454-bf57-4d36-8cb2-9e4f9e007146
    OIDC_CLAIM_iat: 1480608974
    OIDC_CLAIM_iss: https://dev-apps.tis.nhs.uk/auth/realms/lin
    OIDC_CLAIM_aud: admin-cli
    OIDC_CLAIM_given_name: James
    OIDC_CLAIM_family_name: Hudson
    OIDC_CLAIM_acr: 1
    OIDC_CLAIM_preferred_username: jamesh
    OIDC_CLAIM_username: jamesh
    OIDC_CLAIM_resource_access: {}
    OIDC_CLAIM_client_id: admin-cli
    OIDC_CLAIM_active: 1
    OIDC_access_token: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJrcEk5UC1hQ3JaTXJ4cG5aeWNnNnlISk9VZ3g0a2hUYS04TlJyMkRhY0g0In0.eyJqdGkiOiI4MTNhNzUzMS04NmIzLTRjOTgtODY4ZS01NzA5M2E4NDY2MmQiLCJleHAiOjE0ODA2MDkyNzQsIm5iZiI6MCwiaWF0IjoxNDgwNjA4OTc0LCJpc3MiOiJodHRwczovL2Rldi1hcHBzLmxpbi5uaHMudWsvYXV0aC9yZWFsbXMvbGluIiwiYXVkIjoiYWRtaW4tY2xpIiwic3ViIjoiNGY5YWRhY2MtZjEyNC00M2FmLTkyZDMtYjVlZDc3NjhlYTU0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYWRtaW4tY2xpIiwiYXV0aF90aW1lIjowLCJzZXNzaW9uX3N0YXRlIjoiZDM0M2ZiYmUtZjYxMS00YTg3LWE0ZTktODg0ODI0ZTYzN2VkIiwiYWNyIjoiMSIsImNsaWVudF9zZXNzaW9uIjoiODZkZTk0NTQtYmY1Ny00ZDM2LThjYjItOWU0ZjllMDA3MTQ2IiwiYWxsb3dlZC1vcmlnaW5zIjpbXSwicmVzb3VyY2VfYWNjZXNzIjp7fSwibmFtZSI6IkphbWVzIEh1ZHNvbiIsInByZWZlcnJlZF91c2VybmFtZSI6ImphbWVzaCIsImdpdmVuX25hbWUiOiJKYW1lcyIsImZhbWlseV9uYW1lIjoiSHVkc29uIn0.F_wFf1T_kEdcZDlG_H45lk5uukN26trTsPHcko-RF7Zk9VXLjPX6HcExASUmxMqMTBRrbYuLDDPWGZ7OoKHIp-bG-3wR3XqGDTVgQ-DbzarAtEDKsNbAzReh008uo_U3j9biwKHcWNOAFuSde5ZUma5qWS6jvpV750lwCb7WU8xikci9lD_WK6xW_H1B_KW8WJ4SpoH7qNI1OITFtMOQBx06z2q-DQVc_3bISwDKx-sFj6MFOr-0OcXz935H1OJICFYjljquY5q-6ZkB0bwVKVpOKd22q7cnAT50bzAbXCQifja0Jr9qVUytq79QxEDeGeAo40WzPO_a7PPTkfvHdw
    X-Forwarded-Proto: https
    X-Forwarded-For: 89.16.226.104
    X-Forwarded-Host: dev-apps.tis.nhs.uk
    X-Forwarded-Server: dev-apps.tis.nhs.uk
    Connection: Keep-Alive


LIN Keycloak Theme

We have updated the Keycloak theme for the login screens, the new code is held in https://github.com/Health-Education-England/TIS-KEYCLOAK-THEME

To update the theme, the customised Docker image needs to be updated to include that code. There is a job to rebuild in Jenkins https://build-hee.transformcloud.net/jenkins/job/keycloak-docker/

Styling updates to keycloak theme

It is possible to tweak the styling for a keycloak theme without having to run keycloak locally via using charles https://www.charlesproxy.com/download/ which is a web proxy application. This is achieved by locally mapping the remote css file responsible for the theme to a local css file on your computer. 

For example the remote css file https://stage-apps.tis.nhs.uk/auth/resources/2.2.2.final-snapshot/login/lin/css/login.css can be mapped to /Users/XXX/Sites/HEE/keycloak/themes/lin/login/resources/css/login.css which essentially means you can locally work on the css and once done can push your changes to the git repo mentioned above as well as triggering the jenkins job https://build-hee.transformcloud.net/jenkins/job/keycloak-dev-deploy/

Steps to map a remote file locally

  1. Enable SSL proxing for the host


Image Added


2. Choose file to map

Image Added


3. Point to local file

Image Added


MS OpenID Connect Identity Provider

The token that comes back from MS looks like this

Code Block
{
  "aud": "f78cc2a2-14a9-4a2f-88f5-b3ff97a7503a",
  "iss": "https://sts.windows.net/ffa7912b-b097-4131-9c0f-d0e80755b2ab/",
  "iat": 1505401768,
  "nbf": 1505401768,
  "exp": 1505405668,
  "aio": "ASQA2/8EAAAAEvvKfmk+oS98uxWCI6jY0B1Q9fsdaffsdDsEcwShm5Y=",
  "amr": [
    "pwd"
  ],
  "family_name": "Smith",
  "given_name": "James",
  "ipaddr": "86.131.216.237",
  "name": "James Smith",
  "oid": "ad8b4d53-7f0e-4669-a9f3-05b29b558025",
  "sub": "mpoaBkQgd9GviZ3E9V9TOxRabdhLm7_54gVqcbNN5Zc",
  "tid": "ffa7912b-b097-4131-9c0f-d0e80755b2ab",
  "unique_name": "XXXXXXX@hee.nhs.uk",
  "upn": "XXXXXXX@hee.nhs.uk",
  "ver": "1.0"
}


https://dev-apps.tis.nhs.uk/auth/admin/master/console/#/realms/lin/identity-provider-mappers/msoidc/mappers


MS Token ClaimKeycloak Attribute 
upnemail
given_namefirstName
family_namelastName

Useful Links

http://paulbakker.io/java/jwt-keycloak-angular2/

...