FHIR, Oauth2 and the Mobile client
June 18, 2014 7 Comments
In the previous discussion on OAuth2 in FHIR we discussed the ‘usual flow’ that would be used by a web based client (where the application is executed in a browser with pages and script served up by a web server). But what if the application is either a Desktop or a Mobile application? There are a couple of issues to think about:
- For the application to ‘remember’ that who the user was, it needs to store the Refresh Token, as this will be used by the Authorization Server to issue a new Access Token (actually, so does the web client of course).
- The process flow in OAuth2 is dependant on the use of HTTPS. It describes login screens and browser redirects for example.
Lets think about storing that Refresh Token.
In theory, (at least in OAuth2 speak), these applications are not capable of holding the Refresh Token securely. That is because the token will be stored on an end-user device (the Mobile or Desktop) and so could be stolen by a determined attacker. So, again in theory, the application can’t store the Refresh Token – it must authenticate with the Authorization Server each time the user wants to use it, and the session can only be as long as the lifetime of the Access Token (typically an hour). OAuth2 actually describes a specific workflow for this – the Implicit workflow, where the Authorization Server directly returns an Access Token after the user authenticates, but does not return a Refresh Token. It is specifically intended for ‘public’ scenarios where the user doesn’t want their credentials remembered long term (Like using the ‘Incognito’ browser window if you’re in an Internet Cafe).
That’s all well and good, but not very user friendly when it’s your own mobile device that you’re using – and unlikely to be acceptable to users. In this scenario, you have no alternative other than to store the Refresh Token locally but:
- You must do that as securely as possible (maybe you encrypt in some way).
- You must deal with the possibility that the app could be used by multiple users – for example to associate it with the currently logged in user.
- You must provide an easy mechanism for the user to be able to revoke the access token. The spec doesn’t detail how this is to be done, but one possibility would be for the Authorization Server to have a ‘reset’ or ‘lost my mobile’ function. This could be a ‘normal’ web page where the user logs in (using the standard OAuth2 flow), and the Authorization Server then revokes all Refresh Tokens associated with that user. When the user uses their new device they will simply re-authenticate, and the process will continue as usual.
With that out of the way, we can now think about how the desktop/mobile application can use OAuth2. One way is for the application to launch an embedded browser window to interact with the Authorization Server, as described in the following diagram.
- The User starts the app (presumably logging in in some way). The app launches a browser component which is directed to the ‘request login’ endpoint of the Authorization Server. The Authorization Server generates and returns a login page.
- The user enters their details and submits the page back to the Authorization Server. The Authorization Server authenticates the user, generates an authentication code and sends a redirects back to the embedded browser, instructing it to redirect to the application callback endpoint (which, of course, doesn’t actually exist!)
- The application intercepts the browser redirect (remember it is in an embedded browser component)
- The application extracts the authentication code and terminates the browser component.
- The application makes an HTTPS call to the Authorization Server, passing across the authentication code and gets back an Access Token and a Refresh Token.
- The Refresh Token is saved locally (in the most secure way possible)
- The application makes an HTTPS call to the Resource (FHIR) Server, passing across the Access Token in the ‘Authorization’ header. The Resource server validates the token and returns the data
- The application performs any other required business logic.
One thing we haven’t talked about is dealing with an expired Access Token (and this is the same for the web client we discussed last time). Access Tokens have a limited life span (commonly an hour – but that’s up to the Authorization Server) so what happens if the application is in the middle of doing something when it expires? Well, the flow is something like this:
- The application makes a request (or an update) on the Resource Server.
- The Resource Server recognizes that the token has expired and rejects the request. (The spec doesn’t specify the status code to use – but I presume its 401 – Unauthorized).
- The application retrieves the Refresh Token from its local store and sends that to the Authorization Server, which issues a new Access Token (assuming that the Refresh Token is valid of course).
- The application re-tries the request to the Resource Server with the new Access Token.
So, we’ve talked about how a Mobile or Desktop Application can implement standard OAuth2 functionality to authenticate themselves and grant access to their data. This is by no means the only way, but one that should be straightforward to implement.
And a reminder – don’t to this at home folks – use a library!
In the next post we’ll turn our attention to the users Identity – how does the Resource Server know who the patient is? (Hint: their login details aren’t enough…)
On Android devices, you can do a form of anonymous facial recognition, so you could associate the Face object with the RefreshToken, maybe serialize and hash the two together in encrypted storage, and then only release the Refresh Token to retrieve an Access Token if that Face is still in camera. That seems heavy-handed, when locking a device that is not in use is probably enough, but it’s an interesting option.
Can it recognize a specific face? If so, then maybe it could form the basis of the initial authentication? Now, that would be cool!
David, you always provide very informative information in a clear and easy to understand format
Thanks Howard – much appreciated…
Pingback: FHIR and OpenID Connect | Hay on FHIR
Very enlightening, Thanks Hay, very much appreciated.
Pingback: MOBster4: Insecure Authentication – Security Queens