Register new app

Hello!


After creating the app using web ui I am unable to login to swagger url using the client Id and secret.
I get invalid client error:

Kindly suggest if there are any specific scopes should not be selected? In this effort I had selected all the options.

{
“error”: “invalid_client”,
“error_description”: “Client authentication failed”,
“message”: “Client authentication failed”
}

When trying this with Docker image on local machine after providing the client credentials in the Swagger UI it open new window to enter user/pass (I am using the super secret credentials admin/pass) but then it fails to login with Invalid Request

[Sun Nov 19 06:35:11.612530 2023] [php:notice] [pid 213] [client 192.168.65.1:52526] [2023-11-19T06:35:11.612470+00:00] OpenEMR.ERROR: AuthorizationController->oauthAuthorizationFlow() OAuthServerException {"hint":"Check the `patient/appointment.read` scope","message":"The requested scope is invalid, unknown, or malformed","payload":{"error":"invalid_scope","error_description":"The requested scope is invalid, unknown, or malformed","hint":"Check the `patient/appointment.read` scope","message":"The requested scope is invalid, unknown, or malformed"},"trace":"#0 /var/www/localhost/htdocs/openemr/vendor/league/oauth2-server/src/Grant/AbstractGrant.php(322): League\\\\OAuth2\\\\Server\\\\Exception\\\\OAuthServerException::invalidScope()\\n#1 /var/www/localhost/htdocs/openemr/vendor/league/oauth2-server/src/Grant/AuthCodeGrant.php(293): League\\\\OAuth2\\\\Server\\\\Grant\\\\AbstractGrant->validateScopes()\\n#2 /var/www/localhost/htdocs/openemr/src/Common/Auth/OpenIDConnect/Grant/CustomAuthCodeGrant.php(91): League\\\\OAuth2\\\\Server\\\\Grant\\\\AuthCodeGrant->validateAuthorizationRequest()\\n#3 /var/www/localhost/htdocs/openemr/vendor/league/oauth2-server/src/AuthorizationServer.php(163): OpenEMR\\\\Common\\\\Auth\\\\OpenIDConnect\\\\Grant\\\\CustomAuthCodeGrant->validateAuthorizationRequest()\\n#4 /var/www/localhost/htdocs/openemr/src/RestControllers/AuthorizationController.php(504): League\\\\OAuth2\\\\Server\\\\AuthorizationServer->validateAuthorizationRequest()\\n#5 /var/www/localhost/htdocs/openemr/oauth2/authorize.php(86): OpenEMR\\\\RestControllers\\\\AuthorizationController->oauthAuthorizationFlow()\\n#6 {main}","redirectUri":"https://localhost:8443/swagger/oauth2-redirect.html","errorType":"invalid_scope"} [], referer: https://localhost:8443/swagger/
[Sun Nov 19 06:35:27.671022 2023] [php:warn] [pid 214] [client 192.168.65.1:52537] PHP Warning:  Undefined array key "user_id" in /var/www/localhost/htdocs/openemr/src/RestControllers/SMART/SMARTAuthorizationController.php on line 243, referer: https://localhost:8443/oauth2/default/provider/login
[Sun Nov 19 06:35:27.671230 2023] [php:notice] [pid 214] [client 192.168.65.1:52537] [2023-11-19T06:35:27.671081+00:00] OpenEMR.ERROR: SMARTAuthorizationController->patientSelect() Unauthorized call, user has not authenticated [] [], referer: https://localhost:8443/oauth2/default/provider/login
[Sun Nov 19 06:46:51.065897 2023] [php:warn] [pid 221] [client 192.168.65.1:52604] PHP Warning:  Undefined array key "skip_ehr_launch_authorization_flow" in /var/www/localhost/htdocs/openemr/src/Common/Auth/OpenIDConnect/Repositories/ClientRepository.php on line 60, referer: https://localhost:8443/interface/smart/register-app.php
[Sun Nov 19 06:47:18.462876 2023] [php:error] [pid 213] [client 192.168.65.1:52607] PHP Fatal error:  Uncaught TypeError: Cannot access offset of type string on string in /var/www/localhost/htdocs/openemr/src/RestControllers/AuthorizationController.php:267\nStack trace:\n#0 /var/www/localhost/htdocs/openemr/oauth2/authorize.php(119): OpenEMR\\RestControllers\\AuthorizationController->clientRegistration()\n#1 {main}\n  thrown in /var/www/localhost/htdocs/openemr/src/RestControllers/AuthorizationController.php on line 267
[Sun Nov 19 06:47:27.574030 2023] [php:error] [pid 203] [client 192.168.65.1:52608] PHP Fatal error:  Uncaught TypeError: Cannot access offset of type string on string in /var/www/localhost/htdocs/openemr/src/RestControllers/AuthorizationController.php:267\nStack trace:\n#0 /var/www/localhost/htdocs/openemr/oauth2/authorize.php(119): OpenEMR\\RestControllers\\AuthorizationController->clientRegistration()\n#1 {main}\n  thrown in /var/www/localhost/htdocs/openemr/src/RestControllers/AuthorizationController.php on line 267
[Sun Nov 19 06:52:45.637784 2023] [php:warn] [pid 214] [client 192.168.65.1:52640] PHP Warning:  Undefined array key "skip_ehr_launch_authorization_flow" in /var/www/localhost/htdocs/openemr/src/Common/Auth/OpenIDConnect/Repositories/ClientRepository.php on line 60
[Sun Nov 19 06:57:07.487606 2023] [php:notice] [pid 207] [client 192.168.65.1:52666] [2023-11-19T06:57:07.487251+00:00] OpenEMR.ERROR: ScopeRepository->getScopeEntityByIdentifier() request access to invalid scope {"scope":"user/appointment.read","validationScopes":{"nonce":{"description":"Nonce value used to detect replay attacks by third parties"},"openid":{"description":"OpenId Connect"},"fhirUser":{"description":"OpenId Connect"},"online_access":{"description":"OpenId Connect"},"offline_access":{"description":"OpenId Connect"},"launch":{"description":"OpenId Connect"},"launch/patient":{"description":"OpenId Connect"},"api:oemr":{"description":"OpenId Connect"},"api:fhir":{"description":"OpenId Connect"},"api:port":{"description":"OpenId Connect"},"system/Patient.$export":{"description":"OpenId Connect"},"system/Group.$export":{"description":"OpenId Connect"},"system/*.$bulkdata-status":{"description":"OpenId Connect"},"system/*.$export":{"description":"OpenId Connect"},"profile":{"description":"OpenId Connect"},"name":{"description":"OpenId Connect"},"address":{"description":"OpenId Connect"},"given_name":{"description":"OpenId Connect"},"family_name":{"description":"OpenId Connect"},"nickname":{"description":"OpenId Connect"},"phone":{"description":"OpenId Connect"},"phone_verified":{"description":"OpenId Connect"},"email":{"description":"OpenId Connect"},"email_verified":{"description":"OpenId Connect"},"site:default":{"description":"OpenId Connect"},"patient/AllergyIntolerance.read":{"description":"OpenId Connect"},"patient/Appointment.read":{"description":"OpenId Connect"},"patient/Binary.read":{"description":"OpenId Connect"},"patient/CarePlan.read":{"description":"OpenId Connect"},"patient/CareTeam.read":{"description":"OpenId Connect"},"patient/Condition.read":{"description":"OpenId Connect"},"patient/Coverage.read":{"description":"OpenId Connect"},"patient/Device.read":{"description":"OpenId Connect"},"patient/DiagnosticReport.read":{"description":"OpenId Connect"},"patient/DocumentReference.$docref":{"description":"OpenId Connect"},"patient/DocumentReference.read":{"description":"OpenId Connect"},"patient/Encounter.read":{"description":"OpenId Connect"},"patient/Goal.read":{"description":"OpenId Connect"},"patient/Immunization.read":{"description":"OpenId Connect"},"patient/Location.read":{"description":"OpenId Connect"},"patient/Medication.read":{"description":"OpenId Connect"},"patient/MedicationRequest.read":{"description":"OpenId Connect"},"patient/Observation.read":{"description":"OpenId Connect"},"patient/Organization.read":{"description":"OpenId Connect"},"patient/Patient.read":{"description":"OpenId Connect"},"patient/Person.read":{"description":"OpenId Connect"},"patient/Practitioner.read":{"description":"OpenId Connect"},"patient/Procedure.read":{"description":"OpenId Connect"},"patient/Provenance.read":{"description":"OpenId Connect"},"system/AllergyIntolerance.read":{"description":"OpenId Connect"},"system/Appointment.read":{"description":"OpenId Connect"},"system/Binary.read":{"description":"OpenId Connect"},"system/CarePlan.read":{"description":"OpenId Connect"},"system/CareTeam.read":{"description":"OpenId Connect"},"system/Condition.read":{"description":"OpenId Connect"},"system/Coverage.read":{"description":"OpenId Connect"},"system/Device.read":{"description":"OpenId Connect"},"system/DiagnosticReport.read":{"description":"OpenId Connect"},"system/DocumentReference.$docref":{"description":"OpenId Connect"},"system/DocumentReference.read":{"description":"OpenId Connect"},"system/Encounter.read":{"description":"OpenId Connect"},"system/Goal.read":{"description":"OpenId Connect"},"system/Group.read":{"description":"OpenId Connect"},"system/Immunization.read":{"description":"OpenId Connect"},"system/Location.read":{"description":"OpenId Connect"},"system/Medication.read":{"description":"OpenId Connect"},"system/MedicationRequest.read":{"description":"OpenId Connect"},"system/Observation.read":{"description":"OpenId Connect"},"system/Organization.read":{"description":"OpenId Connect"},"system/Patient.read":{"description":"OpenId Connect"},"system/Person.read":{"description":"OpenId Connect"},"system/Practitioner.read":{"description":"OpenId Connect"},"system/PractitionerRole.read":{"description":"OpenId Connect"},"system/Procedure.read":{"description":"OpenId Connect"},"system/Provenance.read":{"description":"OpenId Connect"},"user/AllergyIntolerance.read":{"description":"OpenId Connect"},"user/Appointment.read":{"description":"OpenId Connect"},"user/Binary.read":{"description":"OpenId Connect"},"user/CarePlan.read":{"description":"OpenId Connect"},"user/CareTeam.read":{"description":"OpenId Connect"},"user/Condition.read":{"description":"OpenId Connect"},"user/Coverage.read":{"description":"OpenId Connect"},"user/Device.read":{"description":"OpenId Connect"},"user/DiagnosticReport.read":{"description":"OpenId Connect"},"user/DocumentReference.$docref":{"description":"OpenId Connect"},"user/DocumentReference.read":{"description":"OpenId Connect"},"user/Encounter.read":{"description":"OpenId Connect"},"user/Goal.read":{"description":"OpenId Connect"},"user/Immunization.read":{"description":"OpenId Connect"},"user/Location.read":{"description":"OpenId Connect"},"user/Medication.read":{"description":"OpenId Connect"},"user/MedicationRequest.read":{"description":"OpenId Connect"},"user/Observation.read":{"description":"OpenId Connect"},"user/Organization.read":{"description":"OpenId Connect"},"user/Organization.write":{"description":"OpenId Connect"},"user/Patient.read":{"description":"OpenId Connect"},"user/Patient.write":{"description":"OpenId Connect"},"user/Person.read":{"description":"OpenId Connect"},"user/Practitioner.read":{"description":"OpenId Connect"},"user/Practitioner.write":{"description":"OpenId Connect"},"user/PractitionerRole.read":{"description":"OpenId Connect"},"user/Procedure.read":{"description":"OpenId Connect"},"user/Provenance.read":{"description":"OpenId Connect"}}} [], referer: https://localhost:8443/swagger/







