Tip: Enabling JWT SSO with Multi-Host Applications
This post will review a strategy for setting up Zendesk JWT SSO when your end users connect from any number of different hosts that you manage. The goal here is to make a solution where end users who are authenticated in your application can click a link and automatically sign in to Zendesk without needing to re-login or deal with another set of credentials. This builds on a couple of JWT articles from Zendesk.
The problem we face when managing multiple hosts is getting from Zendesk back to the host where the end user is authenticated. Zendesk JWT configuration only allows for one endpoint for authentication. In order to accomplish our goal we will setup a series of endpoints to route the JWT login request back to the correct endpoint.
- The first endpoint will be a brand router. If you do not have multi-brand setup this step can be skipped. This will look at the return_to parameter in the JWT request and use the brand to determine the correct domain to route to. Each brand will have a centralized endpoint for routing traffic on its domain.
- The next endpoint will be a domain router. This will be a centralized endpoint for a given domain. This endpoint has to be a client webpage because it will be using cookies to determine the next hop. In order for this to work the host that authenticated the end user should create a domain cookie with the name of the server the user is authenticated on. The domain router will look at this cookie and forward the request next endpoint.
- The next endpoint will be the host router. This will be a client webpage residing on the host where the end user originally authenticated. The need for this endpoint is to force the session cookie to load before routing to JWT Handler. This will prevent the user from having to re-authenticate if they are already logged in. This page will redirect to the JWT Handler.
- The final endpoint is the JWT handler. This should be a secure endpoint that a user cannot hit without being authenticated. This endpoint will take the active session information and create a JWT packet and callback to ZenDesk.
Before we get started on implementing this let's talk about the cookie we need to make this routing work. You can name this cookie whatever you want but for reference we will call it the Auth_Host cookie. When a user signs in to your application you will need to create an Auth_Host cookie with the name of the host the end user authenticated with. This cookie will be looked at by a javascript so it cannot be Secure or HttpOnly. Also this will be present for everyone in your domain so you will need to set the Domain property on it.
Set-Cookie: Auth_Host=myhost.domain.com; Domain=domain.com
Now let's look at the router code. First up is the brand router. If you don't have multi-brand you can skip this step. The brand router will need to be hosted by only one of the brands. Zendesk will route to this endpoint. Based on the brand in the return_to, this will route communications to the appropriate domain router. It is important that this endpoint can be reached without authenticating. If you need code for this it is provided in the multi-brand Zendesk article.
Next we need to look at the domain router and the host router. Both of these can be implemented in the same webpage. It is important that this endpoint can be reached without authenticating. For this example the cookie it relies on is "Auth_Host" and the JWT Handler endpoint it routes to is "/zdlogin".
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Redirecting</title>
<script>
//a function to get a cookie
function getCookie(cname) {
let name = cname + "=";
let ca = document.cookie.split(';');
for(let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return null;
}
//Auth_Host cookie will indicate where we signed in
var auth_host = getCookie("Auth_Host");
var url_string = window.location.href;
var url = new URL(url_string);
if(auth_host!=null && auth_host!=url.hostname) {
//if we are not on the host with the session, route to it
url.hostname = auth_host;
window.location = url.toString();
} else {
//if we are on the host with the session route to the jwt handler
var returnTo = url.searchParams.get("return_to");
window.location="/zdlogin?return_to="+returnTo;
}
</script>
</head>
<body>
</body>
</html>
Finally we get to the JWT Handler. This endpoint should only be reached by authenticated end users. This will take the active session and construct the JWT packet to return to Zendesk. The code for this is covered in the Enabling JWT Zendesk article. There are several source code examples provided in this article as well.
That's it. With all of the endpoints in place you will be able to automatically authenticate any of your end users in Zendesk regardless of what host they originally authenticated on.
댓글을 남기려면 로그인하세요.
0 댓글