Skip to content

Conversation

@bwang-icf
Copy link
Contributor

@bwang-icf bwang-icf commented Nov 27, 2024

JIRA Ticket:
BB2-3360

What Does This PR Do?

Adds SMART on FHIR endpoint listing out configuration details

What Should Reviewers Watch For?

Expected endpoint returns correct info as per https://confluence.cms.gov/pages/viewpage.action?spaceKey=BFD&title=BFD-3378%3A+FHIR+IG+conformance

If you're reviewing this PR, please check for these things in particular:

Any ways the code style itself could be improved upon. It was mostly copy pasted from the openid config endpoint and it would be good to know if it is conforming to the quality of code we'd like.

Validation

This was verified by spinning up the docker containers locally, getting a token, and performing a GET request in postman to localhost:8000/.well-known/smart-on-fhir-configuration.

A response from a local test is here:

{
"issuer": "http://localhost:8000",
"authorization_endpoint": "http://localhost:8000/v1/o/authorize/",
"revocation_endpoint": "http://localhost:8000/v1/o/revoke/",
"token_endpoint": "http://localhost:8000/v1/o/token/",
"userinfo_endpoint": "http://localhost:8000/v1/connect/userinfo",
"ui_locales_supported": [
"en-US"
],
"service_documentation": "https://bluebutton.cms.gov/developers",
"op_tos_uri": "https://bluebutton.cms.gov/terms",
"grant_types_supported": [
"authorization-code",
"refresh_token"
],
"response_types_supported": [
"code",
"token"
],
"fhir_metadata_uri": "http://localhost:8000/v1/fhir/metadata",
"scopes_supported": [
"profile",
"patient/Patient.read",
"patient/ExplanationOfBenefit.read",
"patient/Coverage.read"
],
"code_challenge_methods_supported": [
"S256"
],
"capabilities": [
"client-confidential-symmetric",
"sso-openid-connect",
"launch-standalone",
"permission-offline",
"permission-patient",
"permission-v1"
]
}

What Security Implications Does This PR Have?

Please indicate if this PR does any of the following:

  • Adds any new software dependencies
  • Modifies any security controls
  • Adds new transmission or storage of data
  • Any other changes that could possibly affect security?
  • Yes, one or more of the above security implications apply. This PR must not be merged without the ISSO or team
    security engineer's approval.

Any Migrations?

  • Yes, there are migrations
    • The migrations should be run PRIOR to the code being deployed
    • The migrations should be run AFTER the code is deployed
    • There is a more complicated migration plan (downtime,
      etc)
  • No migrations

Copy link
Contributor

