OpenWater allows you to build your own single sign on (SSO) to authenticate users with Json Web Tokens (JWT). Json Web Tokens is a popular single sign on standard and you can learn more at jwt.io.

Workflow Overview

JWT follows a handshake style authentication process. This means that a user will first try to access a page on the OpenWater platform that requires them to be logged in. If they are not logged in, they will be redirected to your website to be authenticated. Upon successful login, they are redirected back to OpenWater and to the page they were originally trying to access.

Here is an animation demonstrating this workflow.

Configure OpenWater

Login to the OpenWater administrative backend, and under System Settings in the left side navigation, click Login Configuration. Select Use 3rd Party Corporate Authentication and then Json Web Token.

Provide the Login Url which will point to your single sign on / authentication login page. Create a secret key that will be used to generate a valid token. Also enter what the login button should say on OpenWater and provide an optional sign out url.

Click Save. At the top of your screen open Public Website in an incognito browser or private browsing mode so that you can view the public portal from a logged out perspective.

Click the Login button to begin testing your SSO.

Writing the Handler

At a minimum, OpenWater requires the following information to be included in the Json Web Token during a single sign on.

  • First Name
  • Last Name
  • Email Address

You can optionally include additional information and demographic details.

The handler involves two steps. The beginning of the handshake when OpenWater passes the returnUrl to your site and the end of the handshake when you redirect the user back to OpenWater with a JSON Web Token.

C# Example

Required Package: https://www.nuget.org/packages/JWT

Set OpenWater to redirect to an endpoint that takes returnUrl as a parameter. Save the returnUrl either in the Session or in a Cookie as it will be used after you authenticate the user on your side.

public ActionResult BeginHandshake(string returnUrl) {
    Response.Cookies.Add(new HttpCookie("returnUrl", returnUrl));               return RedirectToAction("Login"); //authenticate the user          
}

After you authenticate the user, redirect them to a handler to complete the handshake.

public ActionResult CompleteHandshake(string customerId) {
    var jwtSecret = "SharedKey"; //Shared Key as set in configuration
    var returnUrl = Request.Cookies["returnUrl"].Value; //the returnUrl saved earlier

    var userProfile = getUserProfileFromCustomerID(customerId); //get user profile data from your database on this authenticated user

    var jwt = JWT.JsonWebToken.Encode(new
        {
            //required properties
            TimestampUtc = DateTime.UtcNow,
            Email = userProfile.EmailAddress,
            FirstName = userProfile.FirstName,
            LastName = userProfile.LastName,
            UserNameExists = true,
            UserValidatedSuccessfully = true,
            UserIsMember = userProfile.IsMember, //boolean value
           
            //optional properties
            ThirdPartyUniqueId = userProfile.CustomerId,
            Company = userProfile.Company,
            Phone = userProfile.Phone,
            JobTitle = userProfile.JobTitle,
            Gender = userProfile.Gender,
            PrimaryAddress = createAddress(userProfile.PrimaryAddress),
            SecondaryAddress = createAddress(userProfile.SecondaryAddress),
            UserData = userProfile.CustomerId,
            ProfileTextFieldData = getCustomProfileFields(userProfile.EyeColor)
        }, jwtSecret, JwtHashAlgorithm.HS256);

    return Redirect(string.Format("{0}&token={1}", returnUrl, jwt);
}

There are three sets of properties above that are not obvious - ThirdPartyUniqueId, Addresses, and Custom Profile Fields.

ThirdPartyUniqueId is useful if you would like OpenWater to key on some field other than email address. If you do not use ThirdPartyUniqueId, then OpenWater will use the email address to identify the user. This can be problematic in situations where a user is allowed to change their email address on your CRM. If they do so, and then log in to OpenWater again, they will have two accounts - one for each email address. Populating ThirdPartyUniqueId prevents this from happening.

An Address Field should be a dictionary with the following properties:

public Dictionary createAddress(Address address)
{
    var openwaterAddress = new Dictionary();
    openwaterAddress.Add("Line1", address.Line1);
    openwaterAddress.Add("Line2", address.Line2);
    openwaterAddress.Add("City", address.City);
    openwaterAddress.Add("StateProvinceAbbreviationOrName", address.State);
    openwaterAddress.Add("ZipPostalCode", address.Zip);
    openwaterAddress.Add("CountryAbbreviationOrName", address.Country);
    return openwaterAddress;
}

If you have setup additional custom user profile fields as part of your user profile, you can populate those too. In order to do this, you will need to acquire the GUIDs for these custom fields. Log back into OpenWater and return to your public portal and click My Profile.

Right click the custom field and click Inspect in Google Chrome browser.

The data-fieldid under <section> is the GUID you can use.

Once you have your GUIDs, you can set a dictionary on ProfileTextFieldData where the key is the GUID, and the value is the field value you want to pass.

public Dictionary getCustomProfileFields(string eyeColor)
{
    var eyeColorGuid = "c0f12801-3dfe-44a1-a24b-e723ccfdf35f";
    var customFields = new Dictionary();
    customFields.Add(eyeColorGuid, eyeColor);
    return customFields;
}

UserData Field

The UserData property is a useful property to populate with any other information you want to include in OpenWater. Quite commonly this is the ID of the user in your database, but also any kind of membership levels like Gold membership, or Professional vs. Student, etc. You can set pricing based on this field in OpenWater.

Did this answer your question?