[Sun Nov 19 06:57:07.487822 2023] [php:notice] [pid 207] [client 192.168.65.1:52666] [2023-11-19T06:57:07.487776+00:00] OpenEMR.ERROR: AuthorizationController->oauthAuthorizationFlow() OAuthServerException {"hint":"Check the `user/appointment.read` scope","message":"The requested scope is invalid, unknown, or malformed","payload":{"error":"invalid_scope","error_description":"The requested scope is invalid, unknown, or malformed","hint":"Check the `user/appointment.read` scope","message":"The requested scope is invalid, unknown, or malformed"},"trace":"#0 /var/www/localhost/htdocs/openemr/vendor/league/oauth2-server/src/Grant/AbstractGrant.php(322): League\\\\OAuth2\\\\Server\\\\Exception\\\\OAuthServerException::invalidScope()\\n#1 /var/www/localhost/htdocs/openemr/vendor/league/oauth2-server/src/Grant/AuthCodeGrant.php(293): League\\\\OAuth2\\\\Server\\\\Grant\\\\AbstractGrant->validateScopes()\\n#2 /var/www/localhost/htdocs/openemr/src/Common/Auth/OpenIDConnect/Grant/CustomAuthCodeGrant.php(91): League\\\\OAuth2\\\\Server\\\\Grant\\\\AuthCodeGrant->validateAuthorizationRequest()\\n#3 /var/www/localhost/htdocs/openemr/vendor/league/oauth2-server/src/AuthorizationServer.php(163): OpenEMR\\\\Common\\\\Auth\\\\OpenIDConnect\\\\Grant\\\\CustomAuthCodeGrant->validateAuthorizationRequest()\\n#4 /var/www/localhost/htdocs/openemr/src/RestControllers/AuthorizationController.php(504): League\\\\OAuth2\\\\Server\\\\AuthorizationServer->validateAuthorizationRequest()\\n#5 /var/www/localhost/htdocs/openemr/oauth2/authorize.php(86): OpenEMR\\\\RestControllers\\\\AuthorizationController->oauthAuthorizationFlow()\\n#6 {main}","redirectUri":"https://localhost:8443/swagger/oauth2-redirect.html","errorType":"invalid_scope"} [], referer: https://localhost:8443/swagger/
[Sun Nov 19 06:58:53.318015 2023] [php:warn] [pid 214] [client 192.168.65.1:52690] PHP Warning:  Undefined array key "user_id" in /var/www/localhost/htdocs/openemr/src/RestControllers/SMART/SMARTAuthorizationController.php on line 243, referer: https://localhost:8443/oauth2/default/provider/login
[Sun Nov 19 06:58:53.318200 2023] [php:notice] [pid 214] [client 192.168.65.1:52690] [2023-11-19T06:58:53.318067+00:00] OpenEMR.ERROR: SMARTAuthorizationController->patientSelect() Unauthorized call, user has not authenticated [] [], referer: https://localhost:8443/oauth2/default/provider/login

