JSON Web Tokens (JWT) allow the transferring of "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.
JWT SSO addon in Vanilla
Unlike our other SSO methods (JSConnect, SAML, OAuth2), JWT SSO is not intended to be used in conjunction with other Sign On methods. With that said, you can use it with other methods but there will be no Sign In button on your Sign In page, as you can see below.
- If you're using JWT SSO as your default connection, your regular Sign In button will go directly to your JWT SSO Sign In URL.
As with all our SSO solutions:
- user data passed as part of a JWT payload are mapped to existing Vanilla community accounts by email address,
- or a new account is created if no match is found (known as Just-In-Time Provisioning [JIT]).
- 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)
Redirecting back to the Vanilla community
When setting up your Sign In URL in the Vanilla Dashboard, you can redirect users to the URL where they initiated the log in process. To do so, add a target variable and a target placeholder string that will be dynamically replaced when Vanilla redirects the user to your sign in page. For example:
As for your sign-in workflow process for the user:
- make sure you maintain that Target value so that when you redirect back to your Vanilla community, it's passed back so that Vanilla can redirect the user back to where they initiated the sign in.
The entry endpoint for connecting users using JWT SSO is:
https://[your-forum-domain]/entry/connect/JWTSSO/?authKey=JWTSSODefault&target=[uri-where-signin-initiated]
Technically, you can add the JSON Web Token response to this URL, but the best practice would be to put it in the response headers as a Bearer Token:
https://[your-forum-domain]/entry/connect/JWTSSO/?authKey=JWTSSODefault&jwt=[jwt-response]&target=[uri-where-signin-initiated]
Map 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 must map the key names in the JWT SSO Addon Settings form. For example, 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:
Pass 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.
- If you want to pass a user's Role, and have it applied as a Role in the community, it must be passed as "Roles" (case-insensitive, 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 in your community.
The example below:
{
"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.
By default, Vanilla will re-assign the user's Roles every time they log in over SSO, giving your authentication provider full control over the user's Roles.
📝 NOTE: Cloud customers who want to be able to assign Roles to users in the Vanilla Dashboard and have roles added over SSO can ask Vanilla Support to configure their community to work in this way. For more details on passing roles over SSO, check out this article.
Pass the Name in the JWT payload
The Name
attribute of the payload becomes the Display Name that is seen when they post and interact in the Vanilla community.
- Passing the name is optional.
- If you want users to choose their own names, leave the name as an empty string or omit it completely and users will be prompted to create a Display Name when they connect for the first time.
{
"address": "dave@email.com",
"pic": "https://cdn.aws.com/ourcdn/davesprofilepic.gif",
"name": "",
"fullname": "Dave Johnson",
"id": 1828838378,
"Roles": "Moderator, Chearleader"
}
Make this connection your default signin method
Checking the Make this connection your default signin method box in the Settings form will make this the only way to log in to your Vanilla community or create users. This will mean that:
- When you click the default "Sign In" button, it will redirect you to your authentication provider to log in.
- The community's "Username and Password" or "Registration" forms will no longer be accessible to users.
- Users will not be able to edit their profiles in the community.
- You will be able to redirect users to a configured end-point after they log out.
If you have created a user natively in the community 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 in the community, you will be asked to enter the password you set when you created the user. If this becomes problematic, contact your CSM.
Logging out
If Make this connection your default signin method is checked, you can configure a URL where you would like to redirect a user when he/she logs out of your Vanilla community. 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 community and clicks Sign In, he/she will be automatically logged in to the community without having to enter a username and password.
Troubleshooting your JWT setup
You may not be sure what data you're sending or how it's formatted. Ask Vanilla Support to turn on logging. Then, you can click the Event Log link in the left-hand menu to see the logs. Filter on "Event Name" jwt_logging and 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.
Set up your JWT authentication provider
With most SSO providers, you will have two additional requirements:
- Users must access your community over
https
- Your community must contact your Authorization Server using
https
- Your Authorization Server will need to allowlist the redirect URI (e.g.,
https://[your-forum]/entry/JWTSSODefault
)
Build the JWT response
The JWT response comprises two JSON objects:
{
"typ": "JWT",
"alg": "HS512"
}
{
"iss": "https://your-issuing-site.com/",
"sub": "12345",
"aud": "https://forumdomain.vanillacommunities.com/",
"email": "dave@email.com",
"displayname": "Dave",
"exp": 1564426188,
"nbf": 1564425588
}
These have been URL safe base64-encoded. This 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) {
$header = $this->base64url_encode($rawJWTHeader);
$payload = $this->base64url_encode($rawJWTPayload);
$jWTString = $header.'.'.$payload;
$key = strtr($secret, '-_', '+/');
// the secret is base64_encoded, decode it.
$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 in to Vanilla.
Sample JWT Payload
JWT payload passed back to vanilla:
https://[community-url].com/entry/connect/JWTSSO/?authKey=JWTSSODefault&jwt=jwt-signature