This article is for teams responsible for implementing JWT services in organizations. It describes how to build a JWT endpoint to work with the Support SDK for mobile applications to authenticate users in Zendesk Support.
When integrating the Support SDK in a mobile application, the SDK can be configured to authenticate an application user in Zendesk Support. If this option is chosen, Zendesk needs to call a custom endpoint provided by your organization to authenticate the user.
Your dedicated custom endpoint must accept a unique user identifier and return a JWT. Zendesk will send a unique user identifier supplied by the mobile app to the endpoint. In turn, your service should look up the id, confirm that the user is known and trusted, and respond with a JWT payload.
Libraries for implementing JWT services are available for most modern languages. Zendesk Support provides a number of JWT endpoint code examples for different stacks on Github. Though geared for SSO sign-ins, you can replace and refactor the sign-in redirect in the examples with an HTTP response containing a JWT payload.
The unique user identifier is supplied to Zendesk by the mobile application. The developers of the mobile app are responsible for providing identifier values that are supported by your custom endpoint. The user identifier is a string and has no format restrictions.
Topics covered in this article:
Building the endpoint
After getting a unique identifier from your organization's mobile application, the Zendesk Support service will send it in a request to your dedicated JWT endpoint. The Zendesk Support service will expect a response containing a JWT token confirming that the user is known and trusted. See the request and response formats below.
A Zendesk Support administrator in your organization should provide you with the shared secret to sign the JWT token. See JSON web token response below.
After building the endpoint, provide the endpoint URL to the Support administrator. The admin needs the URL to finish configuring the SDK in the Support account.
If the administrator is unsure where to add the URL, it should be entered in the JWT URL field on the Setup page at Admin > Channels > Mobile SDK in the admin interface. JWT should be selected as the authentication method to view the field.
Here's the authentication flow (enlarge):
Request format
The Zendesk Support service will make a POST
request with the following format to the JWT endpoint:
POST {your_service_uri}
user_token={user_identifier_provided_by_the_app}
Response format
The Zendesk Support service expects the following response format:
200 OK
{
"jwt": "{your_jwt_token_response}"
}
If the user identifier the Zendesk Support service sends to the JWT endpoint is not known or trusted, a HTTP 401 Unauthorized
response should be returned to the Zendesk Support service.
JSON web token response
A Zendesk Support admin should provide you with the shared secret. If not, refer the admin to Setting up the SDK in the Zendesk Support Help Center. Use the secret to generate the encrypted string for the JWS signature.
Note: You must use the HMAC with SHA-256 (HS256) algorithm for signing. The RSA signature with SHA-256 (RS256) algorithm is not supported.
The following token properties are required:
name
email
jti
iat
- The JWT will be rejected if any of the properties is missing or empty
- The keys must be lower case
- The
email
andname
values are case-sensitive in Zendesk Support iat
must be a whole number in seconds
Troubleshooting your JWT implementation
If your JWT implementation doesn't work as expected, try the following troubleshooting steps:
- Make sure you're not using SSO JWT
- Check the app settings in Zendesk Support
- Check your initialization code
- Test your JWT endpoint
- Verify the JWT payload
- Verify the shared secret
- Check your SSL certificates
Make sure you're not using SSO JWT
The Support SDK JWT is not the same as Zendesk Support SSO JWT. You must build a dedicated JWT endpoint for the Support SDK, as described above. If you use a JWT library to generate your JWT tokens, make sure you replace the sign-in redirect with an HTTP response.
Check the app settings in Zendesk Support
You need to sign in as a Zendesk Support admin, or ask a Zendesk Support admin in your organization to check the app settings in Zendesk Support for you.
-
In the Zendesk Support agent interface, click the Admin icon in the sidebar, then select Channels > Mobile SDK.
-
Verify the following settings:
Notes:
- Authentication method must be JWT
- JWT URL is an endpoint that you must build specifically for the mobile SDK. It's not your Zendesk Support SSO JWT endpoint (if your organization has one)
- JWT Secret is a secret that your service uses to sign the JWT token that it sends to the Zendesk Support service. The secret is shown in its entirety only once, when the app is set up. Make sure you don't use the redacted version
Check your initialization code
In your app code, make sure the identity is set after the initialization code. Example:
Zendesk.initialize(appId: "1e41a02a5f85d58e009ed4fa",
clientId: "mobile_sdk_client_e1c4e6262f1d02f43496",
zendeskUrl: "https://omniwear.zendesk.com")
let identity = Identity.createJwt(token: "unique_db_user_identifier")
Zendesk.instance?.setIdentity(identity)
Test your JWT endpoint
Use cURL to make requests to the endpoint. You'll need a valid user identifier. For example, if your endpoint is https://example.com/services/jwt
and the user identifier is BD2F35A7621
, use the following cURL statement:
curl "https://example.com/services/jwt" -d "user_token=BD2F35A7621" -v -X POST
The Zendesk Support service expects a very specific response from your service and is strict about it. The response must:
- Return a 200 response code for success, no exceptions. Redirects will not be followed
- Return a JWT payload
- Be signed with the shared key using the HS256 algorithm
Example response:
Formatted for clarity, the JWT token value should look as follows:
{
"jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6ImJ
jYXJyb2xsQHplbmRlc2suY29tIiwibmFtZSI6ImJjYXJyb2xsIiw
icGhvbmUiOiI5ODc2NTQzMjM0NTY3ODkiLCJ0YWdzIjpbImZyZWV
fcGxheWVyIiwiYmlnX2Zpc2giXSwicm9sZSI6InVzZXIiLCJpYXQ
iOjE0NDkzNTUxNjIsImp0aSI6IjIxMTUyMzc5MDcyMDg5MzEyMjc
ifQ.b_0rr6_1MWrmKEzqMfvf_DI4dPPMSmDjKh_M6STIIas"
}
If your service returns something that looks like a JWT token and a 200 response code, then it's time to check the payload itself.
Verify the JWT payload
Paste the JWT token from your cURL request into the decoder at https://jwt.io. Make sure to select the HS256 algorithm for the decoder. The decoded data appears on the right side as soon as you paste the token.
The decoded payload data must contain the following properties:
- name
- jti
- iat
The JWT will be rejected if any property is missing or empty.
The keys must be lower case.
iat
must be a whole number in seconds.
Everything else is optional.
Example:
Verify the shared secret
JWT relies on a shared secret to verify the JWT payload. Make sure the secret in your JWT service is longer than nine characters.
A Zendesk Support admin in your organization might have provided you with a nine-character secret. This is a redacted version of the secret displayed in the Zendesk Support admin interface. Ask your Zendesk Support admin to regenerate the secret in the app's settings in Zendesk Support, and then update your JWT service with the new secret.
Check your SSL certificate
Zendesk won't connect to your JWT endpoint if there are issues with a SSL certificate. You can check this by running the following command, where example.com is the domain of your endpoint:
openssl s_client -connect example.com:443
If the output looks like the following, it means that some certificate in the chain has failed validation:
depth=0 /OU=Domain Control Validated/OU=Free SSL/CN=example.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 /OU=Domain Control Validated/OU=Free SSL/CN=example.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 /OU=Domain Control Validated/OU=Free SSL/CN=example.com
verify error:num=21:unable to verify the first certificate
verify return:1
19 Comments
According to the above steps , now I can test our JWT endpoint, the result same as the picture , return 200 and the result with "jwt" data. but when I call the zenDesk related api on android mobile, the zenDesk log hint 401 and return "{"error":"Couldn't authenticate you"}".
Please give me some hints how to solve this issue?
I have the same problem as candiceyang
Any updates?
@Eugene, you may want to confirm that you're passing over the required attributes for logging in as mentioned here: https://develop.zendesk.com/hc/en-us/articles/360001075248-Building-a-dedicated-JWT-endpoint-for-the-Support-SDK
It may also be worth testing with another user account to see if that resolves the issue.
Hope this points you in the right direction!
This isn't secure though if I open an endpoint to get user information and return it without authentication of the requester. Is there an IP Address I can white label for this request or a way to verify that Zendesk is asking for a JWT?
How is user_identifier_provided_by_the_app used by Zendesk? Do you create a customer/user based on user identifier or is it based on returned email and phone from jwt token?
Providing simply the user identifier is not secure at all as mentioned by Colbey W. We're thinking to provide another token (retrieved by mobile app) which will be accepted by our jwt service and return the data based on the token.
Thanks!
Hi Colbey W Ladislav Lenčucha - Zendesk maintains a list of IPs that can be whitelisted here: Configuring your firewall for use with Zendesk
There have been discussions and interest in making the getting of this list more dynamic (versus just listing them in this article), but currently this is the list to use to configure whitelisting by your service.
Zendesk passes through the "user_identifier_provided_by_the_app" to your service. Your app can can encode a user ID, looking however you like. This process is to authenticate an existing user. The returned JWT from your service requires the user's email. See also Setting a unique identify -- it rounds out some of the information given in this article.
@..., Brett Bowser
When I go into ZenDesk settings for the Mobile SDK and change the authentication type from anonymous to JWT, for a little while afterwards mobile applications trying to use ZenDesk JWT authentication get an error from ZenDesk saying that they are using the wrong authentication type. After a while, it starts working however. Is there a delay between when JWT authentication is enabled in the ZenDesk settings admin interface and when ZenDesk starts using those new settings? And if so, about how long is the delay? We've seen the delay last anywhere from as little as 10 minutes to as long as 3 hours. Is there any way to make this delay more consistant? Also, we've noticed that the delay is shorter for some clients than others. My theory is that there is some distributed system that settings changes get replicated across, and that some ZenDesk instances get the changes before others. Is that correct, or is there some other reason for the variable delay?
Here is PHP/symfony Implementation.
https://gist.github.com/bhaktaraz/edbaa25c4100c9699bf1e5e2a80a8a90
Thanks Bhaktaraz Bhatta for posting that example!
Michael H -- I don't see any documentation on an expected delay, but because a mobile app's setup should be relatively static and not change (at least not that often), there could perhaps be a delay. Do you have a use case where a mobile app's setup is changing often for some reason? Can you provide more details?
I'm also referencing this KB article: Building a dedicated JWT endpoint for the Support SDK
One of our devs shared with us today that there could potentially be a delay when updating settings in the SDK, so I wanted to share this:
I also want to point out that you can use both an anonymous identity, as well as a JWT identity in the same app. Just go to Channels >> Mobile SDK >> Add app and then you can create the other identity. You can choose when to initialize the two!
It's a shame there is no "Test it now" button in the Mobile SDK App Setup page. One where I could provide "unique_id" and get some kind of feedback whether the endpoint is reachable, returns correct JWT (content-wise and signature-wise).
Would it be possible to have this? It would definitely help decrease number of support tickets on your side.
Is there a way to avoid email in the jwt payload as I need to use phone as primary identity ?
Nope, field must be present and non-empty. However, in case of JWT authentication, you can provide also external_id which will be used for customer matching instad of email. The primary identity is then in your hands.
I am receiving request from the zendesk on my lambda service with user_token that is sent from the mobile app. I am validating the necessary items and sending back the jwt after signing it with the secret. My response looks exactly the same with the curl example given above.
But on mobile it gives error code 400, body is null. What could be the issue.
Usually the issue is with the JWT you return. I think I managed to get all the problems that might occur:
- undefined custom field
- inconsistent identity (different id with same email already existed in Zendesk)
- incorrect signature
- incorrect language code
Sadly you can get the explanation from Zendesk support only, which has 2-5 days reaction time.
Hello,
We are implementing a dedicated endpoint for use with the Zendesk SDK in order to authenticate users through a JWT. Our implementation in our backend works correctly, it returns the expected response. However, when we use the Zendesk SDK, there are no traces of a request being made from Zendesk to our servers, even though we have configured everything correctly, as instructed in this link: https://develop.zendesk.com/hc/en-us/articles/360001075248-Building-a-dedicated-JWT-endpoint-for-the-Support-SDK.
What do you think this might be?
Thank you
Two things - you have to enable JWT authentication in Zendesk setup and make sure you initialize Zendesk SDK properly (you need to use the identity which expects customer identifier/token)
Hey Ladislav Lenčucha, thank you for the answer.
We enabled the JWT authentication in Zendesk according to the documentation. Related to the SDK, we are using the following code (iOS):
We don´t know what could be failing.
Thanks again!
i have initialised the zendesk SDK on Android , and tried to get Identity with the help of following code:-
"unique_id" is the unique identifier of the user.
My JWT not getting any hit from Zendesk Server.
I am getting following logs :-
D/OkHttp: <-- 401 https://{companyname}.zendesk.com/access/sdk/jwt (2896ms, 37-byte body)
D/GsonSerializer: Unable to deserialize the provided object into AccessToken
W/ZendeskIdentityManager: There is no stored access token, have you initialised an identity and requested an access token?
Can anybody help us with this issue ?
Note: We have replaced the actual name with {companyname} for the purpose of privacy
Please sign in to leave a comment.