Cross domain Single sign-on with Json Web Tokens (JWT)
Federate your websites using only javascript
Access to several web sites with a unique identification. Uses JSON Web Tokens (RFC7519) to represent the information exchanged between the identification provider (IDP) and service provider (SP). The JWT is shared and synchronized among all your websites through the browser local storage without need of server session
How does it work
You have an excellent introduction to JWT in (https://jwt.io/introduction/) and single sign-on (SSO) on our website (spanish) (https://produccion.sslsignature.com/web/sso.html)
Getting started
With hosted version (it is free)
Define on page a <meta>
field to indicate the sslsignature accountId
<meta name="ssls.accountId" content="5995a3c9-678b-4338-a674-362af68b9ef9" />
Include javascript
<script src="https://produccion.sslsignature.com/sso/resources/js/sslssso.js"></script>
Create a function to receive the authenticated user
function onIdentification(operation){
console.log("eidentifier: "+ operation.eIdentifier);
console.log("name: "+ operation.name);
console.log("jwt: "+ operation.jwt);
}
Now, we are going to see it in action (download the demo for the third step)
- Create a JWT here. This would be done in your login form
- Open a new tab in your browser with this URL. You will see that you are logged in and the content of the JWT token
- Now, here is the magic, download sso.html and open from your computer, and you will see that you are registered with the same user. Try to logout and see the opened page in second step (do not use IE11 at this moment, please...)
##Install
Content of the repository
- /backend -->The sample server
- /build -->Build scripts
- /client -->Javascript library for your pages
- /dist -->Precompiled sso.war to deploy javascript, sample server and demos on a container like tomcat
- /test -->Demo pages (hosted and standalone) and a java sample client to issue/validate tokens
Javascript library
Simply copy the library 'sslssso.js' and its dependencies on a web server. {yourserver.com}/{ssopath}/js/sslssso.js {yourserver.com}/{ssopath}/html/sso.html sslssso will access sso.html and related .js, therefore expect to find this structure
Include a javascript reference in your page to sslssso.js
<script src="{yourserver.com}/{ssopath}/js/sslssso.js"></script>
or use hosted
<script src="https://produccion.sslsignature.com/sso/resources/js/sslssso.js"></script>
Backend server
The signature key to issue tokens (and validate) must be well protected, usually on the server. You can use a hosted account from SSLSignature (free of charges) or issue tokens from your own server. The project includes a sample server with autogenerated HMAC keys
####Use your own server Yo need to provide a REST service to validate the JWT from the client side. If you plan to do it only on server side, move on to the next section
POST /{ssoValidationUri} HTTPS
Content-Type=application/x-www-form-urlencoded
Host: yourserver.com
jwt={jwt}
The answer must have code 200, status = FAILED / SUCCESS, and the JWT parsed fields in JSON format
{
"status": "SUCCESS", //SUCCESS, FAIL. Mandatory
"sub": "123456", //User unique identifier. Recommended
"eidentifier":"john.smith" //username,Recommended
"name": "John Smith", //User Full Name. Recommended
"other": "value", //More fields (email, phone, etc). Optional
"jwt": "eyJhbGciOiJIUzI..." //JWT new token if necessary. Optional
}
####Use the sample server Take care that it is only an example and it is not intended for a production system
Deploy sso.war in a J2EE container like tomcat. The first time you run the HMAC signing key will be created in a file called jwt.hmac (configure location in WEB-INF/web.xml)
The JWT validation service will be available on {yourserver.com}/sso/jwt The sample server also allow you to issue JWT. Invoke the service providing the fields to be included in JWT
POST /sso/jwt HTTPS
Content-Type=application/x-www-form-urlencoded
Host: yourserver.com
sub=123456&eidentifier=john.smith&name=John+Smith&phone=34+661661661&email=john.smith%40mycompany.com&other=...
The response will be the JWT string
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTYiLCJpc3MiOiJKV1QgU0FNUExFIElTU1VFUiIsImlhdCI6MTQ2MzU4MTg4MSwiZXhwIjoxNDYzNjY4MjgxLCJwaG9uZSI6IjM0IDY2MTY2MTY2MSIsIm90aGVyIjoiLi4uIiwiZWlkZW50aWZpZXIiOiJqb2huLnNtaXRoIiwiZW1haWwiOiJqb2huLnNtaXRoQG15Y29tcGFueS5jb20iLCJuYW1lIjoiSm9obiBTbWl0aCJ9.eaihxfyO8zWJJm0o97T6p-Cql9oe6n_3SLj0MphGbBA
Configure expiration or issuer in JWTServlet class.
####Use the hosted server The SSLSignature could issue and validate the JWT for your system. You need an account. After that, the configuration is simple as shown in 'Getting started'.
After a successful authentication in your system, invoke this service to issue a new token . Provide a JSON with your required fields.
POST /sslsignature/account/jwt HTTPS
Authorization=Basic YWNjb3VudElkOmFwaUtleQ==
Content-Type=application/json
Host: produccion.sslsignature.com
{
sub: "yourInternalId",
eidentifier: "yourUserIdentifier",
name: "user name",
other: "other..."
}
Also is needed an authorization header (basic http auth) in the way Basic Base64(accountId:apiKey)
. The string 'Basic' followed by the base64 encoding of the provided accountId, ':' and apiKey
##Usage
Page configuration
Configure the accountId and custom validation URL in the tags of the page or using javascript. The accountId will reference the identifier that will take the token in the local storage.
<meta name="ssls.accountId" content="myTokenId" />
<meta name="ssls.validationUrl" content="{yourserver.com}/{ssoValidationUri}" />
<meta name="ssls.validate" content="true"/>
<script src="https://produccion.sslsignature.com/sso/resources/js/sslssso.js"></script>
//Optional javascript config
var ssls_accountId=myTokenId;
var ssls_validationUrl={yourserver.com}/{ssoValidationUri};
SSO Events
The sso generates events for onload, onIdentification and onLogout. Simply create a function on the page with these names.
// Invoked after page load if you have a valid token or after new JWT correct identification (if page is still loaded)
// If you do not have identification token, this function is not executed
function onIdentification(operation){
console.log(operation.sub); //Your User internal ID
console.log(operation.eidentifier); //Your user unique identifier (for example the username)
console.log(operation.name); //User full name
console.log("operation.jwt); //The token itself
}
//Invoked when the script finish loading the SSO. It is always after onIdentification
function onLoad(){
}
//Invoked when user logs out
function onLogout(){
}
In you need several event listeners use
sslssso.listen ("sso.onload", function (observable, eventType, data) {});
JWT Validation
The token is validated during script execution to check that has been issued by the server and has not been altered. The electronic signature is verified cryptographically on the server. If the token is correct will occur a call to onIdentification. If the validation is unsuccessful, the token is deleted and acts as if there had been token.
Validation URL is configured with <meta name="ssls.validationUrl">
(see server instalation). If you do not want the tokens are validated on the client side, set validate = false
(default is true). Then no server configuration is needed, and sslssso.js
only will decode jwt token and check expiration on the client side.
On hosted version, use the provided accountId and do not set the validationUrl
Login
In a standard authentication flow, when an identification is required, the website redirects the user to the IDP (identification provider). The IDP authenticates user with the organization defined method, for example, and username/password form. After successful authentication, the IDP server returns a valid JWT that includes the identification information and the electronic signature. The JWT is stored locally on the browser
Calls SSO to store the jwt issued token on localStorage of browser. An onIdentification
event will be fired on all tabs
sslssso.login(jwt);
Logout
sslssso.logout();
The token will be cleaned and an onLogout
event will be fired on all tabs
##Known issues ###IE11 & Edge JWT update events do not syncronize tabs. See Microsoft doc
Support
https://soporte.aralink.com https://github.com/Aralink/ssojwt/issues