# How to configure OpenEMR 6.x with Keycloak (or any OAuth2 server)

**URL:** <https://community.open-emr.org/t/how-to-configure-openemr-6-x-with-keycloak-or-any-oauth2-server/15805>\
**Category:** Help Wanted\
**Tags:** question, installation\
**Created:** [January 16, 2021, 10:02am UTC](https://community.open-emr.org/t/how-to-configure-openemr-6-x-with-keycloak-or-any-oauth2-server/15805 "2021-01-16T10:02:40Z")\
**Posts on this page:** 12\
**Page:** 2

<div class="post-metadata">

**Author:** ![benmarte](https://community.open-emr.org/user_avatar/community.open-emr.org/benmarte/32/15117_2.png) [@benmarte](https://community.open-emr.org/u/benmarte)\
**Post date:** [January 20, 2021, 2:16pm UTC](https://community.open-emr.org/t/how-to-configure-openemr-6-x-with-keycloak-or-any-oauth2-server/15805/22 "2021-01-20T14:16:32Z")

</div>

I think the docs might be missing the Authorize section example based on what was posted here: [V6 Authorization and API changes afoot](https://community.open-emr.org/t/v6-authorization-and-api-changes-afoot/15450)

1. You do a registration request to: `https://localhost/oauth2/default/registration`
2. Next step is to authorize to: `https://localhost/openemrv6/oauth2/default/authorize`

The [API docs](https://github.com/openemr/openemr/blob/master/API_README.md#authorization-code-grant) says to use this url: `https://localhost/oauth2/default` and no example.

So I registered the admin account as an API client that worked fine.  
I then proceed to authorize the client via a GET/POST to: `https://localhost:443/oauth2/default/authorize` using these params:

```auto
{
    "client_id": "UIy5NV9K53pYus35IbXGjVuYzQOUXIDQzmF3YocU7Zs",
    "response_type": "code",
    "client_id": "LnjqojEEjFYe5j2Jp9m9UnmuxOnMg4VodEJj3yE8_OA",
    "state": "a85b870548dd8880ddb7c3192439f468fe63396f",
    "scope": "openid api:oemr api:fhir api:port api:pofh",
    "redirect_uri": "https://localhost:443"
}

```

And this is the result:

```auto
<br />
<b>Notice</b>: Key file "file:///var/www/localhost/htdocs/openemr/sites/default/documents/certificates/oaprivate.key" permissions are not correct, recommend changing to 600 or 660 instead of 700 in <b>/var/www/localhost/htdocs/openemr/vendor/league/oauth2-server/src/CryptKey.php</b> on line <b>63</b><br />
{
    "error": "unsupported_grant_type",
    "error_description": "The authorization grant type is not supported by the authorization server.",
    "hint": "Check that all required parameters have been provided",
    "message": "The authorization grant type is not supported by the authorization server."
}

```

Changing permissions on that file does nothing, this is where I’m stuck at the moment so I’m not sure if it’s something I’m doing wrong or missing info in the API docs.

I’ve changed `response_type` to every response type supported based on: `https://localhost/oauth2/default/.well-known/openid-configuration` and get the same error.

Using the endpoint in the API docs `https://localhost:443/oauth2/default` doesn’t return anything but a 200 ok with an empty body.

I’m just looking to be able to use the API with the user accounts created in OEMR like it was prior to V6 since I’m just using OEMR as the backend of my app.

Thanks.

---

<div class="post-metadata">

**Author:** ![benmarte](https://community.open-emr.org/user_avatar/community.open-emr.org/benmarte/32/15117_2.png) [@benmarte](https://community.open-emr.org/u/benmarte)\
**Post date:** [January 20, 2021, 3:56pm UTC](https://community.open-emr.org/t/how-to-configure-openemr-6-x-with-keycloak-or-any-oauth2-server/15805/23 "2021-01-20T15:56:01Z")

</div>

A bit of progress so far here’s what I’ve done:

- Enabled REST API in Admin \> Connectors
- Added Site Address: [https://localhost:443](https://localhost:443)
- Enabled Client SSL under Admin \> Security (not sure if necessary)
- Enabled OAuth2 Password Grant to: On for Both Roles
- Registered my admin account as an API Client via postman on: `https://localhost:443/oauth2/default/registration`  
with the following:

```auto
{
    "application_type": "private",
   "redirect_uris": ["https://localhost:443"],
    "initiate_login_uri": "https://localhost:443",
   "client_name": "admin-account",
   "token_endpoint_auth_method": "client_secret_post",
   "username": "admin",
   "password": "pass",
   "scope": "openid api:oemr api:fhir api:port api:pofh"
}

```

- Enabled Client under Administration \> System \> API Clients
- Proceeded to refresh/authorize the client on: `https://localhost:443/oauth2/default/token` with the following urlencoded data:

```auto
client_id:xtk0UuP446AneUfZs5nchUn_iCQX-yV92Sh_GI8aDMQ
grant_type:password
user_role:users
scope:openid api:oemr api:fhir api:port api:pofh
username:admin
password:pass

```

- Used the access token from the previous request as the Bearer token for my next request to: `https://localhost:443/apis/default/api/facility` which then returns:

```auto
{
    "error": "access_denied",
    "error_description": "The resource owner or authorization server denied the request.",
    "hint": "Error while decoding from JSON",
    "message": "The resource owner or authorization server denied the request."
}

```

That’s as far as I’ve gotten.

---

<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:** [January 20, 2021, 8:35pm UTC](https://community.open-emr.org/t/how-to-configure-openemr-6-x-with-keycloak-or-any-oauth2-server/15805/24 "2021-01-20T20:35:38Z")

</div>

Hi,

Regarding the Authorization Code Grant, that is done via a oauth2 standard flow. That’s why the instructions are minimal (ie. use a oauth2 client, which I detailed an example of using one in the 4 steps several posts above) since there is a standardized process/flow for this (can learn about via google).

Regarding your password grant, just need to include the needed scopes in your scope on the client registration and password grant request. For example, the `user/facility.read` scope will get your call to [https://localhost:443/apis/default/api/facility](https://localhost:443/apis/default/api/facility) to work.

---

<div class="post-metadata">

**Author:** ![benmarte](https://community.open-emr.org/user_avatar/community.open-emr.org/benmarte/32/15117_2.png) [@benmarte](https://community.open-emr.org/u/benmarte)\
**Post date:** [January 21, 2021, 1:05pm UTC](https://community.open-emr.org/t/how-to-configure-openemr-6-x-with-keycloak-or-any-oauth2-server/15805/25 "2021-01-21T13:05:21Z")

</div>

I was under the assumption that using `api:oemr` could grant access to all scopes under it the same for `api:fhir` etc. is that not the case?

I can register fine with all scopes but when I try to refresh the token with all scopes I get an invalid scope error.

```auto
<br />
<b>Notice</b>: Key file "file:///var/www/localhost/htdocs/openemr/sites/default/documents/certificates/oaprivate.key" permissions are not correct, recommend changing to 600 or 660 instead of 700 in <b>/var/www/localhost/htdocs/openemr/vendor/league/oauth2-server/src/CryptKey.php</b> on line <b>63</b><br />
{
    "error": "invalid_scope",
    "error_description": "The requested scope is invalid, unknown, or malformed",
    "hint": "Check the `user/Coverage.read` scope",
    "message": "The requested scope is invalid, unknown, or malformed"
}

```

I’ve tried escaping `/` and periods but no matter what I always get this error when trying to refresh the token.

Thanks for your help and patience 🙏

---

<div class="post-metadata">

**Author:** ![david.ouagne](https://community.open-emr.org/letter_avatar_proxy/v4/letter/d/6bbea6/32.png) [@david.ouagne](https://community.open-emr.org/u/david.ouagne)\
**Post date:** [January 21, 2021, 1:12pm UTC](https://community.open-emr.org/t/how-to-configure-openemr-6-x-with-keycloak-or-any-oauth2-server/15805/26 "2021-01-21T13:12:59Z")

</div>

Hi,

From experience, the scope of the resource must be clearly specified at the time of registering and authorize. In your example, add user/Coverage.read to your scope.

I hope this will help you,

Regards,

---

<div class="post-metadata">

**Author:** ![benmarte](https://community.open-emr.org/user_avatar/community.open-emr.org/benmarte/32/15117_2.png) [@benmarte](https://community.open-emr.org/u/benmarte)\
**Post date:** [January 21, 2021, 1:23pm UTC](https://community.open-emr.org/t/how-to-configure-openemr-6-x-with-keycloak-or-any-oauth2-server/15805/27 "2021-01-21T13:23:23Z")

</div>

Yeah I removed it from the scope and it worked maybe it was no included in the register phase 🤔 thanks.

It definitely was in the registration scope, weird anyways progress now to see if I can get this working, thanks again.

---

<div class="post-metadata">

**Author:** ![nicole16](https://community.open-emr.org/user_avatar/community.open-emr.org/nicole16/32/17808_2.png) [@nicole16](https://community.open-emr.org/u/nicole16)\
**Post date:** [January 21, 2021, 1:40pm UTC](https://community.open-emr.org/t/how-to-configure-openemr-6-x-with-keycloak-or-any-oauth2-server/15805/28 "2021-01-21T13:40:33Z")

</div>

Hi there,

I can surely help with what all you need.

Reach me at nicole(at)cisinlabs(com)

With regards,  
Nciole

---

<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:** [January 22, 2021, 7:12am UTC](https://community.open-emr.org/t/how-to-configure-openemr-6-x-with-keycloak-or-any-oauth2-server/15805/29 "2021-01-22T07:12:16Z")

</div>

Hi @benmarte ,  
The `user/Coverage.read` scope is only in master (ie. dev version) since it was just recently added. If you are using 6.0.0, then it will fail if try to use that scope since it does not exist there. If doing shotgun approach on scopes (ie. including them all) while getting them to work and testing them out, then would use the listing of scopes in the API\_README.md file included in the instance you are running from to avoid trying to use scopes that do not yet exists there.

---

<div class="post-metadata">

**Author:** ![benmarte](https://community.open-emr.org/user_avatar/community.open-emr.org/benmarte/32/15117_2.png) [@benmarte](https://community.open-emr.org/u/benmarte)\
**Post date:** [January 26, 2021, 10:23pm UTC](https://community.open-emr.org/t/how-to-configure-openemr-6-x-with-keycloak-or-any-oauth2-server/15805/30 "2021-01-26T22:23:05Z")

</div>

Ok, so I decided to write down a blog post for any other poor soul trying to use the new Open EMR Auth flows, specifically the Password Grant flow.

Check it out here and let me know what can be improved or is wrong so I can fix it, thank you everyone for your help 🙏

[https://benmarte.com/blog/openemr-api-v6/](https://benmarte.com/blog/openemr-api-v6/)

---

<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:** [January 27, 2021, 5:47pm UTC](https://community.open-emr.org/t/how-to-configure-openemr-6-x-with-keycloak-or-any-oauth2-server/15805/31 "2021-01-27T17:47:24Z")

</div>

@benmarte ,

Very cool stuff! Only 2 things I noted:

1. https is required for oauth/api to work (when set the **Site Address** in globals)
2. The **Activating your API Client** is not needed in this setting (it will work without doing this; this is only pertinent for use of SMART app use)

---

<div class="post-metadata">

**Author:** ![fredrpa708](https://community.open-emr.org/letter_avatar_proxy/v4/letter/f/e0b2c6/32.png) [@fredrpa708](https://community.open-emr.org/u/fredrpa708)\
**Post date:** [March 3, 2022, 10:11pm UTC](https://community.open-emr.org/t/how-to-configure-openemr-6-x-with-keycloak-or-any-oauth2-server/15805/32 "2022-03-03T22:11:48Z")

</div>

Benjamin, Poor Soul here! Very helpful! I followed your instructions and I’m getting an error unsupported grant type? And unable to get the token response. Any thoughts I’m passing in “password” into the value.  
Cheers

---

<div class="post-metadata">

**Author:** ![fredrpa708](https://community.open-emr.org/letter_avatar_proxy/v4/letter/f/e0b2c6/32.png) [@fredrpa708](https://community.open-emr.org/u/fredrpa708)\
**Post date:** [March 4, 2022, 12:11pm UTC](https://community.open-emr.org/t/how-to-configure-openemr-6-x-with-keycloak-or-any-oauth2-server/15805/33 "2022-03-04T12:11:39Z")

</div>

I missed the small print - Use Both Roles.

[Previous page](https://community.open-emr.org/t/how-to-configure-openemr-6-x-with-keycloak-or-any-oauth2-server/15805.md?page=1)
