FHIR Chat · PKCE · smart

Stream: smart

Topic: PKCE


view this post on Zulip Keller Martin (Feb 23 2021 at 20:11):

Trying to add PKCE support to my smart client, and have been using smart.argo.run, which is the only server I have access to that supports it. Currently returning a 500 from the /token endpoint, which was working last time I tested it (about 3 weeks ago, admittedly).
I'm not sure who owns this server, but can someone verify that everything is okay with that endpoint?

view this post on Zulip Josh Mandel (Feb 23 2021 at 20:22):

The server hasn't been touched since the connect-a-thon, I believe. Right now , choosing patient standalone launch from the web UI and then launching the granular controls test app from the link at the bottom of the screen seems to show that pkce is working. Hmm.

view this post on Zulip Keller Martin (Feb 23 2021 at 20:33):

Thanks for the reply - it must be something I'm doing. I'm using the Provider EHR launch. Can't seem to get a helpful response though: Response{protocol=h2, code=500, message=, url=https://smart.argo.run/v/r4/auth/token}

view this post on Zulip Josh Mandel (Feb 23 2021 at 23:05):

Do you have a way to test with patient standalone launch? That may be the only path that works at this stage since I don't think we formally tested the others (but.. you're saying provider EHR launch was working for you before, so that's not super compelling.)

view this post on Zulip Josh Mandel (Feb 23 2021 at 23:05):

Does your error response have an empty body? Is that what message= indicates?

view this post on Zulip Josh Mandel (Feb 23 2021 at 23:05):

Can you send along a full request to we can check for any issues?

view this post on Zulip Keller Martin (Feb 24 2021 at 15:29):

No problem - yeah EHR launch worked for me during the Connectathon. I did a ton of refactoring since then but I don't think I changed anything with the request.

Request{
  method=POST,
  url=https://smart.argo.run/v/r4/auth/token,
  headers=[
    Content-Type:application/x-www-form-urlencoded,
    Accept:application/json,
    Authorization:Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuZWVkX3BhdGllbnRfYmFubmVyIjpmYWxzZSwic21hcnRfc3R5bGVfdXJsIjoiaHR0cHM6Ly9zbWFydC5hcmdvLnJ1bi8vc21hcnQtc3R5bGUuanNvbiIsInBhdGllbnQiOiIyY2RhNWFhZC1lNDA5LTQwNzAtOWExNS1lMWMzNWM0NmVkNWEiLCJlbmNvdW50ZXIiOiIxZTM4Yjc3MS1lYTg3LTQzNDMtYTVhOC02MDAyMjM3NGNiYWEiLCJyZWZyZXNoX3Rva2VuIjoiZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKSVV6STFOaUo5LmV5SmpiMjUwWlhoMElqcDdJbTVsWldSZmNHRjBhV1Z1ZEY5aVlXNXVaWElpT21aaGJITmxMQ0p6YldGeWRGOXpkSGxzWlY5MWNtd2lPaUpvZEhSd2N6b3ZMM050WVhKMExtRnlaMjh1Y25WdUx5OXpiV0Z5ZEMxemRIbHNaUzVxYzI5dUlpd2ljR0YwYVdWdWRDSTZJakpqWkdFMVlXRmtMV1UwTURrdE5EQTNNQzA1WVRFMUxXVXhZek0xWXpRMlpXUTFZU0lzSW1WdVkyOTFiblJsY2lJNklqRmxNemhpTnpjeExXVmhPRGN0TkRNME15MWhOV0U0TFRZd01ESXlNemMwWTJKaFlTSjlMQ0pqYkdsbGJuUmZhV1FpT2lKbU16VTVZVEpoTnkwMk1XTTJMVFEyWWpZdE9XSmlOQzAyWlRNMlpHWTBOemM0TTJVaUxDSnpZMjl3WlNJNklteGhkVzVqYUNCdmJteHBibVZmWVdOalpYTnpJRzl3Wlc1cFpDQndjbTltYVd4bElHWm9hWEpWYzJWeUlHeGhkVzVqYUM5d1lYUnBaVzUwSUhCaGRHbGxiblF2VUhKaFkzUnBkR2x2Ym1WeUxuSnpJSEJoZEdsbGJuUXZUMkp6WlhKMllYUnBiMjR1Y25NZ2NHRjBhV1Z1ZEM5RmJtTnZkVzUwWlhJdWNuTWdjR0YwYVdWdWRDOVBjbWRoYm1sNllYUnBiMjR1Y25NaUxDSjFjMlZ5SWpvaVVISmhZM1JwZEdsdmJtVnlMelV5T1RFNU1EazVMVFpoTjJFdE5EUXlZeTFpTUdRMUxUSmlNREpqTUdSa05HSTNOQ0lzSW1saGRDSTZNVFl4TkRFNE1ESTNOeXdpWlhod0lqb3hOalExTnpFMk1qYzNmUS5yME1rdVgwSmN5QVp1X3M0WDJRVUF4bmc3ajM2eHo0S1pzQTdKYzUxZU5JIiwidG9rZW5fdHlwZSI6ImJlYXJlciIsInNjb3BlIjoibGF1bmNoIG9ubGluZV9hY2Nlc3Mgb3BlbmlkIHByb2ZpbGUgZmhpclVzZXIgbGF1bmNoL3BhdGllbnQgcGF0aWVudC9QcmFjdGl0aW9uZXIucnMgcGF0aWVudC9PYnNlcnZhdGlvbi5ycyBwYXRpZW50L0VuY291bnRlci5ycyBwYXRpZW50L09yZ2FuaXphdGlvbi5ycyIsImNsaWVudF9pZCI6ImYzNTlhMmE3LTYxYzYtNDZiNi05YmI0LTZlMzZkZjQ3NzgzZSIsImV4cGlyZXNfaW4iOjM2MDAsImlkX3Rva2VuIjoiZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKU1V6STFOaUo5LmV5SndjbTltYVd4bElqb2lVSEpoWTNScGRHbHZibVZ5THpVeU9URTVNRGs1TFRaaE4yRXRORFF5WXkxaU1HUTFMVEppTURKak1HUmtOR0kzTkNJc0ltWm9hWEpWYzJWeUlqb2lVSEpoWTNScGRHbHZibVZ5THpVeU9URTVNRGs1TFRaaE4yRXRORFF5WXkxaU1HUTFMVEppTURKak1HUmtOR0kzTkNJc0ltRjFaQ0k2SW1Zek5UbGhNbUUzTFRZeFl6WXRORFppTmkwNVltSTBMVFpsTXpaa1pqUTNOemd6WlNJc0luTjFZaUk2SWpaaE1qQTFOR1prT1RWa1lqRTFOVFV5WXpkbE5XWmxZalU0WlRKbU5ERXhNRFkwT1RZd1pEUXlNR1F5TWpVNU56SmtaakZoWVRZeU4yTTVZalZqTXpZaUxDSnBjM01pT2lKb2RIUndjem92TDNOdFlYSjBMbUZ5WjI4dWNuVnVMeUlzSW1saGRDSTZNVFl4TkRFNE1ESTNOeXdpWlhod0lqb3hOakUwTVRnek9EYzNmUS5LTXdvaDNSb3FVcFpfOXYyb3dubko4STRFYi1FNVNfcFhOUjY3SC01ZEZ1c01TTXNlZVFHLVhVVHJ0dEZBeExtanZpQ29naWhudjZ3U2RXS0o5eHNOaXVaa1JmZzVwb3pjTUxITHVMQ2E0YUNfUzA3T0EzWERMN1ZqOTJPS1pNZURsSGREMDBqRV9Sd3IyUDkwOGk1aHR5dWE5OElnZzNMQUFrbk0zM3dhSC0ycGViUHhsdkF1NFBrUERJZWlac0hmTVN5OFlOMWxuazUzX1ZGNUlieTZ2Yk16U0Zwa0ZpVHRKV3RTQU1LTUxwcFllUHZKZW9KVGxqX3dqaEs1bkdNNnIwUmFrTjAtbXBITDdtcUFRWW8yeEZRaUtzWmt0c2N3RTdoRFlWRUl6U0FFRnRUTFVaWWZoTXFvUS1BWUYyQXVabVdUdDNES3RvU3BPa255NUtha3ciLCJpYXQiOjE2MTQxODAyNzcsImV4cCI6MTYxNDE4Mzg3N30.sXACzTTJ8To9NOKosCdgpaaiYw1XP0wM5p7ecgHiXsg,
    Connection:keep-alive,
    cache-control:no-cache
  ]
}

Form Body: {
  code: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuZWVkX3BhdGllbnRfYmFubmVyIjpmYWxzZSwic21hcnRfc3R5bGVfdXJsIjoiaHR0cHM6Ly9zbWFydC5hcmdvLnJ1bi8vc21hcnQtc3R5bGUuanNvbiIsInBhdGllbnQiOiIyY2RhNWFhZC1lNDA5LTQwNzAtOWExNS1lMWMzNWM0NmVkNWEiLCJlbmNvdW50ZXIiOiIxZTM4Yjc3MS1lYTg3LTQzNDMtYTVhOC02MDAyMjM3NGNiYWEiLCJyZWZyZXNoX3Rva2VuIjoiZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKSVV6STFOaUo5LmV5SmpiMjUwWlhoMElqcDdJbTVsWldSZmNHRjBhV1Z1ZEY5aVlXNXVaWElpT21aaGJITmxMQ0p6YldGeWRGOXpkSGxzWlY5MWNtd2lPaUpvZEhSd2N6b3ZMM050WVhKMExtRnlaMjh1Y25WdUx5OXpiV0Z5ZEMxemRIbHNaUzVxYzI5dUlpd2ljR0YwYVdWdWRDSTZJakpqWkdFMVlXRmtMV1UwTURrdE5EQTNNQzA1WVRFMUxXVXhZek0xWXpRMlpXUTFZU0lzSW1WdVkyOTFiblJsY2lJNklqRmxNemhpTnpjeExXVmhPRGN0TkRNME15MWhOV0U0TFRZd01ESXlNemMwWTJKaFlTSjlMQ0pqYkdsbGJuUmZhV1FpT2lKbU16VTVZVEpoTnkwMk1XTTJMVFEyWWpZdE9XSmlOQzAyWlRNMlpHWTBOemM0TTJVaUxDSnpZMjl3WlNJNklteGhkVzVqYUNCdmJteHBibVZmWVdOalpYTnpJRzl3Wlc1cFpDQndjbTltYVd4bElHWm9hWEpWYzJWeUlHeGhkVzVqYUM5d1lYUnBaVzUwSUhCaGRHbGxiblF2VUhKaFkzUnBkR2x2Ym1WeUxuSnpJSEJoZEdsbGJuUXZUMkp6WlhKMllYUnBiMjR1Y25NZ2NHRjBhV1Z1ZEM5RmJtTnZkVzUwWlhJdWNuTWdjR0YwYVdWdWRDOVBjbWRoYm1sNllYUnBiMjR1Y25NaUxDSjFjMlZ5SWpvaVVISmhZM1JwZEdsdmJtVnlMelV5T1RFNU1EazVMVFpoTjJFdE5EUXlZeTFpTUdRMUxUSmlNREpqTUdSa05HSTNOQ0lzSW1saGRDSTZNVFl4TkRFNE1ESTNOeXdpWlhod0lqb3hOalExTnpFMk1qYzNmUS5yME1rdVgwSmN5QVp1X3M0WDJRVUF4bmc3ajM2eHo0S1pzQTdKYzUxZU5JIiwidG9rZW5fdHlwZSI6ImJlYXJlciIsInNjb3BlIjoibGF1bmNoIG9ubGluZV9hY2Nlc3Mgb3BlbmlkIHByb2ZpbGUgZmhpclVzZXIgbGF1bmNoL3BhdGllbnQgcGF0aWVudC9QcmFjdGl0aW9uZXIucnMgcGF0aWVudC9PYnNlcnZhdGlvbi5ycyBwYXRpZW50L0VuY291bnRlci5ycyBwYXRpZW50L09yZ2FuaXphdGlvbi5ycyIsImNsaWVudF9pZCI6ImYzNTlhMmE3LTYxYzYtNDZiNi05YmI0LTZlMzZkZjQ3NzgzZSIsImV4cGlyZXNfaW4iOjM2MDAsImlkX3Rva2VuIjoiZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKU1V6STFOaUo5LmV5SndjbTltYVd4bElqb2lVSEpoWTNScGRHbHZibVZ5THpVeU9URTVNRGs1TFRaaE4yRXRORFF5WXkxaU1HUTFMVEppTURKak1HUmtOR0kzTkNJc0ltWm9hWEpWYzJWeUlqb2lVSEpoWTNScGRHbHZibVZ5THpVeU9URTVNRGs1TFRaaE4yRXRORFF5WXkxaU1HUTFMVEppTURKak1HUmtOR0kzTkNJc0ltRjFaQ0k2SW1Zek5UbGhNbUUzTFRZeFl6WXRORFppTmkwNVltSTBMVFpsTXpaa1pqUTNOemd6WlNJc0luTjFZaUk2SWpaaE1qQTFOR1prT1RWa1lqRTFOVFV5WXpkbE5XWmxZalU0WlRKbU5ERXhNRFkwT1RZd1pEUXlNR1F5TWpVNU56SmtaakZoWVRZeU4yTTVZalZqTXpZaUxDSnBjM01pT2lKb2RIUndjem92TDNOdFlYSjBMbUZ5WjI4dWNuVnVMeUlzSW1saGRDSTZNVFl4TkRFNE1ESTNOeXdpWlhod0lqb3hOakUwTVRnek9EYzNmUS5LTXdvaDNSb3FVcFpfOXYyb3dubko4STRFYi1FNVNfcFhOUjY3SC01ZEZ1c01TTXNlZVFHLVhVVHJ0dEZBeExtanZpQ29naWhudjZ3U2RXS0o5eHNOaXVaa1JmZzVwb3pjTUxITHVMQ2E0YUNfUzA3T0EzWERMN1ZqOTJPS1pNZURsSGREMDBqRV9Sd3IyUDkwOGk1aHR5dWE5OElnZzNMQUFrbk0zM3dhSC0ycGViUHhsdkF1NFBrUERJZWlac0hmTVN5OFlOMWxuazUzX1ZGNUlieTZ2Yk16U0Zwa0ZpVHRKV3RTQU1LTUxwcFllUHZKZW9KVGxqX3dqaEs1bkdNNnIwUmFrTjAtbXBITDdtcUFRWW8yeEZRaUtzWmt0c2N3RTdoRFlWRUl6U0FFRnRUTFVaWWZoTXFvUS1BWUYyQXVabVdUdDNES3RvU3BPa255NUtha3ciLCJpYXQiOjE2MTQxODAyNzcsImV4cCI6MTYxNDE4Mzg3N30.sXACzTTJ8To9NOKosCdgpaaiYw1XP0wM5p7ecgHiXsg
  grant_type: 'authorization_code'
  client_id: 'f359a2a7-61c6-46b6-9bb4-6e36df47783e'
  redirect_uri: 'http://localhost:443/index'
  code_verifier: '34b2a3a9985d2759786fbe2f8c413591e45c7a5b1abc5635b75e605e3a0327e96e47fbe9eec0eb9442c5df6ebde093dfcc445774ee665a93160b1a505f3fa9b90d1d228f3ed057e4cce581b9bea4a9bec94b077282b6a70995d97d889c9240580721201f4336c69d47e97586'
}

view this post on Zulip Keller Martin (Feb 24 2021 at 15:31):

And yes, message is empty in the response.

view this post on Zulip Keller Martin (Feb 24 2021 at 15:35):

According to the PCKE docs, I would expect a formatted error response. If this is not expected to work, I can chalk it up to it not being implemented. If this is the case, is there a server you know of that has PCKE implemented for the EHR launch that I can test against?

view this post on Zulip Keller Martin (Feb 24 2021 at 15:35):

https://tools.ietf.org/html/rfc7636#section-4.4.1

view this post on Zulip Keller Martin (Feb 24 2021 at 16:04):

To answer your question, no I do not have a way to test with the patient standalone launch, my client app is only ehr launch at the moment.

view this post on Zulip Josh Mandel (Feb 24 2021 at 16:47):

One quick note from your example -- the code_verifier is 216 characters long but the PKCE spec says:

code_verifier = high-entropy cryptographic random STRING using the unreserved characters [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" from Section 2.3 of [RFC3986], with a minimum length of 43 characters and a maximum length of 128 characters.

view this post on Zulip Josh Mandel (Feb 24 2021 at 16:48):

Can you include an example with an auth code, too? That'd help check that the verifier and the challenge match.

view this post on Zulip Josh Mandel (Feb 24 2021 at 16:49):

Re: Error reporting, this is something we should look into -- it will be important for the launcher to provide informative errors, for debugging! (Right now, you could run the launcher locally with docker-compose and review the console; but that's not a great lightweight option.)

view this post on Zulip Keller Martin (Feb 24 2021 at 17:23):

The auth code in that example is the same as the Bearer auth token in the headers. I think that's correct from the documentation? I just didn't want to put the same code twice. I was confused as to why I would need to send the same code as the token auth and in the form body.

view this post on Zulip Keller Martin (Feb 24 2021 at 17:25):

Just sent another request with a code_verifier of 64 characters:

Code Verifier: fb47fc5221317f14fa5a65e4bab82bd7790e69dd7b5d72e75fe8e812a082c5c9
Code Challenge: uXfVXKj-tcEDe7ONF03OkMFdnAuPoKeNfWPYmxea-Lc

view this post on Zulip Keller Martin (Feb 24 2021 at 17:26):

Edited my previous request body to use the authorization code.

view this post on Zulip Keller Martin (Feb 24 2021 at 17:51):

To be clear, I'm sending in the access_token from the /authorization response in the header and in the form body.

view this post on Zulip Keller Martin (Feb 24 2021 at 18:09):

Also, just set up the launcher locally and ran with docker. The container does not have a /.well-known/smart-configuration, is that something I need to set up? Using https://github.com/microsoft-healthcare-madison/smart-launcher

view this post on Zulip Josh Mandel (Feb 24 2021 at 19:03):

The auth code in that example is the same as the Bearer auth token in the headers. I think that's correct from the documentation?

This doesn't sound right. Can you clarify which documentation you mean?

view this post on Zulip Josh Mandel (Feb 24 2021 at 19:04):

The container does not have a /.well-known/smart-configuration, is that something I need to set up?

The branch you pointed to is the right branch to be running (it's what's deployed at https://smart.argo.run). https://github.com/microsoft-healthcare-madison/smart-launcher/blob/master/src/wellKnownSmartConfiguration.js is the code for the smart-configuration page, and https://smart.argo.run/v/r4/fhir/.well-known/smart-configuration shows it in the publicly hosted instance. I'm not sure what may be happening locally.

view this post on Zulip Josh Mandel (Feb 24 2021 at 19:05):

(BTW, thanks for digging in here, and sorry the debugging is so challenging.)

view this post on Zulip Keller Martin (Feb 24 2021 at 19:52):

I think I'm confusing access_token with authorization_code. Up until this point I assumed they were the same. I believe there is some magic happening between the original /authorize request and when my client receives the access_token. Looking at this https://tools.ietf.org/html/rfc6749#section-4.1.
Seems that the authorization_code is used in a behind-the-scenes handshake here. Then I receive the access_token in the token response.
I'm using the js fhir-client. Do I need to make another call to the server's /authorize endpoint to get this authorization_code? Surely I can somehow grab that code during the original authorize request.

view this post on Zulip Keller Martin (Feb 24 2021 at 20:13):

Yep. Seems like it's the access_token in the bearer auth header, and the authorization_code in the body. https://tools.ietf.org/html/rfc6749#section-7.1

view this post on Zulip Keller Martin (Feb 24 2021 at 20:18):

Also, I'm using /authorize and the fhir-client.js method FHIR.oauth2.authorize() interchangeably. I assume that's correct.

view this post on Zulip Isaac Vetter (Feb 24 2021 at 22:45):

Hey Keller, fyi - I'm pretty sure that this sandbox supports PKCE.

view this post on Zulip Josh Mandel (Feb 24 2021 at 22:53):

The code you're pasting in appears to be an access token, not an authorization code.

view this post on Zulip Josh Mandel (Feb 24 2021 at 22:54):

Though I don't understand how you'd have an access token before calling the access token endpoint. Is it possible you've mixed up the values in the example you created?

view this post on Zulip Keller Martin (Feb 25 2021 at 01:22):

I am calling the /token endpoint after I call the /authorization endpoint.
Workflow:

1. EHR launch calls my client's `/launch` endpoint
2. Client calls FHIR.oauth2.authorize with the `code_verifier`
3. Server calls the redirect endpoint with an access token (the client never sees any `authorization_code`)
...
6. Client calls `'.well-known/smart-configuration` to get `/introspect` and `/token` endpoints
7. Token introspection
8. Client calls `/token` endpoint with the `access_token` from step 3.

Seems like I'm doing something wrong here by the way you are responding. Steps 1-3 are in a javascript client, and the rest of the work happens in a backend Java app.

view this post on Zulip Keller Martin (Feb 25 2021 at 01:23):

@Isaac Vetter thanks for the reference, I'll check this out tomorrow

view this post on Zulip Keller Martin (Feb 25 2021 at 01:26):

@Josh Mandel Yes it is, I was working under the assumption that access_token and authorization_code were the same thing. I realize this was a misunderstanding on my end, but I have never seen any authorization_code and am not sure how to get it. The response from the /authorize endpoint only returns an access token and a refresh token.

view this post on Zulip Josh Mandel (Feb 25 2021 at 01:45):

I think you may be a bit confused; the authorization response includes a URL parameter called code, and that parameter conveys the authorization code to your app. That's the one you include in your request to the token endpoint.

view this post on Zulip Keller Martin (Feb 25 2021 at 05:21):

Yep I was confused. I'll grab the code from the URL, thanks.

view this post on Zulip Keller Martin (Feb 25 2021 at 14:53):

Well that was it - thanks for the simple solution. Just made a successful /token request to the server. Thanks for diving into that with me @Josh Mandel !

view this post on Zulip Josh Mandel (Feb 25 2021 at 14:56):

Hurray!

view this post on Zulip Josh Mandel (Feb 25 2021 at 14:56):

(Only downside is that now improving our error responses is falling down on my priority list ;-))

view this post on Zulip Brian Postlethwaite (Oct 20 2021 at 02:04):

I'm also adding support for PKCE in my client app too (and a server) and looking for reference material on implementing it in javascript inside the browser.
The only part I'm really after is what goes into the function:
var encoded_code_challenge = encodeHash(code_challenge);

Is it really this simple, or have I stuffed something up

window.crypto.subtle.digest('SHA-256', encoder.encode('2972734071')).then(hashBuffer => {
        const uiArray =new Uint8Array(hashBuffer);
        encoded_code_challenge = btoa(uiArray);
});

and the .net side to verify it (which isn't working)

var computedChallenge = Convert.ToBase64String(hasher.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(code_verifier)));
if (computedChallenge != _context.CodeChallenge)
...

(I think the .net side is right, but pretty sure the javascript is wrong)

view this post on Zulip Brian Postlethwaite (Oct 20 2021 at 02:26):

Should I just be using base64-js or some similar package?
This is what I ended up with (in the code above)

<script src="https://cdn.jsdelivr.net/npm/js-base64@3.7.2/base64.min.js"></script>
encoded_code_challenge = Base64.fromUint8Array(new Uint8Array(hashBuffer));

If there's an easier way without the other package, interested to know.
(and I also URL encoded the result of the above too)

view this post on Zulip Brian Postlethwaite (Oct 20 2021 at 02:42):

Was there a good way anyone else has done the random string generation too?

view this post on Zulip Brian Postlethwaite (Oct 20 2021 at 02:51):

Works while testing on https://smart.argo.run/ with PKCE enabled
Test Launch URL https://smartqedit4.azurewebsites.net/ts/Tester/smart-launch.html
Test Redirect URL https://smartqedit4.azurewebsites.net/ts/Tester/smart-index.html

view this post on Zulip Josh Mandel (Oct 20 2021 at 03:05):

https://www.npmjs.com/package/pkce-challenge if you don't mind taking a dependency, or you can read through it for example of how to create the challenge from the verifier in any case.

Are you base64url encoding to create the challenge? From the examples above I don't see where.

view this post on Zulip Josh Mandel (Oct 20 2021 at 03:09):

Or: https://github.com/microsoft-healthcare-madison/client-js/blob/68ddd4c2c2c6c594b9ef467e70ac46754f5f350b/src/security/index.ts#L37-L43 is the code I put together at the last connectathon

view this post on Zulip Josh Mandel (Oct 20 2021 at 03:15):

Works while testing on https://smart.argo.run/ with PKCE enabled

Can you clarify what works? When I try the launcher with your example launch URL I see

smart-launch.html:6 GET https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js net::ERR_ADDRESS_UNREACHABLE

in the client page

view this post on Zulip Brian Postlethwaite (Oct 20 2021 at 03:31):

https://smart.argo.run/?auth_error=&client_secret=&fhir_version_2=r4&iss=&jwks=&jwks_uri=&launch_ehr=1&launch_url=https%3A%2F%2Fsmartqedit4.azurewebsites.net%2Fts%2FTester%2Fsmart-launch.html&patient=87a339d0-8cae-418e-89c7-8651e6aab3c6&prov_skip_auth=1&prov_skip_login=1&provider=e443ac58-8ece-4385-8d55-775c1b8f3a37&pt_skip_auth=1&public_key=&redirect_uris=https%3A%2F%2Fsmartqedit4.azurewebsites.net%2Fts%2FTester%2Fsmart-index.html&sde=&sim_ehr=1&token_lifetime=15&user_pt=&validate_pkce=1&validation_method=public

view this post on Zulip Brian Postlethwaite (Oct 20 2021 at 03:34):

And yes, the Base64URL encoding was added after I posted that original snippit.

view this post on Zulip Josh Mandel (Oct 20 2021 at 03:55):

Excellent, that link works for me. I thought you were saying that it was working for you without the base6urlencoding, which would have indicated to me that there was a problem with the launcher accepting pkce parameters without properly checking them :-)


Last updated: Apr 12 2022 at 19:14 UTC