Introduction to JWT
JWT or JSON Web Tokens are a means for transferring "claims" from one party to another in a URL-safe format. The JWT consists of two base64_encoded JSON objects with a signature attached, they can be passed as GET parameters or as Bearer tokens. For more information about JWT please refer to to the JSON Web Token RFC.
Using the JWTSSO Addon in Vanilla
As with all our SSO solutions, user data passed as part of a JWT payload are mapped to existing forum accounts by email address, or a new account is created if no match is found. You may combine it with any other SSO connections.
A settings form in the dashboard allows you to define custom parameter names for:
- Sign In, Register and Sign Out URLs
- Issuer
- Intended Audience
- Client secret (for testing the JWT signature)
- Expected keys in the JSON response to the profile request (e.g. UniqueID, Email, Username, Photo).
Mapping User Profile Values
The JWT SSO workflow sends the user's profile data as a set of key/value pairs as the payload of a JWT object. Vanilla expects those keys to be:
{
"Email",
"Photo",
"Name",
"FullName",
"UniqueID"
}
If those key names do not correspond to Vanilla's you will need to map the key names in the JWT SSO Addon Settings form. For exemple, if your authentication provider sends the user's profile like this:
{
"address": "dave@email.com",
"pic": "https://cdn.aws.com/ourcdn/davesprofilepic.gif",
"name": "Dave",
"fullname": "Dave Johnson",
"id": 1828838378
}
You will want to fill in the form in the dashboard like this:
Passing Roles in the JWT Payload
You can pass a user's role in the profile response. Unlike the values shown above, there is no user interface for mapping the key name for roles in the dashboard -- yet. For now, if you want to pass a user's role and have it applied as a role on the forum it must be passed as "Roles" (capital R, plural "Roles). The value can be a comma separated list of roles. In order for it to work it must correspond exactly with name of a role or roles configured on your forum.
{
"address": "dave@email.com",
"pic": "https://cdn.aws.com/ourcdn/davesprofilepic.gif",
"name": "Dave",
"fullname": "Dave Johnson",
"id": 1828838378,
"Roles": "Moderator, Chearleader"
}
will assign these two roles to this user.
"Make this connection your default signin method."
Checking the "Make this connection your default signin method." checkbox in the Settings form will make this the only way to log into your forum or create new users. This will mean that:
- When you click on the default "Sign In" button it will redirect you to your authentication provider to log in.
- The "Username and Password" or "Registration" forms on the forum will no longer be accessible to users.
- Users will not be able to edit their profiles on the forum.
- You will be able to redirect users to a configured end-point after they log out.
If you have created a user natively on the forum before setting JWT SSO as the default method for connecting but still need to log in using the "Username and Password" form you can always access it by typing /entry/password
in the address bar of your browser. Also, when you try to connect over SSO, and the system detects that you have a user with the same email address on the forum, you will be asked to enter the password you created when you created the user on the forum. If this becomes problematic, talk to your Customer Success Manager.
Logging out
You can configure a URL where you would like to redirect a user when he/she logs out of your forum, only if you have checked "Make this connection your default signin method." in the dashboard. This URL can be an end-point on your authentication provider that will then log them out of the "parent" system. If you choose to not log them out of the authentication provider and the user navigates back to the forum and clicks on "Sign In" he/she will be automatically logged into the forum without having to enter a username and password.
Troubleshooting your JWT Setup
You might not be sure what data you are sending or how it is formatted. Ask your Customer Success Manager to turn on logging. Then you can click on the Event Log link in the left-hand menu to see the logs. Filter on "Event Name" jwt_logging, scroll down to the bottom of the page to view the filtered logs in either JSON or XML format. Search for "profile" to see what key/value pairs are being translated into. There will also be helpful error messages here as well.
The JWT SSO Addon gives helpful errors
Setting up your JWT Authentication Provider
With most SSO providers, you will have two additional requirements:
- Your forum must be accessed over
https
by users. - Your forum must contact your Authorization Server using
https
. - Your Authorization Server will need to whitelist the redirect URI (e.g
https://[your-forum]/entry/JWTSSODefault
)
Building the JWT Response
Building the JWT response consists of two JSON objects, the Header:
{
"typ": "JWT",
"alg": "HS512"
}
and the Payload:
{
"iss": "https://your-issuing-site.com/",
"sub": "12345",
"aud": "https://forumdomain.vanillacommunities.com/",
"email": "dave@email.com",
"displayname": "Dave",
"exp": 1564426188,
"nbf": 1564425588
}
which have been URL safe base64 encoded. Which means:
- Any
+
symbols have been replaced by -
after being encoded. - Any
\
symbols have been replaced by _
after being encoded. - Remove any
=
symbols stripped from the end.
They are then signed by:
- Taking the encoded Header and Payload.
- Concatenating them with a
.
- The concatenated string is now hashed using 'hash_hmac' with the algorithm chosen in the dashboard form (in this example 'HS512' ) and the secret. The secret is presumed to be base64 encoded but if it is NOT, we can manually set a config setting
JWTSSO.DecodeSecret
to FALSE
.
Sample PHP code of how to sign the payload:
$rawJWTHeader = '{
"typ": "JWT",
"alg": "HS512"
}';
$rawJWTPayload = '{
"iss": "https://your-issuing-site.com/",
"sub": "12345",
"aud": "https://forumdomain.vanillacommunities.com/",
"email": "dave@email.com",
"displayname": "Dave",
"exp": 1564426188,
"nbf": 1564425588
}';
$secret = '12355';
$alg = 'HS512';
function signJWT($rawJWTHeader, $rawJWTPayload, $secret, $alg) {
$decodeSecret = c($'JWTSSO.DecodeSecret', true);
$header = $this->base64url_encode($rawJWTHeader);
$payload = $this->base64url_encode($rawJWTPayload);
$jWTString = $header.'.'.$payload;
$key = strtr($secret, '-_', '+/');
// If the secert is base64_encoded, decode it.
if ($decodeSecret) {
$key = base64_decode($key);
}
$rawSignature = hash_hmac($alg, $jWTString, $key, true);
$base64encoded = $this->base64url_encode($rawSignature));
$signature = trim($base64encoded);
$jwt = $header.'.'.$payload.'.'.$signature;
return $jwt;
}
Test the connection
- Sign in at
https://[auth-domain].com
(your actual SSO sign in page) - Visit
https://[forum-domain].com
. Make sure you are not logged in. Clear your cookies, if necessary. - Visit the “authorize” link described above.
- You should automatically arrive back at
https://[forum-domain].com
, but you should now be signed into Vanilla.