@alex-dzeda alex-dzeda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a significant variance between what's returned from this endpoint compared to what's in the links specified in the SMART on FHIR spec + example. For example: the path should be smart-configuration (https://hl7.org/fhir/smart-app-launch/STU2.2/conformance.html#using-well-known), and there are a significant number of fields present that are not in the smart-configuration conformance spec.

@bwang-icf
Copy link
Contributor Author

@alex-dzeda I removed all the fields that weren't listed in the sample response and changed the url path to be smart-configuration.

{
"issuer": "http://localhost:8000",
"authorization_endpoint": "http://localhost:8000/v1/o/authorize/",
"revocation_endpoint": "http://localhost:8000/v1/o/revoke/",
"token_endpoint": "http://localhost:8000/v1/o/token/",
"grant_types_supported": [
"authorization-code",
"refresh_token"
],
"response_types_supported": [
"code",
"token"
],
"scopes_supported": [
"profile",
"patient/Patient.read",
"patient/ExplanationOfBenefit.read",
"patient/Coverage.read"
],
"code_challenge_methods_supported": [
"S256"
],
"capabilities": [
"client-confidential-symmetric",
"sso-openid-connect",
"launch-standalone",
"permission-offline",
"permission-patient",
"permission-v1"
]
}


urlpatterns = [
path("openid-configuration", openid_configuration, name="openid-configuration"),
path("smart-configuration", smart_configuration, name="smart-configuration"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the .well-known/smart-configuration should be relative to the base path of the server, eg v2/fhir/.well-known/smart-configuration for v2, v1/fhir/.well-known/smart-configuration for v1, per environment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see what you mean. I'll have to do a bit more digging around to get it to have that pattern. Would we want to change openid-configuration to follow that pattern as well? It seems like it's the only one to have this current pattern. Swagger link for convenience: https://sandbox.bluebutton.cms.gov/docs/openapi#/v2/openIdConfig

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A good team discussion topic. imo the value of a well-known url is that you can automatically discover it. As it stands today, I'd see the same problem for the OIDC config, since openid-configuration-v2 isn't really well-known.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I'll socialize this with the other engineers and see about making this happen

logger = logging.getLogger(bb2logging.HHS_SERVER_LOGNAME_FMT.format(__name__))
SCOPES_SUPPORTED = ["profile", "patient/Patient.read", "patient/ExplanationOfBenefit.read", "patient/Coverage.read"]
CODE_CHALLENGE_METHODS_SUPPORTED = ["S256"]
CAPABILITIES = [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add "authorize-post"? looks like that one would also fit within the existing, supported capabilities of BB2

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add that now.

@jimmyfagan jimmyfagan marked this pull request as draft December 2, 2024 18:02
@jimmyfagan jimmyfagan self-assigned this Dec 2, 2024
@bwang-icf bwang-icf marked this pull request as ready for review December 2, 2024 21:25
Copy link
Contributor

@jimmyfagan jimmyfagan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good, just a few more comments from me. Latest output from the endpoint is here:

{
    "issuer": "http://localhost:8000",
    "authorization_endpoint": "http://localhost:8000/v2/o/authorize/",
    "revocation_endpoint": "http://localhost:8000/v1/o/revoke/",
    "token_endpoint": "http://localhost:8000/v2/o/token/",
    "grant_types_supported": [
        "authorization-code",
        "refresh_token"
    ],
    "response_types_supported": [
        "code",
        "token"
    ],
    "scopes_supported": [
        "profile",
        "patient/Patient.read",
        "patient/ExplanationOfBenefit.read",
        "patient/Coverage.read"
    ],
    "code_challenge_methods_supported": [
        "S256"
    ],
    "capabilities": [
        "client-confidential-symmetric",
        "sso-openid-connect",
        "launch-standalone",
        "permission-offline",
        "permission-patient",
        "permission-v1",
        "authorize-post"
    ]
}

issuer = base_issuer(request)
v2 = request.path.endswith('openid-configuration-v2') or request.path.endswith('openidConfigV2')
data = build_endpoint_info(data, issuer=issuer, v2=v2)
data = build_endpoint_info(data, issuer=issuer)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With OIDC v2 feeding through the normal endpoint now, can you also update the swagger page to remove the -v2 from /.well-known/openid-configuration-v2? It's in openapi.yaml.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there already a follow up ticket to add the smart config to the swagger doc? If so, we can save this adjustment for that if that's preferred, if not, we should either make a ticket, or include the smart config updates to swagger docs as part of this PR.

del(data["ui_locales_supported"])
del(data["service_documentation"])
del(data["op_tos_uri"])
del(data["fhir_metadata_uri"])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we'll want to add this in:

Suggested change
del(data["fhir_metadata_uri"])
del(data["fhir_metadata_uri"])
data["grant_types_supported"].remove("refresh_token")

Spec says for grant_types_supported:

The options are “authorization_code” (when SMART App Launch is supported) and “client_credentials” (when SMART Backend Services is supported).

data["authorization_endpoint"] = issuer + \
reverse('oauth2_provider:authorize' if not v2 else 'oauth2_provider_v2:authorize-v2')
reverse('oauth2_provider_v2:authorize-v2')
data["revocation_endpoint"] = issuer + reverse('oauth2_provider:revoke')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we go ahead and make this change now, I think we're done with that bug we refined yesterday:

Suggested change
data["revocation_endpoint"] = issuer + reverse('oauth2_provider:revoke')
data["revocation_endpoint"] = issuer + reverse('oauth2_provider_v2:revoke-token-v2')

Might require a test update too.

@bwang-icf bwang-icf requested a review from alex-dzeda December 3, 2024 18:22
Copy link
Contributor

@JFU-NAVA-PBC JFU-NAVA-PBC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noticed some inconsistencies on v1 vs v2 endpoints responses:
auth, token end points URLs are all BB2 v2...

also scopes include "permission_v1", if that v1 is referring to BB2 API ver, then it needs to be consistent with the version of the smart config URL...

V1: GET http://localhost:8000/v1/fhir/.wellknown/smart-configuration response:
{ "issuer": "http://localhost:8000", "authorization_endpoint": "http://localhost:8000/v2/o/authorize/", "revocation_endpoint": "http://localhost:8000/v2/o/revoke_token/", "token_endpoint": "http://localhost:8000/v2/o/token/", "grant_types_supported": [ "authorization-code" ], "response_types_supported": [ "code", "token" ], "scopes_supported": [ "profile", "patient/Patient.read", "patient/ExplanationOfBenefit.read", "patient/Coverage.read" ], "code_challenge_methods_supported": [ "S256" ], "capabilities": [ "client-confidential-symmetric", "sso-openid-connect", "launch-standalone", "permission-offline", "permission-patient", "permission-v1", "authorize-post" ] }
V2: GET http://localhost:8000/v2/fhir/.wellknown/smart-configuration response:

{ "issuer": "http://localhost:8000", "authorization_endpoint": "http://localhost:8000/v2/o/authorize/", "revocation_endpoint": "http://localhost:8000/v2/o/revoke_token/", "token_endpoint": "http://localhost:8000/v2/o/token/", "grant_types_supported": [ "authorization-code" ], "response_types_supported": [ "code", "token" ], "scopes_supported": [ "profile", "patient/Patient.read", "patient/ExplanationOfBenefit.read", "patient/Coverage.read" ], "code_challenge_methods_supported": [ "S256" ], "capabilities": [ "client-confidential-symmetric", "sso-openid-connect", "launch-standalone", "permission-offline", "permission-patient", "permission-v1", "authorize-post" ] }

Copy link
Contributor

@JFU-NAVA-PBC JFU-NAVA-PBC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@bwang-icf bwang-icf merged commit d575789 into master Dec 3, 2024
6 checks passed
@bwang-icf bwang-icf deleted the brandon/BB2-3360-smart-on-fhir branch December 3, 2024 21:33
@jimmyfagan
Copy link
Contributor

also scopes include "permission_v1", if that v1 is referring to BB2 API ver, then it needs to be consistent with the version of the smart config URL...

Just chiming in to make sure we're on the same page, that v1 doesn't refer to our API it refers to the SMART scope syntax, the options are:

So we have it right, no issues there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants