GSoC 2018 - OAuth module enhancements and SMART apps support

Hey @mavrk I am stuck at one thing. I need to know that when the SMART app or say any client requests authorization with a authorization URL which looks like (say):

https://ehr/authorize? response_type=code& client_id=app-client-id& redirect_uri=https%3A%2F%2Fapp%2Fafter-auth& scope=patient%2FObservation.read+patient%2FPatient.read+openid+profile& state=98wrghuwuogerg97& aud=https://ehr/fhir

how do we actually verify this client?? I mean how do we retrieve the parameters say client_id from the authorization url and match with one of the existing clients???

So far I have understood that the authentication uri hits the ws/oauth/authorize endpoint which has the clientControllerEndpointFilter which uses the class clientAuthenticationServiceImpl to verify the client credentials.

But what i need is if some way we could get the authorization url as it is sent by the client and extract the parameters so as to get the “launch” value verified.

I have searched many sites but didn’t find any help.

Can you please suggest a way?

We have different controllers written to handle this. While hitting “/oauth/authorize/” the request is sent to the Access Confirmation Controller which produces an “access confirmation page” giving user the ability to allow or deny the request. Look at https://github.com/mavrk/openmrs-module-oauth2-prototype/blob/oauth2-pure-rest/omod/src/main/java/org/openmrs/module/oauth2/web/controller/AccessConfirmationController.java#L20-L35

You can extract the launch parameter from the request sent to this class.

Also, the identity of an OAuth client is verified using clientAuthenticationService class. You can know more about this here https://github.com/mavrk/openmrs-module-oauth2-prototype/blob/oauth2-pure-rest/api/src/main/java/org/openmrs/module/oauth2/api/impl/ClientAuthenticationServiceImpl.java#L25-L43

Thanks @mavrk :slight_smile:

I have now figured out how would we extract the launch parameter. There is a method called getRequestParameters() See here AuthorizationRequest (OAuth for Spring Security 2.4.0.BUILD-SNAPSHOT API)

The method returns a map from which we can extract the launch value and match it with the one we have in our database. Do you think this will work? :slight_smile:

Yep I already figured this out above.

Thanks a bunch for the help. :slight_smile:

Yes, I know :smile: And yes it will work, as you can see from the link of the class I sent you, we are sending an Authorization request object “client_auth” and you can use getRequestParameters() to extract the “launch” parameter if it exists.

1 Like

Exactly!!! Yay :slight_smile: thanks.

Hey @mavrk I read about how can we deal with SMART scopes. I think I have figured out some points.

First talking about the patient specific scopes like patient/*.read or patient/Observation.write etc. Basically, when apps ask for patient specific scopes, they ask us permissions about the current patient in context. Reference here: https://groups.google.com/forum/#!topic/smart-on-fhir/WUFHIBOvZBE

Now all we have to do is to give the information about which patient is currently in context. And we do this by sending the launch context parameters along with the access_token. So when apps would ask for patient specific scopes, what we need to do is to get the id of patient currently in context and send it as a parameter with the access_token.

Say if we pass a parameter patient : “123” Then, this means that the app was launched in the context of FHIR Patient 123 and if the app has any patient-level scopes, they will be scoped to Patient 123.

This is how we can implement patient level scopes. :slight_smile:

Now coming to User specific scopes like user/*.read, user/Patient.read etc. These type of scopes limits the scopes to what level of authority the authorizing user has.

So, here first we need to retrieve what authorities does the user has. Then, suppose the requested scope is user/*.read then we need to only grant permissions to read resources which are accessible by the current user.

Here I have a doubt that how can we retrieve what resources a particular user, for example say a doctor, has access? In OpenMRS, do we have some functionality which would tell us about what resources or what permissions does a particular user has??

1 Like

We can do that using the Context class. Maybe with a method like Context.getAuthenticatedUser() However, I am not sure, I think it’d be better if you could create a new topic on talk and get a bigger audience or ask on the IRC.