GSoC'20 : Advancement of OAuth2 Module and Improvements in SMART OWA (SMART on FHIR)

Hello everyone,

This is a public thread for the project “Advancement of OAuth2 Module and Improvements in SMART OWA”. This project aims for enabling SMART Apps on OpenMRS EMR through FHIR.

Actually the title of the project isn’t very appropriate with what we are trying to accomplish as of now. Just after the proposal submission period was over I started working on this project after talking to Ian and as the title suggests I starting working on improving the existing OAuth2 Module some of that work can be found here.

To enable SMART Apps an important requirement is an Authorisation server which was earlier fulfilled by the existing OAuth2 Module. But recently Spring release a Deprecation Notice which stated

The Spring Security OAuth project is deprecated. The latest OAuth 2.0 support is provided by Spring Security. See the OAuth 2.0 Migration Guide for further details.

But the major problem was that in Spring Security oauth2 there was no Authorisation server included so we were stuck on the earlier Spring Security OAuth project. Ian and I still tried to work on the earlier version of Spring oauth2 but as most of the classes were depreciated we had to shift to a different approach for an Authorisation server.

Ian suggested to completely come out of the Spring trap :smile: and try to make things work with Keycloak. Keycloak is basically an Open Source Identity and Access Management software. For our purpose it’ll work as an Authorisation server.

Till now we have been able to successfully connect OpenMRS user-store with Keycloak, this can be found here though it’s still in the PoC phase. The next we are working on is exposing the FHIR resources through DSTU3 profiles, this work can be found here.

My target is to wire up everything together and deploy a SMART App as a PoC before the Community Bonding period ends. This will ensure that we will be able to bring this project to a production level before the GSoC’20 ends.

I hope this will give a clear idea to anyone who is interested in this project.

cc @ibacher @jecihjoy @suthagar23

5 Likes

I have added a Task in JIRA, I’ll be adding more sub-tasks to it as and when required.

cc @ibacher @jecihjoy @suthagar23

I am trying to separate the SMART-on-FHIR configuration stuff from the FHIR stuff. So I have made a sub module in the FHIR2 module itself. The problem I am facing is that the servlet and filter present in SMART sub-module are not detected I get a classdefnotfound error.

Could somebody help me.

I just want to know how to configure servlets and filters in a multi module maven project with many servlets and filter in different sub-modules.

cc @ibacher @jecihjoy @dkayiwa

Do you have a draft pull request to look at?

@dkayiwa Yes I do have one Link to latest commit

Things are a bit messed up as the PR is still far from being merged

Can you share the error log via pastebin.com?

@dkayiwa So the commit that I have pointed above doesn’t gives any errors because FHIR2 module doesn’t detects SmartAuthenticationFilter and FhirSmartConfigServlet (I checked it by applying breakpoints and also sending request through Postman)

But when I add this to omod config.xml

<servlet>
		<servlet-name>fhir2SmartConfig</servlet-name>
		<servlet-class>org.openmrs.module.fhir2.web.servlet.FhirSmartConfigServlet</servlet-class>
	</servlet>

	<filter>
		<filter-name>clientAuthenticationFilter</filter-name>
		<filter-class>org.openmrs.module.fhir2.web.filter.SmartAuthenticationFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>clientAuthenticationFilter</filter-name>
		<url-pattern>/ws/fhir2</url-pattern>
		<url-pattern>/ws/fhir2/*</url-pattern>
		<url-pattern>/ms/fhir2Servlet</url-pattern>
		<url-pattern>/ms/fhir2Servlet/*</url-pattern>
		<url-pattern>/ms/fhir2R3Servlet/*</url-pattern>
	</filter-mapping>

I get this error on debugging

INFO - LoggingAdvice.invoke(156) |2020-06-14 03:25:35,950| Exiting method saveGlobalProperty
WARN - WebModuleUtil.loadServlets(458) |2020-06-14 03:25:38,086| Class not found for servlet fhir2SmartConfig for module FHIR2
java.lang.ClassNotFoundException: org.openmrs.module.fhir2.web.servlet.FhirSmartConfigServlet
        at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)
        at org.codehaus.plexus.classworlds.realm.ClassRealm.unsynchronizedLoadClass(ClassRealm.java:271)
        at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:247)
        at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:239)
        at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:470)
        at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:421)
        at org.openmrs.module.ModuleClassLoader.loadClass(ModuleClassLoader.java:572)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
        at org.openmrs.module.web.WebModuleUtil.loadServlets(WebModuleUtil.java:455)
        at org.openmrs.web.Listener.performWebStartOfModules(Listener.java:681)
        at org.openmrs.web.Listener.performWebStartOfModules(Listener.java:612)
        at org.openmrs.web.Listener.startOpenmrs(Listener.java:251)
        at org.openmrs.web.WebDaemon$1.run(WebDaemon.java:42)
WARN - HibernateSchedulerDAO.getTaskByName(99) |2020-06-14 03:25:38,093| Task 'Post Atlas Data Task' not found
WARN - TimerSchedulerServiceImpl.getTaskByName(401) |2020-06-14 03:25:38,094| getTaskByName(Post Atlas Data Task) failed, because: org.springframework.orm.ObjectRetrievalFailureException: Object of class [org.openmrs.scheduler.TaskDefinition]

full error log

Here is what @ibacher has to say about this

Cut this plugin and paste it to overwrite this plugin.

1 Like

@dkayiwa It works :partying_face:

Now both the SmartAuthenticationFilter and FhirSmartConfigServlet are detected and are working as intended.

Thanks a lot for helping

I have implemented SmartAuthenticationFilter which authenticates a client with OAuth2 Token. For this I implemented the AuthenticationScheme but I think due to these lines the AuthenticationFilter has stopped working

if (!(credentials instanceof SmartTokenCredentials)) {
			throw new ContextAuthenticationException("Invalid credentials");
		}

What should come here so that the AuthenticationFilter works with the new SmartAuthenticationFilter

cc @ibacher @dkayiwa

What exactly does this mean?

So the control goes here but the credentials are not validated, I get Invalid Credentials even on giving correct username and password.

Are your changes in a pull request that we can look at?

Link to latest commit https://github.com/openmrs/openmrs-module-fhir2/commit/c469b0403ab9dba7dc6a09685e4b55d3462173fc

Did you switch to? https://github.com/openmrs/openmrs-module-smartonfhir/pull/2

@dkayiwa Yes we did or I should say we had to switch because is was becoming difficult to making oauth2 and basic auth schemes to work simultaneously.