Single sign-on (SSO)

Overview


It is a common request for an external system to be able to launch the PKB GUI for a given user (either patient or clinician), without the user needing to manually re-enter their PKB credentials. For this to work, the external system, or a proxy acting on its behalf, needs to authenticate against PKB on behalf of the user it knows to be currently logged in, and then launch PKB in the correct context. The external system may make use of the dataFromOtherOrg REST API call, which highlights if there is data present in PKB which may not be visible in the users system.

Relevant PKB Design Principles


  • In order to authenticate against the PKB, an external system must provide either:

  • The password of the authenticating user (not currently supported in any automated flow)

  • A valid OAuth2 access token associated with the authenticating user


Without one of these, PKB is unable to gain access to the private decryption keys for the authenticating user, and as such is not able to complete the log in. This principle is important, because it means that an external system cannot simply send a pre-agreed alias or passphrase which PKB will accept in lieu of the actual password or OAuth2 token. Even if PKB entirely trusts the request from the external system to log in a specified user, it is not possible to perform the login without one of these two pieces of data.

OAuth2 Based Solution

OAuth2 allows a more secure authentication procedure than exchanging passwords directly.. The solution below requires extra development effort on the part of the external system, but offers significant security and usability improvements.

OAuth2 allows a user to authenticate against the PKB REST API. The steps below indicate how an external system would make use of the REST API to launch a user into the PKB GUI without that user manually re-entering their credentials (after initial pairing).


Further information about this process is provided here.


Initial pairing


  1. A PKB user initiates a workflow on the external system (e.g. clicks a link) that indicates their desire to pair their PKB account with the external system.


  1. The external system redirects the user to an authentication page, hosted by PKB.


Sandbox URL

(example values)

https://sandbox.patientsknowbest.com/apiAuthorize.action?response_type=code&client_id=TRUST_USER_CLIENT_ID&scope=CLINICIAN&state=CLIENT_PROVIDES_ANTI_CRSF&redirect_uri=https://client.example.com/pkbLanding

Authentication

The URL should contain the Trust’s User Client ID, since an actual human is being authenticated.



  1. The user enters and submits their PKB credentials into the PKB authentication page.


  1. PKB will validate these credentials, and then generate an authorization code. The user will be redirected back to a URL hosted by the external system (previously agreed with PKB). The redirect URL will include the authorization code (valid for a short period of time).


Redirected URL

(example values)

https://client.example.com/pkbLanding?code=oPkr3gloNe3sNg2k-_vIc9vd3gr42TIY



  1. The external system sends this authorization code to PKB in order to exchange it for an access and refresh token pair.


Sandbox URL

https://sandbox.patientsknowbest.com/apiToken.action

HTTP method

POST

Authentication

The form parameters should contain the Trust’s User Client ID, since an actual human is being authenticated.

Form Parameters

(example values)

grant_type = authorization_code

client_id = TRUST_USER_CLIENT_ID

code = oPkr3gloNe3sNg2k-_vIc9vd3gr42TIY

redirect_uri = https://client.example.com/pkbLanding


  1. In response, PKB returns an access and refresh token, each of which are associated only with the authenticated user.


Response

(example values)

{

 "access_token":"AT3EvOxGqVAFgE7i-YzSbZ8mM_aw8jU2",

 "token_type":"Bearer",

 "expires_in":30,

 "refresh_token":"iYS26gLWCBDmz6mD-YzSbZ8mM_aw8jU2",

 "scope":"clinician"

}



  1. The external system stores both of these tokens in a local database, along with whatever identifier the external system uses to identify the currently logged in user.

Ongoing usage


  1. Subsequently, when the user wishes to access the PKB web application, they will initiate this workflow in the external system (e.g. clicks a link).


  1. The external system looks up the access token associated with this user in their local database.


  1. The external system requests a One Time Password (OTP) from the PKB REST API, providing the access token as part of the request.


Sandbox URL

https://sandbox.patientsknowbest.com/json/v1/otp

HTTP method

GET

Authentication

The access token associated with the user who wishes to log in to the web interface.

HTTP Headers (example values)

authorization = Bearer Ap2fw5ILoTFUgE9i-ZzTKzlmPUaf7jB4


  1. PKB will respond with an OTP.


Response

(example values)

{

   "otp_token":"gnUF6vXCWhZ9QgD4-7s6TE1bSiqfUniw"

}


  1. The external system automatically redirects the user to the PKB web application, including the OTP in the URL.


Sandbox URL

(example values)

https://sandbox.patientsknowbest.com/otp.action?otpToken=gnUF6vXCWhZ9QgD4-7s6TE1bSiqfUniw


In addition, a redirect_uri parameter can be specified here that will redirect the user (after a successful login) to another page within the PKB web interface. The redirect_uri parameter must be URL encoded; and only relative URLs will be accepted. An example URL is given below which will login the clinician whose OTP token is provided, and then redirect them to the summary page for the patient whose NHS number is 5555555555.


Sandbox URL

(example values)

https://sandbox.patientsknowbest.com/otp.action?otpToken=gnUF6vXCWhZ9QgD4-7s6TE1bSiqfUniw&redirect_uri=%2Fauth%2FpatientSummary.action%3Ftab%3DpatientSummary%26pnid%3D5555555555%26pnidcc%3DGB-ENG


  1. PKB will validate these credentials, and then log the user into their PKB account.


Note - the OTP is no longer valid at this point.


  1. The user is now logged in to the PKB GUI. Normal rules regarding session expiry will apply - if the configured period of inactivity elapses, the user will be logged out of the PKB GUI. They must then trigger the relevant workflow in the external system to begin a new exchange, during which a new OTP is generated.


Password Based Solution (not supported)

One possible solution would be for PKB to accept the user password as a URL parameter. This would allow the external system to configure this once per user, and then provide this password with the request. This is the approach taken by some other systems to solve the SSO problem. However, PKB does not expose this mechanism because of the following security and usability weaknesses:

  • Requested URLs often end up in unprotected log files generated by the components involved in handling the web request. If this were to occur, the password would be visible to anyone with access to that log file.

  • Requested URLs are visible in the browser address bar and history. Again, the password would then be available to anyone with access to those locations, including someone with visibility of the screen at the time of login.

  • If the password is compromised from the external system, an unauthorised user could use this password to access the relevant account without detection for an unbounded period of time.

  • If the user changes their password, the external system will no longer be able to authenticate as that user.


PKB SSO


Comments