Pluggabale authentication modules for OpenMRS

As part of the work we are doing in Bahmni for offline data entry by health workers, we are looking in to the following aspects-

  • Two-factor authentication to ensure increased security of data sync with Bahmni/OpenMRS server when the app is online
  • Feasibility of plugging-in custom authentication on top of OpenMRS

Could anyone who has worked on this area give suggestions?

Here’s a blog post which might help you.

1 Like

@vvinay, this topic comes up about once a year, but AFAIK nobody has ever done the required work to do it.

In this ticket from 2010 Burke describes the relevant API changes to support this:

I haven’t heard of anyone doing 2FA with OpenMRS, but I hope someone pops up out of the woodwork!

2 Likes

Thanks @r0bby and @darius. Will look into this and try to see if we can come up with an approach which can be generic enough to be used by the OpenMRS community and also develop component for 2FA in Bahmni.

Just to point it out explicitly, the TRUNK-381 ticket is ready for work, and you’re welcome/encouraged to do this. (Of course if in the process you need to modify some of the design details, just let us know.)

I believe, the current mechanism of login is done from the LoginServlet. I have gone through the #381. The current OpenMRS is using spring 4.1.x. Do we want to rethink about moving to Spring Authentication?

@angshuonline, is Spring Authentication the same as Spring Security? What would be the benefit of this? To be able to use existing Spring Security plugins?

If it’s backwards compatible and makes the code cleaner and not uglier, we’d definitely consider it.

Note that we currently use @Authorized annotations in code, a taglib in jsp in the legacy UI, and via the UI Framework pages there’s context.requirePrivilege and sessionContext.requireAuthentication

@darius: Yes, I am talking about spring security. Spring has nice framework built around all sorts of authentication provider, standard ones and also providing extensions for custom ones. Also has very good support for JAAS. Spring security (formerly known as acegi, run by Ben Alex) has been there since spring 2.0, but I am not sure how far back the compatibility goes. To what version of OpenMRS and Spring are you looking for backward compatibility? Regarding the custom openmrs @authorized, Spring has very nice annotations of its own (PreAuthorize for example), with very powerful EL support. Otherwise, we can always use custom annotation handler to handle OpenMRS @Authorize annotation.

@darius Can we discuss this topic in one of the design calls (either this week or next) ?

1 Like

I’d be interested in talking about this on a design call. Maybe @jthomas can find us a time?

@vvinay @pascal today’s design forum is full and I believe Wednesday’s may be too late for you all. How about Monday, May 23 @4pm UTC?

That would work for me.

@vvinay, @angshuonline, you should provide some justification for shifting to Spring Security, versus just doing this in our own existing framework, if that’s the way you want to proceed.

(If we were starting from scratch, this wouldn’t be an issue, but given the existing code and install base, we wouldn’t make this change unless it brings some tangible benefit.)

@jthomas, Monday, May 23rd @4 PM UTC is ok.

@angshuonline did you ever spike this out? We would like to enable SSO between OpenMRS and a couple of other components. We’re looking at JBoss’ Keycloak.

Keycloak offers many Java adapters, one of which being the Spring Security adapter (here). @darius I guess this doesn’t make a case strong enough to implement authentication/authorization with Spring Security in Core? I haven’t looked in enough details, some other Java adapter might just do the trick though, I would be curious to know your thoughts about this.

P.S. For ref. here are the notes of the design called that ensued this topic back in 6/25/2016.

Cc @amine

Not in OpenMRS/Bahmni. But in other projects. I think it should be relatively simple (not code wise) to plug Spring Security onto OpenMRS core, which can retain the existing “privilege” checks. This can be done, by building a custom UserDetailsService and using means like

  • " @PreAuthorize ( "hasAuthority('SYS_ADMIN')" )"
  • or using OpenMRS specific @Authorized custom annotation processor

The advantage is of course, that it allows you to plugin other Identity Providers. I think card 381 provides a way to do it least invasive way, however I would have preferred the abstraction raised to AuthenticationProvider and AccessDecisionManager level. But reworking that might be some work!

If none of the above works, then you probably have to

  • rerouting the login to some other URL, that does the login with external system and does the population of the User, roles and within the privileges. (Btw, you can achieve all that using Spring Security and GrantedAuthority). So now, the user object has all required info. Of course, this will require a fair bit of code change and introducing abstractions in “Context”.
  • you also probably need to figure out how to bypass the “loginServlet” and the filter that does the checks - but that can be avoided using a custom web.xml.