Cannot get Access Token

1,131 views
Skip to first unread message
Assigned to Fenil....@cerner.com by me

Roshaan Rasool

unread,
Jul 8, 2021, 7:50:41 PM7/8/21
to Cerner FHIR Developers
Hello, I am trying to get the Access token but I am getting a "read ECONNRESET" error. I was successfully able to get the code. When I try to pass the code via the API call to the /token URL, I am getting the "read ECONNRESET" error. 

I am following this step mentioned in the documentation:

POST /tenants/ec2458f2-1e24-41c8-b71b-0e701af7583d/protocols/oauth2/profiles/smart-v1/token HTTP/1.1 Host: authorization.cerner.com Accept: application/json Content-Type: application/x-www-form-urlencoded Content-Length: 75 Connection: close grant_type=refresh_token&refresh_token=b30911a8-9278-45aa-bbd9-aa05244faf

My credentials and code is correct. This is the piece of code I am using to make the API call to get the access token:

request({
    method: 'POST',
    headers: {
        Accept: 'application/json',
        'content-type' : 'application/x-www-form-urlencoded',
         Authorization: 'Basic ' + self.config.creds.client_id
     },
     form: {
          code: code,
          grant_type: 'authorization_code',
          client_id: self.config.creds.client_id,
          state: 'a4c16a46-2c46-482c-8d66-4cc4a2990bda'
     }
}


I have been stuck at this point for a while. Please help!

Thanks,

Sean Nolan

unread,
Jul 9, 2021, 2:32:44 AM7/9/21
to Cerner FHIR Developers
A few things I see: (1) your Authorization header is missing the client secret. If you don't have a secret (i.e., aren't requesting a refresh token) then you don't need to send the Authorization header at all --- but if you do send it, it needs to be properly formatted with the client id and secret; (2) you don't have the redirect_uri in the form; (3) you have the state in the form which is not needed in the token call, not sure if that would cause a failure or just be ignored.

Some code that manages these values correctly wrt Cerner is here and can be used for reference as well: https://github.com/seanno/shutdownhook/blob/main/smart-trials/src/main/java/com/shutdownhook/smart/SmartEhr.java#L240

Hope that helps!
---S

Fenil Desani (Cerner)

unread,
Jul 12, 2021, 1:18:48 PM7/12/21
to Cerner FHIR Developers
Hello,

What type of App are you using? Is it a System App, Provider App, or Patient App?
Are you trying to fetch the initial Bearer token or a refresh token?

Thank you,
Fenil (Cerner)

Roshaan Rasool

unread,
Jul 12, 2021, 5:15:10 PM7/12/21
to Cerner FHIR Developers
Hello Fenil,
I am using a Provider App. Also, I am trying to fetch the initial Bearer Token, so that I can capture the patient data via a GET call.

Thanks,

Roshaan Rasool

unread,
Jul 12, 2021, 5:17:47 PM7/12/21
to Cerner FHIR Developers
Thank you for the suggestions. I have tried your suggestions, but I am still getting the same result. This is my POST call:

request({
    method: 'POST',
    headers: {
        Accept: 'application/json',
        'content-type' : 'application/x-www-form-urlencoded',
        Authorization: 'Basic ' + self.config.creds.client_id + self.config.creds.clientSecret
    },
    form: {
        code: code,
        redirect_uri: self.config.authorization_uri.redirect_uri,
        grant_type: 'authorization_code',
        clientID: self.config.creds.client_id,
     }

Thanks,

Fenil Desani (Cerner)

unread,
Jul 12, 2021, 5:55:33 PM7/12/21
to Cerner FHIR Developers
You don't need to use the Basic Authorization Workflow for Provider Apps.
Remove Authorization header and try.



Roshaan Rasool

unread,
Jul 12, 2021, 6:22:55 PM7/12/21
to Cerner FHIR Developers
I have tried to make a POST call like this:

request({
    method: 'POST',
    headers: {
        Accept: 'application/json',
        'content-type' : 'application/x-www-form-urlencoded',
    },
    form: {
        code: code,
        redirect_uri: self.config.authorization_uri.redirect_uri,
        grant_type: 'authorization_code',
        clientID: self.config.creds.client_id,
}




and I got the response:

{"statusCode":401,"body":"{\"error\":\"invalid_client\",\"error_uri\":\"https://authorization.cerner.com/errors/urn%3Acerner%3Aerror%3Aauthorization-server%3Aoauth2%3Atoken%3Ainvalid-authorization-header/instances/b47649b4-b29c-48f3-afea-f4ce68fb85d0?tenant=ec2458f2-1e24-41c8-b71b-0e701af7583d\"}","headers":{"expect-ct":"enforce, max-age=30","www-authenticate":"Basic realm=\"CernerCare\"","access-control-allow-origin":"*","access-control-allow-methods":"OPTIONS, POST","access-control-allow-headers":"Content-Type, Authorization, Accept, Cerner-Correlation-Id","cache-control":"no-store","pragma":"no-cache","cerner-correlation-id":"b47649b4-b29c-48f3-afea-f4ce68fb85d0","content-type":"application/json;charset=UTF-8","content-length":"263","date":"Mon, 12 Jul 2021 22:18:10 GMT","server":"cloud_authorization_server1","connection":"close","strict-transport-security":"max-age=631138519; includeSubDomains"},"request":{"uri":{"protocol":"https:","slashes":true,"auth":null,"host":"authorization.cerner.com","port":443,"hostname":"authorization.cerner.com","hash":null,"search":null,"query":null,"pathname":"/tenants/ec2458f2-1e24-41c8-b71b-0e701af7583d/protocols/oauth2/profiles/smart-v1/token","path":"/tenants/ec2458f2-1e24-41c8-b71b-0e701af7583d/protocols/oauth2/profiles/smart-v1/token","href":"https://authorization.cerner.com/tenants/ec2458f2-1e24-41c8-b71b-0e701af7583d/protocols/oauth2/profiles/smart-v1/token"},"method":"POST","headers":{"Accept":"application/json","content-type":"application/x-www-form-urlencoded","content-length":177}}}


Sean Nolan

unread,
Jul 13, 2021, 4:29:21 AM7/13/21
to cerner-fhir...@googlegroups.com

Roshaan, as the other responder said it may be the case that you don’t need the Authorization header, but if you’ve configured to receive a refresh token I think you probably do … and in that case, your format is still not quite right. The format of the authorization header is “Basic “ + the base 64 encoding of the string formed by concatenating the client id, a “:” and the client secret. See example code here: https://github.com/seanno/shutdownhook/blob/v1/toolbox/src/main/java/com/shutdownhook/toolbox/WebRequests.java#L92 and the spec here: https://hl7.org/fhir/smart-app-launch/basic-auth-example/index.html

 

Let us know how it goes!

---S

--
You received this message because you are subscribed to a topic in the Google Groups "Cerner FHIR Developers" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/cerner-fhir-developers/M0N6BBTTJnA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to cerner-fhir-devel...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/cerner-fhir-developers/964b78a1-dfc3-47b6-a473-fc10ceaade6cn%40googlegroups.com.

Message has been deleted

Fenil Desani (Cerner)

unread,
Jul 13, 2021, 2:45:14 PM7/13/21
to Cerner FHIR Developers
Roshaan, 

I have deleted your previous comment as it violated group policy for posting security credentials.
  • Do NOT post your OAuth Bearer token or other security credentials on this group.

Couple of questions I had,
  • Why would you use a System Account for Provider Application?
  • Why would you mark your App as confidential? [1]



Sean,
For Provider Applications we only support online _access refresh token and not offline_access token [2], thereby not requiring Client credentials.


NOTE: Cerner’s authorization server currently does not support the stand-alone “openid” workflow for patients and/or their authorized representatives, nor does it support “offline_access” for providers at this time.

Roshaan Rasool

unread,
Jul 15, 2021, 1:02:07 PM7/15/21
to Cerner FHIR Developers
Hello Fenil,

  • Why would you use a System Account for Provider Application?
            I followed the step by step guide instructed on http://fhir.cerner.com/authorization/. I am not sure if we need a System account for a providers app? If not, how will we get the ClientID and ClientSecret? 



Also, there has been some development. I was able to get the Access Token once via the API call, but I tried the same API call after some time and it is giving me this error:

{"error":"invalid_grant","error_uri":"https://authorization.cerner.com/errors/urn%3Acerner%3Aerror%3Aauthorization-server%3Aoauth2%3Atoken%3Acode-invalid-or-expired/instances/e3dcc972-486f-446d-b808-262dd206a091?tenant=ec2458f2-1e24-41c8-b71b-0e701af7583d","expires_at":"20210715T12:46:50"}


I know that code is not reusable and it has expired, but I am making a new set of API calls which are in this order:

  1. Getting the authorization & token endpoints by making a call (Conformance (DSTU2))
  2. Making the authorization call to get the code by passing the clientID
  3. Passing that code along with the clientID and clientSecret to get the access token

I was successfully able to get the access token once by following these steps, but when I try to follow these steps again, with the same script, I am getting the "invalid grant" error. 
Any idea if I need to change anything? I am getting a new code every time, how can that expire? Or is there another way to get the new code?

Thanks,
Roshaan


Reply all
Reply to author
Forward
0 new messages