Hi @chaudhariatul ,
Try to check whether all the scopes are selected before registering the app and while authorizing the swagger.

From the error screenshot that you have shared, its showing the user/appointment.read and patient/appointment.read scopes are missing. Check whether the respective scopes are checked.
After checking this process, try to login using openemr credentials .

After providing the username and password, click openemr login button and you will be able to view the patient selection list.
If you encounter further issues, do drop a mail to openemr.support@visolve.com

-ViSolve AI Team

Looks like you are running into the problem of using standard api scopes but registering an application using the GUI that only supports FHIR api scopes. If you want to test standard api you need to register your application using the oidc app registration call.

You can read more about the issue here: feat: Update OpenEMR App Registration Page to support standard api scopes · Issue #6999 · openemr/openemr · GitHub

Hi Stephen, ViSolve team,

Thank you for the replies and references.


I was later able to register a new app and request new token using the APIs

Here is the sample code I used in JupterNotebook


import requests
import json

emr_config = {
    "emr_host":"ten.openemr.io/e/openemr",
    "client_name": "Appointment Reminder",
    "contact": "noname@example.com",
    "scope": 'openid offline_access launch/patient api:fhir ' +
      'patient/AllergyIntolerance.read patient/Appointment.read ' +
      'patient/Binary.read patient/CarePlan.read patient/CareTeam.read ' +
      'patient/Condition.read patient/Coverage.read patient/Device.read ' +
      'patient/DiagnosticReport.read patient/DocumentReference.read ' +
      'patient/DocumentReference.$docref patient/Encounter.read ' +
      'patient/Goal.read patient/Immunization.read patient/Location.read ' +
      'patient/Medication.read patient/MedicationRequest.read ' +
      'patient/Observation.read patient/Organization.read ' +
      'patient/Patient.read patient/Person.read patient/Practitioner.read ' +
      'patient/Procedure.read patient/Provenance.read ' +
      'user/Binary.read user/CarePlan.read user/CareTeam.read user/Condition.read ' +
      'user/Coverage.read user/Device.read user/DiagnosticReport.read ' +
      'user/DocumentReference.read user/DocumentReference.$docref ' +
      'user/Encounter.read user/Goal.read user/Immunization.read ' +
      'user/Location.read user/Medication.read user/MedicationRequest.read ' +
      'user/Observation.read user/Organization.read user/Organization.write ' +
      'user/Patient.read user/Patient.write user/Person.read ' +
      'user/Practitioner.read user/Practitioner.write user/PractitionerRole.read ' +
      'user/Procedure.read user/Provenance.read'
}

reqUrl = f"https://{emr_config['emr_host']}/oauth2/default/registration"

headersList = {"Content-Type": "application/json"}

payload = json.dumps(
  {
    "application_type": "private",
    "redirect_uris": [f"https://{emr_config['emr_host']}/swagger/oauth2-redirect.html"],
    "initiate_login_uri": f"https://{emr_config['emr_host']}/swagger/index.html",
    "post_logout_redirect_uris": [""],
    "client_name": "TestApp",
    "token_endpoint_auth_method": "client_secret_post",
    "contacts": ["user@example.com"],
    "scope": emr_config['scope']
  }
)

response = requests.request("POST", reqUrl, data=payload,  headers=headersList)

client_app = response.json()

# Print client app details
client_app

Going through some steps as described in documentation and the training video on YT it helped to run tests in SwaggerUI

Thank you for your support!

Happy Thanksgiving!