Page tree
Skip to end of metadata
Go to start of metadata

This article describes how to implement Nexus GO Authentication. Nexus provides authentication libraries for easier integration to the authentication service from your online application.

There is a demo application where you can try out the service. 

Expand/Collapse All

Step-by-step instruction

Link to Nexus GO

You can either add a link to Nexus GO authentication in a separate page, or insert the link in an iframe.

 Option: Link to Nexus GO in separate page
  1. Insert a link to the Method URL generated by Nexus GO.

    Link to Method URL
    <a href="{Method URL}">Log in</a>

Swedish BankID

If you want to use logotypes for Swedish BankID or Swedish Mobile BankID, you need to follow the BankID guidelines for logotypes: BankID - Logotyper (In Swedish).


 Option: Link to Nexus GO in iframe

The JavaScript library iFrame Resizer is required to change the height of the iframe in order to fit any messages. The height can be expected to change less than 100px.

  1. Download the library, and save it in your JavaScript file folder:
    File for download: iframeResizer.min.js
  2. On the login page, add code to insert an iframe, using the Method URL generated by Nexus GO. The iframe has a minimum width of 260px, and no maximum width. Also add code to use the JavaScript library to handle resizing of the iframe.

    Login page: Insert iframe
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>Log in</title>
            <!-- Handle resizing of the iframe using the JavaScript library -->
            <script src="js/iframeResizer.min.js"></script>
        </head>
        <body>
            <!-- Insert iframe -->
            <iframe src="{Method URL}" width="260" scrolling="no" onload="iFrameResize()"></iframe>
        </body>
    </html>
  3. Add a separate page that will be returned as the response from the Validation URL page. This page will break out of the iframe by redirecting the top frame to the welcome page, where logged-in users will be sent.

    Break out of iframe page
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title></title>
        </head>
        <body>
            <!-- Break out of iframe -->
            <script type="text/javascript">
                window.top.location.href = "{Welcome page}";
            </script>
        </body>
    </html>
  4. If you want to get messages from the iframe to the login page, use the setup in the following example. This enables hiding and showing a progress indicator. See also example in the demo application.

    Example: Advanced iframe settings using jQuery
    $(function () {
      'use strict';
    
      function registerIframeCallbacksWhenReady() {
        $('.nexus-iframe').on('load', registerIframeCallbacksOnce);
      }
    
      function registerIframeCallbacksOnce() {
        registerIframeCallbacks();
        $('.nexus-iframe').off('load', registerIframeCallbacksOnce);
      }
    
      function registerIframeCallbacks() {
        iFrameResize({
          messageCallback: function (messageData) {
            if (typeof messageData !== 'undefined'
                && typeof messageData.message !== 'undefined'
                && 'submitForm'.match(messageData.message.event)) {
              // 'nexus-iframe' is about to reload, here you can e.g. hide the iframe and show a progress indicator
            }
          },
          resizedCallback: function () {
            // 'nexus-iframe' has initialized completely, here you can e.g. show the iframe and stop progress indicator
          },
        }, '.nexus-iframe');
      }
    
      registerIframeCallbacksWhenReady();
    });
    
    // The actual iframe:
    // <iframe class="nexus-iframe" width="260" scrolling="no" src="{Method URL}"></iframe>
  5. Because the Method URL page which is on the domain idp.go.nexusgroup.com is separate from the login page and needs to use cookies during the authentication, placing it inside an iframe means that its cookies will be seen as third-party cookies by the browser. Some browsers with stricter privacy settings may reject these cookies if it doesn't already have a first-party cookie from that domain. So to improve reliability across different browsers we recommend login links to go via our bounce page, which will set a first-party cookie and immediately redirect the end-user to the actual login page. There are a few approaches to achieve this.

    1. Use the bounce page in all links to the login page containing the iframe.[note 1]

      Link to Login page URL via Nexus GO bounce page
      <a href="https://idp.go.nexusgroup.com/wa/bounce.html?destination={Login page URL}">Log in</a>
    2. Use a server-side HTTP redirect to send the end-user to the login page via the bounce page. Example flow:
      1. End-user requests the login page at https://example.com/login
      2. Server examines the path seeing that no query parameter is present, the server responds with a HTTP redirection[note 1]

        Server side redirect via Nexus GO bounce page
        HTTP/1.1 302 Found
        Location: https://idp.go.nexusgroup.com/wa/bounce.html?destination=https://example.com/login?showLoginForm=true
      3. End-user reaches the bounce page, which sets the first-party cookie and immediately redirects back to the destination URL given
      4. End-user reaches the destination URL, which is the page https://example.com/login?showLoginForm=true
      5. Server examines the path seeing that the query parameter is present, it displays the page as normal, which includes the iframe
    3. Use a client-side JavaScript redirect to send the end-user to the login page via the bounce page.[note 1] This approach is the same as for b. above, except that the logic is instead performed by JavaScript, which decides whether to display the login page or redirect via the bounce page.

      JavaScript redirect via Nexus GO bounce page
      (function () {
        'use strict';
      
        function isBounced() {
          var params = parseQueryString();
          return params.showLoginForm === 'true';
        }
      
        function parseQueryString() {
          var plusPattern = /\+/g;  // Plus character is a space in application/x-www-form-urlencoded
          var keyvalPattern = /([^&=]+)=?([^&]*)/g;
          var decode = function (s) { return decodeURIComponent(s.replace(plusPattern, ' ')); };
          var query = window.location.search.substring(1);
          var keyvals = {};
          var match = keyvalPattern.exec(query);
          while (match) {
            keyvals[decode(match[1])] = decode(match[2]);
            match = keyvalPattern.exec(query);
          }
          return keyvals;
        }
      
        if (isBounced()) {
          // Show the iframe containing the login form
        } else {
          window.location = 'https://idp.go.nexusgroup.com/wa/bounce.html?destination=https://example.com/login?showLoginForm=true';
        }
      }());

    Note 1

    The destination query argument should have all characters with delimiting roles for the query component (& and #) percent-encoded (%26 and %23, respectively), as they would otherwise have ambiguous delimiting roles. Alternatively, encode the entire destination query argument using application/x-www-form-urlencoded.

Swedish BankID

If you want to use logotypes for Swedish BankID or Swedish Mobile BankID, you need to follow the BankID guidelines for logotypes: BankID - Logotyper (In Swedish).

 Inform about use of cookies

The Nexus GO authentication uses cookies, to handle the session to the back-end system.

  1. If you do not already inform your end-users about the use of cookies, you must do that to follow the EU legislation on cookies

Validate response from Nexus GO

 Download authentication library
  1. Download the Authentication library that suits your platform.
  2. Unzip the library package and save the library file in your developing environment, for example the PHP project folder.

    Each package contains:
    • Nexus GO authentication library
    • API documentation
    • Demo application - For testing the libraries in .NET and PHP
    • Readme file - Contains detailed information on files, folders, and how to use the demo application
 Download metadata XML files
  1. In Nexus GO, go to Services and then Authentication.
  2. Click on the environment that you want to protect with authentication, and then How to implement.
  3. Download the metadata XML files: sp.xml and idp.xml. Save the files in the metadata folder in the developing environment.
 Initialize authentication library
  1. Initialize the authentication library with the metadata files. The method reads sp.xml and idp.xml from the folder metadata, as specified in the argument.

     Java example
    Java example
    try {
        Path conf = Paths.get("metadata");
        librarySamlEngine = LibrarySamlEngine.initialize(conf);
    } catch (SamlEngineException e) {
        logger.error("Failed to initialize SAML engine", e);
    }
     .NET example


    .NET example
    try
    {
        SamlEngine = LibrarySamlEngine.Initialize("metadata");
    }
    catch (SamlEngineException e)
    {
        WriteToEventLog(e.Message, EventLogEntryType.Error);
    }
     PHP example


    init.php
    <?php
    require_once 'saml-validation.phar';
    
    final class LibrarySamlEngineHolder
    {
        public static function Instance()
        {
            static $inst = null;
            if ($inst === null)
            {
                $inst = LibrarySamlEngine::initialize("metadata");
            }
            return $inst;
        }
    
        private function __construct()
        {
        }
    }
    ?>
    


    For a list of possible initiation errors and proposed solutions, see Initiation errors.

 Validate response

When the end-user has authenticated using the Method URL, the authentication response will be sent to the Validation URL as a HTTP POST request.

  1. On the Validation URL, add code to validate the authentication response.

     Java example
    Java example
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        String samlResponse = req.getParameter("SAMLResponse");
        try {
            Result result = librarySamlEngine.validateSamlResponse(samlResponse);
            HttpSession session = req.getSession(true);
            session.setAttribute("userId", result.getNameID());
            session.setAttribute("method", result.getAuthnContextClassRef());
    
            // SAML attributes
            for (String key : result.getAttributes().keySet()) {
                session.setAttribute(key, result.getAttributes().get(key));
            }
    
            String contextPath = req.getServletContext().getContextPath();
    
            // If an iframe is used, link to the "iframe break-out" page here
            resp.sendRedirect(contextPath + "/welcome");
        } catch (SamlEngineException e) {
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
        }
    }
    
     .NET example


    .NET example
    [HttpPost]
    [AllowAnonymous]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }
        try
        {
            Result result = SamlEngine.ValidateSamlResponse(model.SAMLResponse);
            var ident = new ClaimsIdentity(
                new[] {
                        new Claim(ClaimTypes.Name,result.NameID),
                        new Claim(ClaimTypes.AuthenticationMethod, result.AuthnContextClassRef)
                },
                DefaultAuthenticationTypes.ApplicationCookie);
            
            HttpContext.GetOwinContext().Authentication.SignIn(
                new AuthenticationProperties { IsPersistent = false }, ident);
                Session["AssertionID"] = result.AssertionID;
            
            Session["InResponseTo"] = result.InResponseTo;
            Session["ExpireTime"] = result.ExpireTime;
    
            // SAML attributes
            foreach (KeyValuePair<string, object[]> item in result.Attributes)
            {
                Session[item.Key] = item.Value;
            }
    
            // If an iframe is used, link to the "iframe break-out" page here
            return RedirectToLocal(returnUrl);
        }
        catch (SamlEngineException e)
        {
            LastError = e;
            return
            View("Error");
        }
     PHP example
    1. Call the method validateSamlResponse() to process the authentication response. The method reads the response from the HTTP POST request and returns a result. A positive result is stored in the $result variable. If the validation of the authentication response fails, the method will throw an exception. Insert any links and error messages for successful and non-successful validations.

      PHP example
      <?php
      session_start();
      require_once 'saml-validation.phar';
      
      try
      {
          require_once 'init.php';
          $result = LibrarySamlEngineHolder::Instance()->validateSamlResponse();
          setcookie("Result", serialize($result));
      
          // SAML attributes
          foreach (array_keys($result->getAttributes()) as $key)
          {
              $_SESSION[$key] = $result->getAttributes()[$key];
          }
      
          // If an iframe is used, link to the "iframe break-out" page here
          header('Location: '.$uri.'index.php');
      }
      catch (Exception $e)
      {
          echo "[", $e->getCode(), "] ", $e->getMessage(), "\n";
          if ($e->getPrevious())
          {
              echo " - ", $e->getPrevious()->getMessage();
          }
      }
      ?>

    Example of a successful result:

    Example: Successful SAML response in .NET
    Name ID: 198901023286
    Authn context: urn:yourdomain.com:y2ylodsd2yxgwyy/pn7yt5tan6465yi/MobiltBankID
    Assertion ID: _7c8d6bdc3822afcebf0d93465a97a134
    Expiretime: 1485938846
    InResponseTo: _7d62a8736643eee397f4feae033ff0e6
    Relay state: abc12345
    commonName: Agda Andersson
    givenName: Agda
    surname: Andersson
    serialNumber: 198901023286
    countryName: SE
    issuerCommonName: Example Bank
    issuerOrganizationName: Example Bank AB
    issuerCountryName: SE

    The following attributes are available in the result:

    AttributeDescription

    commonName

    Common name

    givenName

    Given name

    surname

    Surname
    serialNumberPersonal identification number

    countryName

    Country name

    issuerCommonName

    Common name of the client certificate issuer

    issuerOrganizationName

    Organization name of the client certificate issuer

    issuerCountryName

    Country name of the client certificate issuer

For a list of possible validation errors and proposed solutions, see Validation errors.

Brand the login page or iframe

 Provide .css style sheet to Nexus

The Nexus GO login page or iframe can be branded, by providing a .css style sheet to Nexus.

Without a provided style sheet, then you will get an error message in the browser console:

Example: 404 error message
Failed to load resource: the server responded with a status of 404 (File Not Found)
https://idp.go.nexusgroup.com/wa/css/custom/www.mywebapp.com%20Swedish%20Mobile%20BankID%20dga5st2nq6s4nvq.css

To provide a .css style sheet with overridden rules for branding the login page or iframe:

  1. Create your own .css style sheet.
    See the default style sheet here: https://idp.go.nexusgroup.com/wa/css/style-v2.css
  2. Give the file the same filename as mentioned in the 404 error message, for example:

    Example: .css file name
    www.mywebapp.com Swedish Mobile BankID dga5st2nq6s4nvq.css
  3. Provide the .css file to Nexus. Ask your Nexus contact person for details.