OHDSI Home | Forums | Wiki | Github

Tips for configuring CAS 2.0 SSO

It can be quite difficult to figure out the correct configuration for the mere 5 CAS parameters because the documentation lacks a meaningful template. But with the right starting point this may be one of the easiest for enterprise authentication (AD or LDAP has presented multiple challenges for us for both authentication and authorization). Here is a redacted working version of the parameters in the Broadsea webtools docker-compose environment .env file (substitute . for _ if not using Docker, but note for some unknown reason in our experience any pom.xml parameter using dot notation instead of underscores in the Docker environment is ignored).

security_oauth_callback_ui=https://[your_atlas_server]/atlas/#/welcome
security_cas_loginUrl=https://[cas_server]/idp/profile/cas/login
security_cas_callbackUrl=https://[your_atlas_server]/WebAPI/user/cas/callback?client_name=CasClient
security_cas_serverUrl=https://[cas_server]/idp/profile/cas
security_cas_casticket=ticket

  1. If oauth_callback_ui is not updated from the default, you will see the browser land on an invalid localhost page after successfully validating the CAS ticket. The default might work if testing locally, but fails for a remote server connection. It is necessary to change this despite not using oauth. It is merely an intermediate URL, as it will redirect to the home page after authenticating.

  2. Your identity and access management team can provide you with the URL to access the CAS server (in our case, the settings were posted on an internal web page). The base URL is item 4, and “login” is most likely going to be appended to the path for the loginUrl for item 2. During login, a casurl attribute is appended to this URL, the value of which is the callbackUrl + client_name=CasClient. This is not obvious from source, but is clear when debugging.

  3. callbackUrl should be structured exactly like this. It would be useful if pom.xml had this as the default. The client_name=CasClient key/value pair is required. During ticket validation, Atlas will send 2 attributes, ticket and service, where the value of ticket is the ticket received from the CAS server, and service is the callbackUrl. If client_name=CasClient is omitted, then the ticket validation step will fail with a service mismatch error presented in the browser, because CasClient is passed during the initial login step, and the CAS server needs to match the casurl sent during the login step (which hard codes the client_name=CasClient to the query string. Fortunately during the construction of the query string at the login step, it does not append the hard-coded client_name pair again if it already exists in the callbackUrl, otherwise CAS likely would be unusable because the server would not validate–unless it ignored duplicate pairs).

  4. See 2

  5. The casticket default value is casticket. Instead, the value really should be “ticket”, because that is the standard attribute name returned from probably any CAS server. Using “casticket” resulted in the following error:

javax.servlet.ServletException: java.lang.IllegalStateException: createToken method implementation returned null. A valid non-null AuthenticationToken must be created in order to execute a login attempt.

The other CAS parameter, security_cas_cassvcs, was left with default of null, as debugging revealed it served no purpose.

The IAM person we worked with suggested trying https://[cas_server]/idp/profile/cas/serviceValidate for the callbackUrl. Obviously, this turned out to be a reference to the atlas server callback. But I wanted to mention that the serviceValidate attribute, which is an essential part of the protocol, is not required to be set because the application will append this to the serverUrl setting when performing ticket validation. To convince yourself, you can add serviceValidate to the serverUrl and see two instances of serviceValidate appear in the URL in the error logs.

Another thing to consider is the user name returned from the server, which may or may not correspond to the name entered when signing onto the CAS server. The default received from the server appears in the upper right corner of Atlas, and in our case it was not a particularly user-recognizable name. We requested that the mail field from AD be returned instead. This name appears in the PG sec_user table, and if you switch fields at some point, multiple instances of that user will appear in PG, with anything but the most recent not being usable in the absence of a migration.

One thing you may find helpful in debugging is setting the following in docker-compose .env file:

logging_level_org_apache_shiro=trace
logging_level_root=trace
logging_level_org_ohdsi=trace

Also, information on this site can be helpful for understanding the basics of the protocol:CAS - CAS Protocol

This is great information and would become a great wiki article for setting up CAS and WebAPI. We’re also working on improving the documentation for WebAPI, and although we’re starting off on documenting endpoints, it’s certainly a welcome addition to improve installation/configuration documentation too.

It will be good to hear that someone may benefit from the effort to get this working.

A couple of very important points I forgot to mention is that in the config-local.js file, the ajax parameter must be changed to false. This is a pre-requisite before you have any opportunity to evaluate the protocol in action, as you’ll immediately get a “Login failed” message in the login dialog box. And the CAS endpoint is user/login/cas. You don’t need to enter credentials on the Atlas server, so it makes sense to set that parameter to false. It should look like this:

    configLocal.authProviders = [{
         "name": "Single Sign On",
         "url": "user/login/cas",
         "ajax": false,
         "icon": "fa fa-cubes",
         "isUseCredentialsForm": false
    }
  ];
t