Superset utilizes an underlying framwork call Flask App Builder. Flask has a module that specifically supports OAuth authentication. Superset utilizes this and has built in configurations to recognize OAuth from Google, Twitter and GitHub. Our goal is to identify the best mechanism moving forward for OAuth support in OpenLMIS. OpenLMIS has built an Authentication mechanism using the Spring Security https://spring.io/projects/spring-security-oauth specifically, it implements client-credentials and implicit grant types.

How it works:

Here's a brief overview of how it works when Superset is connected to GitHub as the OAuth 2 provider.

OpenLMIS currently supports implicit and password (client-credentials) grant types. Currently, OpenLMIS does not support authorization code when you get a token.

Our team has done research on these grant types and built a custom security manager that gets partially the way there. However, we have identified that we would need to build a robust security manager that handles multiple use cases in order to get Superset to function with the existing OpenLMIS auth microservice. When comparing the amount of work and potential security risk, the Ona team has decided to recommend that we add authorization code base grant types when getting an access token.

We request that the OpenLMIS community evaluate the effort of updating the Auth microservice to support authorization_code based grant types when getting a token.

Here's what's working based on our testing:

Core Work for OpenLMIS:

Another thing that we scoped:

We started scoping creating an independent login page that could receive an access token from OpenLMIS because we're planning on embedding it as an iFrame within OpenLMIS. We created a login page that would receive the access_token and the username. When we received this from OpenLMIS, our security page had to create an account for that user in Superset following the same principles of OAuth. At this point, we realized that we were recreating the OAuth process and stopped work on it until this decision was made. We believe that adding grant_type=code will solve this problem as well by passing in the token to the page that already supports OAuth code based authentication without having to develop a new set of security pages for Superset.

Sample OAuth Configuration in Flask

Superset, written in Flask allows for custom OAuth2 configuration. To enable this, import AUTH_OAUTH, change the authorization type to AUTH_OAUTH then define the OAUTH providers and assign the user role and enable user registration role.

The following fields need to be defined based on OpenLMIS Auth microservice:

OAUTH_PROVIDERS = [

   

OAUTH_PROVIDERS = [
    {   'name': 'openlmis',
        'icon': 'fa-google',
        'token_key':'access_token',
        'remote_app': {
            'consumer_key': 'tableau-wdc',
            'consumer_secret': 'changeme',
            'request_token_params': {
                'scope': 'read write'
            },
            'access_token_method': 'POST',
            'access_token_headers': {
                'Authorization':'Basic dXNlci1jbGllbnQ6Y2hhbmdlbWU=='
            },
            'base_url': 'https://uat.openlmis.org/api/oauth',
            'access_token_url': 'https://uat.openlmis.org/api/oauth/token?grant_type=implicit',
            'authorize_url': 'https://uat.openlmis.org/api/oauth/authorize?'}
     }
]