# V6 Authorization and API changes afoot

**URL:** <https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450>\
**Category:** OpenEMR Development\
**Created:** [November 7, 2020, 4:34pm UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450 "2020-11-07T16:34:57Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![sjpadgett](https://community.open-emr.org/user_avatar/community.open-emr.org/sjpadgett/32/21623_2.png) [@sjpadgett](https://community.open-emr.org/u/sjpadgett)\
**Post date:** [November 7, 2020, 4:34pm UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/1 "2020-11-07T16:34:57Z")

</div>

Currently in v6.0.0 master: [Authorization Server by sjpadgett · Pull Request #4013 · openemr/openemr · GitHub](https://github.com/openemr/openemr/pull/4013)  
Here is a summary from post on issue thread: [Implement OA2 Authorization server to support: · Issue #3956 · openemr/openemr · GitHub](https://github.com/openemr/openemr/issues/3956) to catch up.  
As soon as I can get some documentation done I plan to merge.

- If you are currently or plan to use our apis, I strongly encourage you to pay attention to this PR as our api base url has to change to support multi site.
- Also changing is one will have to register their client regardless if using the resource(password) or authorization grant as explained above. Once registered then always registered.
- Mostly OIDC compliant authorization with some, unnecessary for openemr, items left to do.
- Password grant can receive a token via hitting the oauth2/default/token endpoint with the password grant type.(_we’ve removed the custom oauth2/default/password endpoint 11-18-2020_)
- Refresh token is as normal with new access token issued by hitting oauth2/default/token endpoint.

I plan to do a complete api session for final testing before merge by documenting vis several posts in sequence here, starting with registration.  
For clarity, all example urls with ‘default’ part is the targeted site id. I’m also not going to explain what every attribute means as there is more than enough information on the web. Plus, I hate to type.🙂  
Here’s registration Request(note: post\_logout\_redirect\_uris is optional):

```auto
curl -X POST -k -H 'Content-Type: application/json' -i https://localhost/openemrv6/oauth2/default/registration --data '{
   "application_type": "private",
   "redirect_uris":
     ["https://client.example.org/callback"],
   "post_logout_redirect_uris":
     ["https://client.example.org/logout/callback"],
   "client_name": "A Private App",
   "token_endpoint_auth_method": "client_secret_post",
   "contacts": ["me@example.org", "them@example.org"]
  }'

```

Response:

```auto
{
    "client_id": "LnjqojEEjFYe5j2Jp9m9UnmuxOnMg4VodEJj3yE8_OA",
    "client_secret": "j21ecvLmFi9HPc_Hv0t7Ptmf1pVcZQLtHjIdU7U9tkS9WAjFJwVMav0G8ogTJ62q4BATovC7BQ19Qagc4x9BBg",
    "registration_access_token": "uiDSXx2GNSvYy5n8eW50aGrJz0HjaGpUdrGf07Agv_Q",
    "registration_client_uri": "https:\/\/localhost\/openemrv6\/oauth2\/default\/client\/6eUVG0-qK2dYiwfYdECKIw",
    "client_id_issued_at": 1604767861,
    "client_secret_expires_at": 0,
    "contacts": ["me@example.org", "them@example.org"],
    "application_type": "private",
    "client_name": "A Private App",
    "redirect_uris": ["https:\/\/client.example.org\/callback"],
    "token_endpoint_auth_method": "client_secret_post"
}

```

Next will be an authorization code or code grant type request:

```auto
curl -X GET -k -i 'https://localhost/openemrv6/oauth2/default/authorize?
response_type=code
&client_id=LnjqojEEjFYe5j2Jp9m9UnmuxOnMg4VodEJj3yE8_OA
&state=a85b870548dd8880ddb7c3192439f468fe63396f
&scope=openid email phone address api:pofh api:fhir
&redirect_uri=https://client.example.org/callback'

```

Response is a redirect to get user consent.

1. Status : 301 Moved Permanently
2. Location : [https://localhost/openemrv6/oauth2/default/provider/login](https://localhost/openemrv6/oauth2/default/provider/login)  
 ![image](https://discourse-uploads-openemr.s3.dualstack.us-east-1.amazonaws.com/original/2X/9/9bab3286cb7dfc1604aa957e678c4b6b2653f102.png)  
Ignore Register button as forgot to remove. Then  
 ![image](https://discourse-uploads-openemr.s3.dualstack.us-east-1.amazonaws.com/original/2X/1/16d1bcca753056641793478917b1f9dd3d71247a.png)

Where an authorization code is returned and client sends a request for access\_token:

```auto
curl -X POST -k -H 'Content-Type: application/x-www-form-urlencoded' 
-i https://localhost/openemrv6/oauth2/default/token 
--data 'grant_type=authorization_code
&client_id=LnjqojEEjFYe5j2Jp9m9UnmuxOnMg4VodEJj3yE8_OA
&client_secret=j21ecvLmFi9HPc_Hv0t7Ptmf1pVcZQLtHjIdU7U9tkS9WAjFJwV....
&redirect_uri=https://client.example.org/callback
&code=def50200102853212bca0b139843....'

```

with a json response:

```auto
{
  "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJ...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQi...",
  "refresh_token": "def502001d015749fa13456a9d39faeccbf659..."
}

```

I’ll maybe come back to this to continue with refresh however, the web can describe this flow better than me. Next will do an api call using our issued token.

Here is a create patent FHIR request just to show it:

```auto
curl -X POST -k -H 'Authorization: Bearer eyJ0eXAiOiJ...' -i https://localhost/openemrv6/apis/default/fhir/Patient 
--data '{"id":"46","meta":{"versionId":"1","lastUpdated":"2020-03-24T19:49:24"},"resourceType":"Patient","active":true,"name":[{"use":"official","family":"Aaaa Jr.","given":["Jim","Adam"]}],"gender":"male","birthDate":"1969-04-11","address":[{"line":["16129 Barry Rd"],"city":"Brandon","state":"FL","postalCode":"33511"}]}'

```

Response is a 201 created status and body:

```auto
{
  "validationErrors": [],
  "internalErrors": [],
  "data": {
    "pid": 511,
    "uuid": "91f45c9b-36bc-4c8c-a646-030a758b771e"
  }
}

```

So a couple other points real quick:  
Hitting the [https://localhost/openemrv6/oauth2/default/.well-known/openid-configuration](https://localhost/openemrv6/oauth2/default/.well-known/openid-configuration) endpoint will return any needed discovery of supported claims and scopes and supported auth endpoints as a json.  
example:

```auto
{
"issuer": "https://localhost/openemrv6/oauth2/default",
"authorization_endpoint": "https://localhost/openemrv6/oauth2/default/authorize",
"token_endpoint": "https://localhost/openemrv6/oauth2/default/token",
"jwks_uri": "https://localhost/openemrv6/oauth2/default/jwk",
"userinfo_endpoint": "https://localhost/openemrv6/oauth2/default/userinfo",
"registration_endpoint": "https://localhost/openemrv6/oauth2/default/registration",
"scopes_supported": [
    "openid",
    "profile",
    "name",
    "given_name",
    "family_name",
    "nickname",
    "phone",
    "address",
    "email",
    "email_verified",
    "api:oemr",
    "api:fhir",
    "api:port",
    "api:pofh"
],
"response_types_supported": [
    "code",
    "token",
    "id_token",
    "code token",
    "code id_token",
    "token id_token",
    "code token id_token"
],
"code_challenge_methods_supported": [
    "S256",
    "plain"
],
"grant_types_supported": [
    "authorization_code",
    "password",
    "refresh_token"
],
"response_modes_supported": [
    "query",
    "fragment",
    "form_post"
],
"subject_types_supported": [
    "public"
],
"claims_supported": [
    "aud",
    "email",
    "email_verified",
    "exp",
    "family_name",
    "given_name",
    "iat",
    "iss",
    "locale",
    "name",
    "sub"
],
"require_request_uri_registration": ["false"],
"id_token_signing_alg_values_supported": [
    "RS256"
],
"token_endpoint_auth_methods_supported": [
    "client_secret_post"
],
"token_endpoint_auth_signing_alg_values_supported": [
    "RS256"
]
}

```

Forgot second point.🙂

So once in codebase this phase 1 and 2(OAuth2 and OIDC) towards our ONC Api requirement. Besides Api testing requirements, the last phase of Api access will be the Smart on FHIR requirement.

Good luck.

---

<div class="post-metadata">

**Author:** ![Amiel](https://community.open-emr.org/letter_avatar_proxy/v4/letter/a/8baadc/32.png) [@Amiel](https://community.open-emr.org/u/Amiel)\
**Post date:** [November 10, 2020, 8:42am UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/2 "2020-11-10T08:42:05Z")

</div>

Hi @sjpadgett

Really huge and great work!  
I’m testing the new authentication now, meanwhile I’ve found 2 bugs with the length of the client\_id and client\_secret.

1. the column length of client\_id is 40 but the generated sting is 43.
2. the column length of client\_secret is 80 but the generated sting is 86.

And a few questions-

1. What need to set in the “state” property in the GET oauth2/default/authorize call?
2. About “refresh token”, you wrote on issue in Github “Refresh token is as normal with new access token issued by hitting oauth2/default/token endpoint.”, how it supposed to work? for new access\_token need “code” and the expiration od the code is very short, can you send example of refresh, or we need new development for refresh token interface if needed, the expiration time of the access token now is 1 hour…
3. is there interface to logout and remove access token from the system?

Thanks  
Amiel

---

<div class="post-metadata">

**Author:** ![sjpadgett](https://community.open-emr.org/user_avatar/community.open-emr.org/sjpadgett/32/21623_2.png) [@sjpadgett](https://community.open-emr.org/u/sjpadgett)\
**Post date:** [November 10, 2020, 10:56am UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/3 "2020-11-10T10:56:58Z")

</div>

Hi @Amiel  
Yep Brady caught that too. I used an old table structure when did PR but Brady did a fix straight in master. He also buttoned down our encrypt keys here: [secured the mechanism for oauth key pair and encryption key by bradymiller · Pull Request #4022 · openemr/openemr · GitHub](https://github.com/openemr/openemr/pull/4022)

Here’s a refresh example:

```auto
curl -X POST -k -H 'Content-Type: application/x-www-form-urlencoded' 
-i 'https://localhost/openemrv6/oauth2/default/token' 
--data 'grant_type=refresh_token
&client_id=kbyuFDidLLm280LIwVFiazOqjO3ty8KH
&client_secret=60Op4HFM0I8ajz0WdiStAbziZ-VFQttXuxixHHs2R7r7-CW8GR79l-mmLqMhc-Sa
&refresh_token=def50200a50b23cf663e51dd535f93.....'

```

Response is new access/id etc

```auto
{
  "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJrYn...",
  "token_type": "Bearer",
  "expires_in": 3599,
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJrYnl1RkRp...",
  "refresh_token": "def5020017b484b0add020bf3491a8a537fa04eda12..."
}

```

I haven’t done the logout or revoke yet but plan to in day or two.

---

<div class="post-metadata">

**Author:** ![sjpadgett](https://community.open-emr.org/user_avatar/community.open-emr.org/sjpadgett/32/21623_2.png) [@sjpadgett](https://community.open-emr.org/u/sjpadgett)\
**Post date:** [November 10, 2020, 11:22am UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/4 "2020-11-10T11:22:43Z")

</div>

Sorry @Amiel forgot state attribute. Here is what I support from OIDC spec:  
OpenID Connect uses the following OAuth 2.0 request parameters with the Authorization Code Flow:

> scope
> 
> REQUIRED. OpenID Connect requests MUST contain the openid scope value. If the openid scope value is not present, the behavior is entirely unspecified. Other scope values MAY be present. Scope values used that are not understood by an implementation SHOULD be ignored. See Sections [5.4](https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims) and [11](https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess) for additional scope values defined by this specification.
> 
> response\_type
> 
> REQUIRED. OAuth 2.0 Response Type value that determines the authorization processing flow to be used, including what parameters are returned from the endpoints used. When using the Authorization Code Flow, this value is code.
> 
> client\_id
> 
> REQUIRED. OAuth 2.0 Client Identifier valid at the Authorization Server.
> 
> redirect\_uri
> 
> REQUIRED. Redirection URI to which the response will be sent. This URI MUST exactly match one of the Redirection URI values for the Client pre-registered at the OpenID Provider, with the matching performed as described in Section 6.2.1 of [[RFC3986]](https://openid.net/specs/openid-connect-core-1_0.html#RFC3986) (Simple String Comparison). When using this flow, the Redirection URI SHOULD use the https scheme; however, it MAY use the http scheme, provided that the Client Type is confidential, as defined in Section 2.1 of OAuth 2.0, and provided the OP allows the use of http Redirection URIs in this case. The Redirection URI MAY use an alternate scheme, such as one that is intended to identify a callback into a native application.
> 
> state
> 
> RECOMMENDED. Opaque value used to maintain state between the request and the callback. Typically, Cross-Site Request Forgery (CSRF, XSRF) mitigation is done by cryptographically binding the value of this parameter with a browser cookie.

OpenID Connect also uses the following OAuth 2.0 request parameter, which is defined in [OAuth 2.0 Multiple Response Type Encoding Practices](https://openid.net/specs/openid-connect-core-1_0.html#OAuth.Responses) [OAuth.Responses]:

> response\_mode
> 
> OPTIONAL. Informs the Authorization Server of the mechanism to be used for returning parameters from the Authorization Endpoint. This use of this parameter is NOT RECOMMENDED when the Response Mode that would be requested is the default mode specified for the Response Type.

This specification also defines the following request parameters:

> nonce
> 
> OPTIONAL. String value used to associate a Client session with an ID Token, and to mitigate replay attacks. The value is passed through unmodified from the Authentication Request to the ID Token. Sufficient entropy MUST be present in the nonce values used to prevent attackers from guessing values. For implementation notes, see [Section 15.5.2](https://openid.net/specs/openid-connect-core-1_0.html#NonceNotes).

Remember also for non ‘private’ or native app types you’ll need to follow the PKCE code challenge flow.

---

<div class="post-metadata">

**Author:** ![brady.miller](https://community.open-emr.org/user_avatar/community.open-emr.org/brady.miller/32/10178_2.png) [@brady.miller](https://community.open-emr.org/u/brady.miller)\
**Post date:** [November 11, 2020, 9:09am UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/5 "2020-11-11T09:09:04Z")

</div>

Finally was successful in getting through the entire flow on this. Something I noted in addition to the above tutorial was needed to place the `state` parameter when making a request for an access token which was also returned along with the authorization code (also needed to do it pretty quickly before it timed out 🙂 ). really neat stuff now that i am beginning to understand how it all works.

---

<div class="post-metadata">

**Author:** ![Amiel](https://community.open-emr.org/letter_avatar_proxy/v4/letter/a/8baadc/32.png) [@Amiel](https://community.open-emr.org/u/Amiel)\
**Post date:** [November 12, 2020, 8:53am UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/6 "2020-11-12T08:53:14Z")

</div>

Hi @sjpadgett  
Thanks a lot for your clarification.

Just a few additional issues I’ll happy to understand better.

1. “Password grant” - In which step of the process I can use it? what are the parameters need to send for that? when is better to use a password instead of a token?

2. Do you think to integrate MFA in the authentication process (for users that registered to MFA in the user table)? is it can be fit together?

---

<div class="post-metadata">

**Author:** ![sjpadgett](https://community.open-emr.org/user_avatar/community.open-emr.org/sjpadgett/32/21623_2.png) [@sjpadgett](https://community.open-emr.org/u/sjpadgett)\
**Post date:** [November 12, 2020, 1:32pm UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/7 "2020-11-12T13:32:03Z")

</div>

Hi @Amiel,

1. The password grant doesn’t require an authorization server sign in, only registration. The endpoint for password is the token endpoint with a password grant type and client\_id. A secret currently is not required.

```auto
curl -X POST -k -H 'Content-Type: application/x-www-form-urlencoded' 
-i 'https://localhost/oauth2/default/token' 
--data 'grant_type=password
&client_id=G2aphKFWUks8203A8JtriLnYUTZlTWHjJqIeAg5EqQs
&username=admin
&password=pass
&scope=openid api:fhir'

```

Response

```auto
{
  "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9....",
  "token_type": "Bearer",
  "expires_in": 3600,
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSU...",
  "refresh_token": "def50200ded9989134976302793b9cea72895d5..."
}

```

1. I don’t plan to do MFA as is kind of out of scope for what we currently need for ONC. However, one could add a different third party provider to the flow and hook out of server sign in dialog. Or somewhere depending on what our current MFA requires. I’ve never looked at it and don’t know if only requires a dongle or also sends text/email etc…

edit: changed request password grant endpoint example to default/token as the most correct. Using default/password works also and is unique to openemr.

Here is a password refresh ex:

```auto
curl -X POST -k -H 'Content-Type: application/x-www-form-urlencoded'
-i 'https://localhost/oauth2/default/token' 
--data 'grant_type=refresh_token
&client_id=openemrfhir
&refresh_token=def502005fdeecf212f0158f45...'

```

---

<div class="post-metadata">

**Author:** ![brady.miller](https://community.open-emr.org/user_avatar/community.open-emr.org/brady.miller/32/10178_2.png) [@brady.miller](https://community.open-emr.org/u/brady.miller)\
**Post date:** [November 18, 2020, 7:49am UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/8 "2020-11-18T07:49:16Z")

</div>

Just updated Authentication documentation for this feature:  
[openemr/API\_README.md at master · openemr/openemr · GitHub](https://github.com/openemr/openemr/blob/master/API_README.md#authorization)

@sjpadgett , just really awesome stuff!!!

And of course the fans are happy

![2DV](https://discourse-uploads-openemr.s3.dualstack.us-east-1.amazonaws.com/original/2X/c/c96783041fd7645cfd23d4842a53eeb46da9799d.gif)

---

<div class="post-metadata">

**Author:** ![sjpadgett](https://community.open-emr.org/user_avatar/community.open-emr.org/sjpadgett/32/21623_2.png) [@sjpadgett](https://community.open-emr.org/u/sjpadgett)\
**Post date:** [November 18, 2020, 2:30pm UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/9 "2020-11-18T14:30:33Z")

</div>

Thanks for the coding/review help and especially keeping up with the darn official documenting @brady.miller.

@Amiel You folks are probably the furthest along with implementing this feature. Just wanted you to be aware that Brady and I have tightened security and updated the feature and is in master now.

I am very curious how you plan to use the feature. Are you primarily going to use with password grant or how do you plan to use the password grant?

Are you still looking into hooking in a third party provider or MFA?  
Do you plan to use the public application type for your users and thus the code challenge flow?  
Besides the implemented custom scopes of api:fhir, api:oemr, api:port and api:pofh are there others i’ve missed?

Feedback by anyone is appreciated before I move on to adding a SMART layer which i’ll probably start a new thread to track. SMART will not be included in our upcoming initial release of v6.0.0 but will soon follow.

---

<div class="post-metadata">

**Author:** ![Amiel](https://community.open-emr.org/letter_avatar_proxy/v4/letter/a/8baadc/32.png) [@Amiel](https://community.open-emr.org/u/Amiel)\
**Post date:** [November 23, 2020, 7:18am UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/10 "2020-11-23T07:18:01Z")

</div>

Hi @sjpadgett  
Thank you for being interested in us.  
We are actually at the end of the development of a client-side application based on React for Emergency medical centers, the application needs to start a pilot in the next weeks therefore for now we implement Grant password authentication that matches to existing code, I hope we continue to Code grant when the project will grow up.  
For MFA (we must for security requirements) we plan to expand the existing MFA found in the login of openemr to grant password in the API (for users that turn the MFA on), hopefully to create pull request soon.

Our application use a openemr API and FHIR api but most of the calls address to our zend modules that expand the api.

On this occasion I invite you to take a look on our projects, all the source is open, and from the last weekend integrated with the latest Openemr code.

backend modules -

> **[GitHub - MohGovIL/Clinical-Vertical-emergency-medicine-backend](https://github.com/MohGovIL/Clinical-Vertical-emergency-medicine-backend)**
>
> Contribute to MohGovIL/Clinical-Vertical-emergency-medicine-backend development by creating an account on GitHub.

> [@HL7 FHIR API Module](https://community.open-emr.org/t/hl7-fhir-api-module/14522):
>
> Hi all, In the past several months my team has been working on a module that extends the Openemr API. This API extension adheres to the HL7 FHIR (release 4) API standard, and we are constantly adding more functionality and implementations of the FHIR standard. The source code for this module is hosted on Github here: This repository contains some other modules along with the FhirAPI module. Some of these modules need to be installed as a prerequisite to the FhirAPI module. Documentation…

React client -

> **[GitHub - MohGovIL/Clinical-React](https://github.com/MohGovIL/Clinical-React)**
>
> Contribute to MohGovIL/Clinical-React development by creating an account on GitHub.

devops tools -

> **[GitHub - MohGovIL/Clinical-DevOps](https://github.com/MohGovIL/Clinical-DevOps)**
>
> Contribute to MohGovIL/Clinical-DevOps development by creating an account on GitHub.

Always happy about collaboration.

Best regards  
Amiel

---

<div class="post-metadata">

**Author:** ![Amiel](https://community.open-emr.org/letter_avatar_proxy/v4/letter/a/8baadc/32.png) [@Amiel](https://community.open-emr.org/u/Amiel)\
**Post date:** [November 23, 2020, 8:27am UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/11 "2020-11-23T08:27:51Z")

</div>

@sjpadgett @brady.miller  
Just the last issue is missing in the new authorization server - logout action. would Do you plan to write it soon?  
Thanks a lot…

---

<div class="post-metadata">

**Author:** ![sjpadgett](https://community.open-emr.org/user_avatar/community.open-emr.org/sjpadgett/32/21623_2.png) [@sjpadgett](https://community.open-emr.org/u/sjpadgett)\
**Post date:** [November 23, 2020, 4:49pm UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/12 "2020-11-23T16:49:34Z")

</div>

Thanks @Amiel for sharing what your team has been up to. Very exciting work of which exposure on this thread may help some other community members. I know I learn a couple things.

Concerning logout action, yes I hope to have a PR up tonight or tomorrow that will include logout, revoke and maybe finalize the userinfo endpoint.

I’m still a little concerned with registration and may add a few items to track.

As for MFA, I assume our current core solution meets your need although, it sure would be handy to have in authorization server for apis.

Edit: Looking at a logout, i’m somewhat undecided how best to handle in our implementation.  
I don’t issue cookies to user agent/user to maintain a persistent session state. I persist in a table.  
As far as server is concerned, you are signed into the server unless a refresh token has expired at which point client must sign back into server to get a new token.  
So a logout for us would really just be a revoke of refresh token.

How do you see this working?

---

<div class="post-metadata">

**Author:** ![sjpadgett](https://community.open-emr.org/user_avatar/community.open-emr.org/sjpadgett/32/21623_2.png) [@sjpadgett](https://community.open-emr.org/u/sjpadgett)\
**Post date:** [November 24, 2020, 12:54am UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/13 "2020-11-24T00:54:57Z")

</div>

For client logout here is pattern i’m thinking. Please, anyone with further input, please chime in.

- basic

```auto
GET https://{baseUrl}/logout?id_token_hint=${id_token}

```

The trusted user session associated/identified by the id token will be deleted and a confirmation displayed.

- registered redirects request initiates a logout and redirects to the post\_logout\_redirect\_uri. The registered post\_logout\_redirect\_uri and the request post\_logout\_redirect\_uri must match.

```auto
GET https://{baseUrl}/logout?
  id_token_hint=${id_token}&
  post_logout_redirect_uri=${post_logout_redirect_uri}&
  state=${state}

```

Both initiate a redirect to either the OP confirm dialog or the redirected endpoint depending on request.

```auto
HTTP 302 Found
Location: https://post_logout_redirect_uri/redirect&state=${state}

```

---

<div class="post-metadata">

**Author:** ![sjpadgett](https://community.open-emr.org/user_avatar/community.open-emr.org/sjpadgett/32/21623_2.png) [@sjpadgett](https://community.open-emr.org/u/sjpadgett)\
**Post date:** [November 25, 2020, 3:42am UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/14 "2020-11-25T03:42:04Z")

</div>

> <https://github.com/openemr/openemr/pull/4058>

If post\_logout\_redirect\_uris is provided during registration then after session is destroyed, server will redirect to that endpoint otherwise, a logged out message is sent to user logging out.

We maintain user sessions as trusted users where a log out is essentially removing the trusted user resulting in resource server dispatch denying any tokens, valid or not, from advancing api request until user logs back into identity server.

I don’t see any reason to revoke tokens because that would essentially just be invalidating current session the tokens were issue against. If disagreement, please comment.

@Amiel this probably is of interest you.

---

<div class="post-metadata">

**Author:** ![Amiel](https://community.open-emr.org/letter_avatar_proxy/v4/letter/a/8baadc/32.png) [@Amiel](https://community.open-emr.org/u/Amiel)\
**Post date:** [November 26, 2020, 6:08am UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/15 "2020-11-26T06:08:42Z")

</div>

Looks excellent. thank you!

---

<div class="post-metadata">

**Author:** ![sjpadgett](https://community.open-emr.org/user_avatar/community.open-emr.org/sjpadgett/32/21623_2.png) [@sjpadgett](https://community.open-emr.org/u/sjpadgett)\
**Post date:** [December 4, 2020, 5:25am UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/16 "2020-12-04T05:25:52Z")

</div>

Announcing the token introspection endpoint and if I may say, at one point I just wanted to have a response of yep or nope. I mean, why be so formal!🙂

- Only access\_token and refresh\_tokens will be validated. I may add id\_token later but, it is really not needed IMO.

- All Http status responses will be 200 with response showing whether active and the token status. Exceptions are in the case token fails signature verification or a mangled request then you’ll see appropriate 400/401/500.

- To fetch url from discovery json use `'introspection_endpoint'` that yields something like `https://localhost/oauth2/default/introspect`

- _Request attributes:_

| Field | Description | Type | Required |
| --- | --- | --- | --- |
| client\_id | Application client Id | String | Yes |
| client\_secret | Application Client Secret. If client has private(confidential) registration status, then a client secret is mandatory otherwise, public apps only require client\_id. | String | Yes |
| token\_type\_hint | The appropriate token hint of `access_token` or `refresh_token` | String | Yes |
| token | The string value of the token returned from auth token endpoints. | String | Yes |

```auto
curl -X POST -k -H 'Content-Type: application/x-www-form-urlencoded'
 -i 'https://localhost:port/oauth2/default/introspect' 
--data 'client_id=kbyuFDidLLm280LIwVFiazOqj...
&client_secret=khYVHgkbBBYUU...
&token_type_hint=refresh_token
&token=def50200695611d39349fad4bb913b686e1c53fc99116ebabdfcc08...

```

- _Responses:_

**Active Token**

| Response Body Field | Value Returned |
| --- | --- |
| active | true |
| status | ‘active’ |
| exp | Expiry Epoch Time |
| sub | The subject of the token. Mostly user\_id UUID |
| scope | Token scopes |
| client\_id | Application Client ID Value |

**Expired Token**

| Response Body Field | Value Returned |
| --- | --- |
| active | false |
| status | ‘expired’ |
| exp | Expiry Epoch Time |
| sub | The subject of the token. Mostly user\_id UUID |
| scope | Token scopes |
| client\_id | Application Client ID Value |

**Revoked/Logged out User Token**

| Response Body Field | Value Returned |
| --- | --- |
| active | false |
| status | ‘revoked’ |
| exp | Expiry Epoch Time |
| sub | The subject of the token. Mostly user\_id UUID |
| scope | Token scopes |
| client\_id | Application Client ID Value |

**Invalid Client Id or Client Secret**  
_Also case of token client info doesn’t match trusted user. In both regards let’s not return anything useful_

| Response Body Field | Value Returned |
| --- | --- |
| active | false |
| status | ‘invalid’ |

- _A refresh\_token example response_

```auto
{
    "active": true,
    "status": "active",
    "scope": "openid email phone api:fhir api:pofh site:default",
    "client_id": "kbyuFDidLLm280LIwVFiazOqjO3ty8KH",
    "exp": 1614792378,
    "sub": "91e65743-aa8c-4a7e-a183-706912c92436"
}

```

- _A token invalid client example response_

```auto
{"active":false}

```

So I think this gives a good overview of this endpoint. Comments welcomed.

Temporary note: I got a jump start on documenting this for comments with the PR going up within a day and in master shortly thereafter. I’ll post back once in master.

---

<div class="post-metadata">

**Author:** ![RachelEllison](https://community.open-emr.org/user_avatar/community.open-emr.org/rachelellison/32/14041_2.png) [@RachelEllison](https://community.open-emr.org/u/RachelEllison)\
**Post date:** [December 7, 2020, 8:16pm UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/17 "2020-12-07T20:16:26Z")

</div>

Hi I’m trying to test out the new API, I see that it requires SSL.

I looked on the instructions and it said to set the baseurl at Administration-\>Globals-\>Connectors-\>'Site Address

> <https://github.com/openemr/openemr/blob/master/API_README.md#authorization>

Did the Site Address field move? I don’t see it in connectors, there’s an eRX site address but I don’t think that’s it.

---

<div class="post-metadata">

**Author:** ![sjpadgett](https://community.open-emr.org/user_avatar/community.open-emr.org/sjpadgett/32/21623_2.png) [@sjpadgett](https://community.open-emr.org/u/sjpadgett)\
**Post date:** [December 8, 2020, 12:41am UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/18 "2020-12-08T00:41:03Z")

</div>

Hi @RachelEllison  
Hope you’re using v6.0.0-dev because this is not a v5.0.2 feature. However,

 ![image](https://discourse-uploads-openemr.s3.dualstack.us-east-1.amazonaws.com/original/2X/e/e211082a5a3fd3dd8e33804ef25c770987762211.png)

also I don’t check for a SSL certificate, yet, but, soon. Still, hit endpoints as https://…

---

<div class="post-metadata">

**Author:** ![RachelEllison](https://community.open-emr.org/user_avatar/community.open-emr.org/rachelellison/32/14041_2.png) [@RachelEllison](https://community.open-emr.org/u/RachelEllison)\
**Post date:** [December 8, 2020, 3:47am UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/19 "2020-12-08T03:47:57Z")

</div>

Hi Jerry,

I am on version 6.0.0-dev

 ![image](https://discourse-uploads-openemr.s3.dualstack.us-east-1.amazonaws.com/original/2X/c/c3b8e14ce9f3e72ef38bf59c1cacdab40809fe2d.png)

The site address textbox is missing in my connectors settings.

 ![image](https://discourse-uploads-openemr.s3.dualstack.us-east-1.amazonaws.com/original/2X/5/565950914fdafcc7d6fba81ac78d071a7c8ebf0d.png)

I tried pasting the the example on the readme without any changes and got the below error.

 ![image](https://discourse-uploads-openemr.s3.dualstack.us-east-1.amazonaws.com/original/2X/8/89e919274a0b60f44dcccb020958de018ae36893.png)

---

<div class="post-metadata">

**Author:** ![sjpadgett](https://community.open-emr.org/user_avatar/community.open-emr.org/sjpadgett/32/21623_2.png) [@sjpadgett](https://community.open-emr.org/u/sjpadgett)\
**Post date:** [December 8, 2020, 3:53am UTC](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450/20 "2020-12-08T03:53:20Z")

</div>

When is the last time u updated your dev version with master as this was added just recently?

[Next page](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450.md?page=2)
