SMART on FHIR Launcher OpenID Connect ID Token Validation

528 views
Skip to first unread message

David Vaccaro

unread,
Jul 23, 2020, 3:03:55 PM7/23/20
to SMART on FHIR
All,

Looks like the endpoint identified by the "iss" value within the OpenID Connect "id token" issued by the launcher does NOT fully support enough Open ID Connect metadata in order to validate the "id token".

Here is the "iss" served by an instance of a launch within the launcher WITH the additional standard metadata path appended:


Notice that it serves the absolute minimum metadata which is NOT enough to properly enforce the OIDC validation rule (specified within the SMART spec).

For example, Google hosts the following for a similar OIDC endpoint:


Anyone encounter this?  I'm just trying to develop/test (using the launcher) the complete validation of the id-token to prove my app strictly adheres to the standard.

Thanks,
Dave

Vladimir Ignatov

unread,
Jul 24, 2020, 12:16:17 PM7/24/20
to David Vaccaro, SMART on FHIR
It should be noted that the launcher is not a real auth server, but a tool design to make testing a SMART app easier for developers. It often just simulates the real-world setup. For example, no client registration is needed and any client_is accepted as if it has been registered already.

With that said, supporting only the minimal metadata made sense when that was being implemented. We could add more, although I am not sure if that would be enough for token validation. Which "well-known" properties are you missing?

Thanks,
Vlad



--
You received this message because you are subscribed to the Google Groups "SMART on FHIR" group.
To unsubscribe from this group and stop receiving emails from it, send an email to smart-on-fhi...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/smart-on-fhir/76a9e6bc-37e4-4bcf-b47b-2bccb46d39e8o%40googlegroups.com.

David Vaccaro

unread,
Jul 24, 2020, 1:17:47 PM7/24/20
to SMART on FHIR
Vlad,

I'm not exactly sure as of yet what in particular is missing that prevents standard OIDC token validation but my intention was to leverage Spring OATH2 client library to perform the validation as follows:

                // NOTE the "header" is the id-token header values, the "payload" is the id-token payload values

// Establish the client-registration
ClientRegistration registration = ClientRegistrations
.fromOidcIssuerLocation(payload.get("iss"))
.clientId("my client id")
.clientSecret("my client secret").build();

// Create the OIDC token validator
OidcIdTokenValidator validator = new OidcIdTokenValidator(registration);

// Validate the id-token
OAuth2TokenValidatorResult result = validator.validate(new Jwt(id_token,
    Instant.ofEpochSecond((Integer)payload.get("iat")),
    Instant.ofEpochSecond((Integer)payload.get("exp")),
    header,
    payload));

NOTE: That this validation works when launched within the Epic SMART on FHIR Launch Simulator.

I realize that the SMART Health IT Launcher is primarily intended to support the basic flow through to the SMART launch process for basic testing purposes but, I find this launcher to be VERY useful when developing my SMART apps.  

None of the other simulators or launchers that I have used is as feature rich (supporting different versions of FHIR, all launch flows, CDS Hooks, standard error cases, etc.) so I would highly encourage maintainers to make the launcher issue real tokens and fully support OIDC token validation (as well as any other aspect of the SMART/OAUTH2 standard relevant to SMART).  

In fact, if this is an open-source initiative, I would be happy to implement this myself if that is possible.

In the meantime, I'll see if I can determine what might be missing from the config that is failing the above code.

Dave 
To unsubscribe from this group and stop receiving emails from it, send an email to smart-...@googlegroups.com.

Vladimir Ignatov

unread,
Jul 24, 2020, 7:53:46 PM7/24/20
to David Vaccaro, SMART on FHIR
Hi Dave,

It seems to me that this functionality would depend on what the OidcIdTokenValidator expects to find in the metadata. 
The project is open source and I am supposed to maintain it. However, I am currently struggling with few deadlines and may not be able to address this for a while. It would be very helpful If you can make a PR or just open an issue to document what you find out. Here are some hints to help you get started:

1. The ".well-known/openid-configuration" is currently very simple and is defined inline at https://github.com/smart-on-fhir/smart-launcher/blob/master/src/index.js#L86-L89.
2. if it has to be augmented, it will be better implement it in a separate file similar to the ".well-known/smart-configuration" -  https://github.com/smart-on-fhir/smart-launcher/blob/master/src/index.js#L86-L89 and https://github.com/smart-on-fhir/smart-launcher/blob/master/src/wellKnownSmartConfiguration.js
3. The best way to work on it locally is to use Node 14.2.0 and VScode. Then "git clone https://github.com/smart-on-fhir/smart-launcher.git", "cd smart-launcher", "npm i". Then in VScode add it as a project folder and in the debug panel run the "Launch" task.

Thanks,
Vlad

To unsubscribe from this group and stop receiving emails from it, send an email to smart-on-fhi...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/smart-on-fhir/f3973a70-ba1e-4948-88b2-aa5e2527612bo%40googlegroups.com.

David Vaccaro

unread,
Jul 25, 2020, 10:26:33 AM7/25/20
to SMART on FHIR
Vlad, excellent. Thanks for the links..
Ill hop on this today and submit a PR. Dave

David Vaccaro

unread,
Jul 27, 2020, 2:02:04 PM7/27/20
to SMART on FHIR
Vlad,

Im all up and running with the project and I have a workable solution but I'd like to get your input on a few points.

1. The only OIDC configuration items that appear to be required in order to enable the standard OIDC id-token validation to pass are as follows:

    - issuerMUST exactly match the value of the iss (issuer) Claim.  
    - jwks_uri: The uri to the encryption key information. (launcher already properly supporting this element)
    - authorization_endpoint: The uri to the OAUTH2 "authorize" endpoint.
    - token_endpoint: The uri to the OAUTH2 "token" endpoint.
    - subject_types_supported: The type of subject identifier used.  The value "public" should be used to indicate that this provides the same sub (subject) value to all Clients.
 
The elements that need to be added are, "issuer", "authorization_endpoint", "token_endpoint" and "subject_types_supported"... I'll read the code the better understand how I can properly formulate the first three, the last one is jut hard-coded.  I'll submit a PR with these additions using the method you outlined above.

2. Epic App Orchard Launcher adds the following STATIC items to their OIDC discovery metadata but I've determined that these may be generally optional:

    - id_token_signing_alg_values_supported: The current type of signing algorithm used for the token (same as in header) defaults to "RS256"
     - response_types_supported: The type of the response... I believe this is supposed to be "id_token" but Epic shows "code" (this might be wrong on their part).
     - scopes_supported: The scopes supported during token negotiations.  Epic has: "fhirUser", "launch" and "openid". 
     - grant_types_supported: The grant types supported during token negotiations.  Epic has: "authorization_code", "refresh_token", "client_credentials" and "urn:ietf:params:oauth:grant-type:jwt-bearer".
     - token_endpoint_auth_methods_supported: the token endpoint methods supported during the token negotiations.  Epic has: "client_secret_post", "client_secret_basic" and "private_key_jwt".
     - response_modes_supported: The response modes supported.  Epic has: "query"

I'll document these within the PR just in case that these should need to be added in a later PR.

3. The value of the "aud" within the id_token is defined to be as follows:

Audience(s) that this ID Token is intended for. It MUST contain the OAuth 2.0 client_id of the Relying Party as an audience value. It MAY also contain identifiers for other audiences. In the general case, the aud value is an array of case sensitive strings. In the common special case when there is one audience, the aud value MAY be a single case sensitive string.

Currently, the id_token coming back from the SMART launcher always has the value "whatever" as the value of the "aud".  I think to properly support this field, we would need to introduce a "client-id" entry field in the tool that allows the user to specify a "client-id" to use during the launch process.  This value could be pre-populated with a random GUID value and, more or less, collapsed in some section so that it doesn't overwhelm the UI.  The user that needs to set this value could hunt it out, expand it and set it if needed..... any thoughts?

Dave

Vladimir Ignatov

unread,
Jul 27, 2020, 4:04:29 PM7/27/20
to David Vaccaro, SMART on FHIR
Hi Dave,

Nice to see that you've found the missing pieces! The authorization_endpoint and token_endpoint should have "well-known" values. You can borrow those from wellKnownSmartConfiguration.js. The client_id should be dynamic and come from the app that is being launched. If you use the built-in sample app, it will have the hardcoded value of "whatever", which is just an attempt to be explicit about the fact that this launcher does not care about this value. Other apps may have other client IDs though.

Finally, how about moving this discussion to GitHub so that we don't bother this global forum with specific coding issues.

Thanks,
Vlad

To unsubscribe from this group and stop receiving emails from it, send an email to smart-on-fhi...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/smart-on-fhir/e9f475d9-9792-4cbf-94a1-a52f74a00528o%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages