Do you use or administer OpenEMR? Take the General Satisfaction Survey to help improve the product

V6 Authorization and API changes afoot

I believe about 3 weeks ago. The curl queries I had used previously no longer work so I assume it’s due to the API changes.

That’s because we removed the old auth method and add new which is different endpoints.
Your request look okay.
Pull in current master and rebuild. Then try to register after setting up globals.

I’ll throw out there for other’s benefits who are trying to follow along with the CURL requests on the api documentation that I had to urlencode my curl request to get things to work. I’m on ubuntu w/ bash on the command line so not sure if its different on other environments as any spaces, colons, or slashes were creating errors.

Note you use the client_id you get from the registration request Jerry mentions. The state parameter is a randomly generated string you will use as a CSRF token. It will get returned to you at the callback URL you provided in the redirect_uris as part of your application client registration call and you can use it to make sure the request hasn’t been tampered with.

curl -X GET -k -i ‘https://localhost:9300/oauth2/default/authorize?response_type=code&client_id=9qAEZoCDYOdDlCeU1oJbNo-uItuzKxEqBCLz9hq6McA&state=a85b870548dd8880ddb7c3192439f468fe63396f&scope=openid%20email%20phone%20address%20api%3Afhir

(Note I’m using the default OpenEMR easy development docker install here).

1 Like

So another thing I’ve been running into problems and figured out that outside of the initial registration request any use of the redirect_uri parameter that @sjpadgett uses in his examples would return invalid responses. I haven’t dug into the code yet as to figure out why that is, but if you only use the redirect_uri parameter in the initial registration request, I was able to get things to work from start to finish.

Note the code parameter returned from the authorization request https://localhost:9300/oauth2/default/authorize (after you provide username/password and authorize the scopes) is VERY shortlived (I think its set to 60 seconds) so if you are manually testing this on the CLI you’ll want to make sure to handle that final request to https://localhost:9300/oauth2/default/token to get your access token is done quickly.

Any client request that includes the redirect_url must match the registered redirect_url. This is a security feature of the spec.

Should be 10 minutes. I had it at I think 1 or 2 minutes at one time but changed it I thought!

nope, production is set at 1 minute. Not sure I want to change longer.

yep, reminds when I was trying to use cli for code flow (quickly copy/pasting things :slight_smile: ). For code flow testing and development I now use a simple oauth client (@sjpadgett pointed me towards it in the past) which make working on code flow development much easier. The package is here:
GitHub - jumbojett/OpenID-Connect-PHP: Minimalist OpenID Connect client

And I have 2 client.php setups.

easy dev environment: https://gist.github.com/bradymiller/82202f0c1157f57e58cd7f8967766ade

online demo testing: https://gist.github.com/bradymiller/1d3f06b3c8a2c420204f5ed28d2bd3d6

You basically populate the client id and secret in the client.php script and then point your web browser to it and presto (the code is really simple too, so was a way for me to learn how the heck all this stuff including state/nonce were working). I installed it on my local environment outside the dockers.

Hi Jerry,

I pulled the latest version and rebuilt. Is this the correct site address for testing?

I tried the example in the readme and got the below. Does that look right?

Nope, looks to me like the dependencies were not updated.
Did you rebuild after source update?

I did:

sudo docker stop $(sudo docker ps -aq)

sudo docker rm $(sudo docker ps -aq)

cloned master onto my VM in a new directory, cd’ed into openemr/docker/development-easy-light
then

sudo docker-compose up

combining docker and docker-compose commands can be tricky. in your case, also need to then remove the shared volumes after the docker stop/rm commands:
docker volume prune

1 Like

Thanks Brady. Rachel’s original issue appeared to me as missing the crypt dependency.

yep, not removing shared volumes in the easy docker dev environments will break lots of things (including not re-updating all the composer/js libraries). I still marvel how those easy dev dockers do what they do (in terms of hiding everything from the underlying working repository).

Thanks. I pruned the volumes and rebuilt.

I was able to get a response to the registration.

I copied the client ID into the password grant example. It gave the following error.

I checked and it is “on for both roles” in settings.

looks like you need to remove the spacing preceding the & characters in your call (i only know this because I also did the same thing on the weekend call)

Ya know what’d be great for this Brady? A short youtube video! What do ya think?:wink:

Hey all,

Thank you for pointing out the spaces. I removed them and was able to obtain an ID token.

Are we able to access the previous standard API functionality at this point? I tried a few different variations of a curl command to post data to the practitioner table but got some error messages.

Something like the below where I put the ID token in the header.

I wasn’t sure what url to specify in place of http://localhost:8300/apis/default/api/practitioner

Would https://localhost:9300/oauth/default/api/practitioner work?

curl -X POST ‘http://localhost:8300/apis/default/api/practitioner’ -H ‘Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJEVlZGNmFKZTNpVGlrMjl5bUUxN2N4THM0WmwzNlpYLVdXWG91SFVCVDJrIiwiaXNzIjoiaHR0cHM6XC9cL2xvY2FsaG9zdDo5MzAwIiwiaWF0IjoxNjA4MjI3MDAzLCJleHAiOjE2MDgyMzA2MDIsInN1YiI6IjkyNDQ3M2ViLTk5ODMtNDIyOS04MjYwLTkzOThjNWU3Y2EyMSJ9.aYcriItshE8II6i8Js8Pb2Z7opJg3qQEq_uHBpz1fj54y4_08IwQm83r5rbDL-JdPrrGh0RE3GFYiVLs1CnB5zEFDAkBrnROPt89kV5pMKNuhHG7WWHRDKJEVGfQF-i3k1hTSj1Alc4e1ddTDIsliTD74xUylu4CjMdN6snE2f5orWn5krPgM2yqBXS0iegAVkXEah4ChNeBi0ewKxXjPdSyhmZuuybNi3L4hmBwHVXd75WPJO39TuifjX_2Lk_zjxdmI-mWOsGZYLvLbzADE1oD0BANa1DgQNuJQh8g1zR-ZToRzjdYujJfjTd_1hpnEf85XynT4shf2f_RhBZPQQ",“token_type”:“Bearer”,“expires_in”:3600,“access_token”:“eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJEVlZGNmFKZTNpVGlrMjl5bUUxN2N4THM0WmwzNlpYLVdXWG91SFVCVDJrIiwianRpIjoiNzAwODJiZjcwZGQ1YjIxYThlOWY1MWVhYjRkMjY4MmU3YzhlMDM4YjQ3ZjU0ZGRhYmQyMjNiNjBjNGNlY2JiNGEwYmM2ZWY5M2ZhZmVmYjUiLCJpYXQiOjE2MDgyMjcwMDIsIm5iZiI6MTYwODIyNzAwMiwiZXhwIjoxNjA4MjMwNjAyLCJzdWIiOiI5MjQ0NzNlYi05OTgzLTQyMjktODI2MC05Mzk4YzVlN2NhMjEiLCJzY29wZXMiOlsib3BlbmlkIiwic2l0ZTpkZWZhdWx0Il19.CtG7QGRpoQ0vRsIAVfKJpWa6czCShNg2Dqde-hwEFObQnzgnFdMl2Apq6nrtwDnVPVox0mV0rU1dlFkfcVX25CMf2vgPYQKKDGzL9FICnjIX63Mc7_i1Sxlwd8R5QRS_KyR-YGZr9m0CH6LRudxLXS9_1-grEoSAXiPXA38dmduMDFGMWffhFNBjDS6PJwuD5wf_jyAoHYGG_rOsXkPObOC5KKuoZzHr6ARDV4o3t-gtFLVHEAUu2TxjkC4HVLT2bNY5gmmZ7VnSOvLlV1UVSJMTnZQNS6NhAC5xyPHfEKJoFWwVCsVBNEHj7Wm_5-TI2QFJK9q_AanRvSkzgIzXzA”,“refresh_token”:"def5020037fb2e43b5aeb4abcd7de367df86a2005438a537937c7a9d37995cc79a8a4d054c75e9cf9c3251c6808edd714a8a45db3c9f5e2888a2e0b92b3c4ec1b1757d5dec24e393e9b92c49c0976238e60841be1b654db328dda7280fa0dee2b88f506b9f54a5c8219092ee000274379fb45dc0d18d0a628e812aabe5645b9733837b96f5b32a4dc20f6a3eb753d4c964b9aeaa44fa158134514053fb3c6fd1125d7801e4da3b937c1b85c4f808302eb0faaa09a386c1b9567367a371c9856f70215eaf682185fab3a2d3286ddd9bb924f2f31b16d0e0ceffe9241c55a26d9c313c2338b459ff1260ef5843c1a6bc785428ee1d8e0d6809b25336988aaa584f576d618c2237c80c5add3e21a53d9e9fd025e0be3b040367c386fbb2a4105edbfa719e7cdae19248e655036674b33a4c0cec69834fddf190cdd01b456fa40b92b6f6600434eb38a9791395df11e84d842da27b4b9da14b1743c3c4e7f96479b577939e60a5cdcfb6ceca7e473724ed5514869174a3c42161ebcead11ea5d40c272f9db67f1dfc2fd9adf196008107b6134052758cf9b3e7af4ec6175e42544d844828e38cfb13e8be85317dfacd5e2590912f5b28636bc864688b5e199519fcda97d73de859d90’ -d ‘{“title”: “Mrs.”,“fname”: “Eduardo”,“mname”: “Kathy”,“lname”: “Perez”,“federaltaxid”: “”,“federaldrugid”: “”,“upin”: “”,“facility_id”: “3”,“facility”: “Your Clinic Name Here”,“npi”:“0123456789”,“email”: “info@pennfirm.com”,“specialty”: “”,“billname”: null,“url”: null,“assistant”: null,“organization”: null,“valedictory”: null,“street”: “789 Third Avenue”,“streetb”: “123 Cannaut Street”,“city”: “San Diego”,“state”: “CA”,“zip”: “90210”,“phone”: “(619) 555-9827”,“fax”: null,“phonew1”: “(619) 555-7822”,“phonecell”: “(619) 555-7821”,“notes”: null,“state_license_number”: “123456”}’

The bearer token should be the access_token not id_token. The id_token is used by the client to get information about the user the access_token was issued to.
Also, the access_token only lives for one hour at which time you’ll receive a http 401 status where either have to use the issued refresh token to receive new access_token or a new code flow to re-sign into auth server i.e get a new trusted user session and tokens.

@sjpadgett / @brady.miller, healthit.gov provides clinfhir tool that allows connecting to fhir sites and permits other capabilities.

If we set up one of the demo servers to readily interact with that tool across the periodic refreshes, it will help users see the fhir in action. Other tools at that site will let them see the full potential of this feature.

1 Like

Hi Guys,

Thanks to @benmarte I was able to register a test application in OpenEMR v6 but now I’m having issue trying to generate my auth token.

This is how I registered my client

curl --location --request POST ‘http://localhost/oauth2/default/registration
–header ‘Content-Type: application/json’
–data-raw ‘{
“application_type”: “private”,
“redirect_uris”: [
http://localhost:3000
],
“post_logout_redirect_uris”: [
http://localhost:3000
],
“initiate_login_uri”: “https://localhost:3000”,
“client_name”: “external-web-app”,
“token_endpoint_auth_method”: “client_secret_post”,
“username”: “admin”,
“password”: “pass”,
“scope”: “openid api:oemr api:fhir api:port api:pofh user/allergy.read user/allergy.write”
}’

I got the following answer which looks fine

{“client_id”:“Nc0A6QG70aY8mEJa4WkmFcb–q1zV7otwowWfUmsNmM”,“client_secret”:“pnYukidooOhwtoA0mRjQkhFq3RjB4bPF5ZCiAgwGuZCxaOM1O5yXoNFA8TNYoc7mdQssCw87cmaqCIGJ96w8Jw”,“registration_access_token”:“MvIw-BU3cOP7qOEqNygOUNhYbQtCB846j26cdEmWZwY”,“registration_client_uri”:“ec2-18-212-180-77.compute-1.amazonaws.com/oauth2/default/client/GkT5iv1cOmuCmmhn2vmFgw",“client_id_issued_at”:1612675985,“client_secret_expires_at”:0,“client_role”:“user”,“application_type”:“private”,“client_name”:“external-web-app”,“redirect_uris”:[“http://localhost:3000”],“post_logout_redirect_uris”:[“http://localhost:3000”],“token_endpoint_auth_method”:“client_secret_post”,“initiate_login_uri”:“https://localhost:3000”,“scope”:"openid api:oemr api:fhir api:port api:pofh user/allergy.read user/allergy.write”}

I then tried to request a token with:
curl -X POST -k -H ‘Content-Type: application/x-www-form-urlencoded’ -i ‘http://localhost/oauth2/default/token’ --data ‘grant_type=password&client_id=Nc0A6QG70aY8mEJa4WkmFcb–q1zV7otwowWfUmsNmM&username=admin&password=pass&user_role=users&scope=openid api:fhir’

But I got the following error message:
HTTP/1.1 400 Bad Request
Date: Sun, 07 Feb 2021 05:35:42 GMT
Server: Apache
Set-Cookie: authserverOpenEMR=ZrH9EuM1f4KTqy96UrreQK8diMOZa1lC80DXGIM7HKvUdiX1; expires=Sun, 07-Feb-2021 13:22:22 GMT; Max-Age=28000; path=/oauth2/; secure; HttpOnly; SameSite=None
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: origin, authorization, accept, content-type, x-requested-with
Access-Control-Allow-Methods: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS
Access-Control-Allow-Origin: *
Set-Cookie: authserverOpenEMR=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/oauth2/; secure; HttpOnly; SameSite=None
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-XSS-Protection: 1; mode=block
Content-Length: 566
Connection: close
Content-Type: application/json

{“error”:“invalid_grant”,“error_description”:“The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.”,“hint”:“Failed Authentication”,“message”:“The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.”}

It looks like I’m doing something wrong with the grant but I can’t find what it is.
Any idea?

Thanks a lot !!!

I also made sure my registered client was enabled :slight_smile: