Authentication

By default, Finsemble applications do not require authentication (i.e., user sign-on), but hooks are available for you to add an authentication component to match your specific application's needs. The Authentication Client API and underlying Authentication Service allow developers to add a custom authentication component which obliges end users to authenticate before proceeding. This API does not define a specific authentication protocol. It deals strictly with integration of authentication into the UX.

Finsemble itself is agnostic about which type of authentication you may choose to implement—the only requirement is to pass back to Finsemble the results using publishAuthorization(). If your authentication model requires handing control off to an external authentication server, then the "redirect page" you've specified to the external server must be the one to invoke publishAuthorization. Finsemble doesn't define what happens on authentication failure; it is up to the authentication component to determine how to handle failures (e.g., retry, terminate application, display error). Finsemble will simply not proceed with its start-up sequence until a successful authentication.

First, to define our terms:

  • Authentication - Checking an end user’s credentials to allow access to a system

  • Authorization - Asking another system whether an end user has been authenticated

Enabling authentication

You can have your users log in to Finsemble using a user name by password by using an authentication profile.

To do this, configure an authentication profile in your manifest-local.json. Add "startup" under "finsemble" and give it an adapter of "PASSWORD":

    "authentication": {
        "startup": {
             "adapter": "PASSWORD",
             "component": "defaultAuthentication"
         }
     }

The specified component will launch at start. You can use the existing defaultAuthentication component, which asks for username and password, or you can write your own. You must code that component to collect credentials and authenticate against your back end. Finsemble will block access to the overall application until your authentication dialog completes the process by calling AuthenticationClient.publishAuthorization. Once that function is called, the start-up process resumes.

The form of credentials required would typically be username/password, but this could be coded in any way that meets your security requirements. For instance, you can use SAML, HTTP authentication (Digest, NTLM, Negotiate, etc.), two-factor authentication, or any other schema.


The authentication start-up sequence

When a Finsemble application with authentication enabled launches, the following authentication sequence occurs:

  1. Finsemble checks for a "startup" profile. The "startup" profile tells Finsemble which authentication component to look for.

  2. The Authentication Service spawns the authentication component and waits for a response.

  3. The spawned authentication component runs developer code to authenticate the user. When complete, the developer invokes FSBL.Clients.AuthenticationClient.publishAuthorization(username, credentials) with the authenticated username and credentials. Credentials can be any object. The credentials will be available to Finsemble components that need access to it. Note that in cases where your authentication model requires handing control off to an authentication server (such as OAuth 2.0), then the "redirect page" from the authentication server should invoke publishAuthorization.

  4. Upon receiving the authentication response from the component (i.e., when publishAuthorization is invoked), the service publishes the authenticated username and credentials to all listeners on SubPub topic "Authorization" (see below).

Any Finsemble component or service can be an "authorization listener" to receive the authorization results by using the following SubPub subscription:

	RouterClient.subscribe("Authorization", function (err, response) {
		// do something with auth data contained in "response.data"
	} );

Authorization through an external authentication website

OAuth 2.0/OpenID

With OAuth, applications (such as your Finsemble app) can defer authentication to an external "identity provider" (IP). On the web, firms like Google and Facebook play the role of IP. Your firm may have its own identity service that supports OAuth. OAuth is made possible through a "shared secret" between the identity provider and the application. Behind the scenes, it is affected through a series of redirects.

Note: Finsemble’s implementation uses OAuth2 server flow (not implicit flow).

Set an authentication config. We call this an authentication profile:

"startup": {
	"adapter": "OAUTH2",

// The url of your identity provider’s login page. You can add additional query string parameters to this if necessary.
// For instance, MS ADFS sometimes requires a non-standard "resource" parameter.
// Another example would be https://accounts.google.com/o/oauth2/v2/auth?prompt=consent which controls how Google presents its OAuth page.
"authorization_endpoint": "https://openid.c2id.com/login",

// The type of OAuth request
"scope": "openid",

// This will be provided by your identity provider
"client_id": "XYZABC",

// Your OAuth server side script
"backchannel_endpoint": "https://yoursite/authenticate",

// Your redirect_uri. Use the provided oauthResponse.html located in *finsemble-seed/src-built-in/components/authentication* unless you need to modify behavior.
// In this case make a copy and fill in your business logic.
"Redirect_uri": "$applicationRoot/src-built-in/components/authentication/oauthResponse.html",

// Optionally specify which component to use to spawn this profile
"component": "defaultAuthentication"
}

If you’re familiar with OAuth, Finsemble is automatically generating the following fields: state, response_type, and redirect_uri.

startup is a special authentication profile which causes Finsemble to wait for authentication before proceeding. You can create additional profiles, and call them using AuthenticationClient.beginAuthentication(), such as when you have a third-party component which requires OAuth.

Stage 1: With this configuration in place, Finsemble display the page at authorization_endpoint as a modal when it’s launched. The end user will log in to this modal. Upon successful login, the identity provider will redirect to Finsemble’s built in OAuth component. This component will validate and process the response for the next stage.

Stage 2: Finsemble’s OAuth component will then make a post request to the URL you specified in backchannel_endpoint. This request will contain client_id, grant_type, code and redirect_url. backchannel_endpoint should point to a server page that you host which should add the client_secret, and then forward this information via a /token request to your identity provider’s token_endpoint. The results should be returned back to the Finsemble request.

Finsemble will receive the results. It will process and publish the results as "credentials" via FSBL.Clients.AuthenticationClient.publishAuthorization. If the results include an id_token then it will be decoded and parsed. The parsed variables will be made available in the credentials object. If those results include a "sub" field, then that will be set as the Finsemble user. Otherwise, the access_token will be set as the Finsemble user.

The application will start and your components can use the contents of the credentials object where needed.

Note: The client_id and client_secret should be encoded based on the specifications of your identity provider. Some require that these be base64 encoded into an HTTP header. Some can accept them as post parameters

Currently, credentials are available to all components.

During development, you can skip the server stage by including client_secret in your authentication config. This can make development easier but should not be done in production.

Using OAuth to retrieve an access_token for API usage

OAuth can be used to access third-party resources. In this scenario, the end user is presented with login credentials from the third party. Once authenticated through a series of redirects, the client application is provided with an access_token which it can use to access the third-party resources.

Create an OAuth2 profile as described above but with a specific name. You can then use AuthenticationClient#beginAuthentication to kick off the process of retrieving an access_token. When that process is complete, the callback will be returned with the access_token and other credentials. See AuthenticationClient#completeOAUTH for implementation details.

Session-based authentication

Typically, session-based authentication uses a browser cookie to store a session token. Each request back to the webserver includes the token cookie, which the webserver checks against its internal map of authenticated sessions.

When you log in through the authentication dialog, any cookies will be set for the domain where that dialog is hosted. Other components that Finsemble accesses which are hosted on that domain will automatically use that cookie. Session authentication will thus behave the way you would expect a normal web page to behave.

If you need the same session cookie to be used across domains then you should create a distributed store to share the cookie across domains.

Automatically authenticate with the user's Windows login credentials

If your organization has an authenticated network environment, you can use Integrated Windows Authentication (IWA) to automatically authenticate Finsemble using the user’s Windows login credentials.

When using Windows credentials on a trusted network, Finsemble itself does not actually play a role in authentication. Rather, authentication is requested of your servers using Chromium's Negotiate protocol. Finsemble runs on top of Electron, which uses the Chromium engine and can make use of Chromium's protocols.

The request will be fulfilled by Chromium via either Microsoft Kerberos or NTLM.

Overview of Windows authentication

The process is as follows:

  1. A Finsemble component or service requests content from your server (e.g., an HTML file, WebSocket connection, or API call).

  2. Your server responds with a request to authenticate with the Negotiate protocol specified. This is very similar to how HTTP basic or digest authorization work, but Negotiate is a protocol that is used to select the Kerberos or NTLM protocols on Windows.

  3. Chromium automatically responds with the Windows credentials if the server is on a trusted network. If your server is on the same LAN (same IP network/submask), or if your server is configured as a trusted server, then credentials will be sent (this works the same way as Internet Explorer does). Your network administrator will likely configure your end users' machines to trust your server through group policy management.

  4. The server validates the credentials by making its own connection to the Windows LAN/Kerberos server. If validated, the content will be delivered; otherwise a 503 Unauthorized message will appear.

  5. Subsequent components connecting to this server will get their content immediately because Chromium will return valid credentials for any window that connects to the same, already-authorized, domain.

Example of Windows authentication

For most use cases, you will wish to capture the user’s details and credentials or session token. This will allow you to customize their experience via Dynamic Configuration and store their data via the Storage Service.

For security reasons, the user’s credentials (used by Chromium to perform authentication) are not automatically made available through JavaScript. Therefore, you will need to implement your own custom API call on your web server infrastructure to pass users' credential or session token back to Finsemble.

To use the returned credentials, implement a basic Finsemble component. Code it to initiate the API call and publish the response with AuthenticationClient.publishAuthorization().

Default Authentication component - You can adapt the Default Authentication component (found at src-built-in/components/authentication/defaultAuthentication.html) in the seed project to use the returned credentials. Just replace the fields and login button with an automated call to your API.

To enable your authentication component, configure an authentication profile in your manifest file ( /configs/application/manifest-local.json for local development). Add the following as a property of "finsemble":

   "authentication": {
        "startup": {
             "adapter": "PASSWORD",
             "component": "defaultAuthentication"
         }
     }

Replace defaultAuthentication with the name of your customized authentication component.

Note: If all you need to simply authenticate requests to resources on your network, then you can turn off the Authentication Service (do not create a "startup" authentication profile in your config). It isn't needed.

Display a "Logging in" message

A visible window can be used to provide a "Logging in..." message to users during the authentication process. Hide it afterwards by using WindowClient.close().

Alternatively, you can hide an authentication component's window throughout the authentication process by setting window.options.autoShow = false in its component configuration.

Use Dynamic Configuration

If you wish to customize each user’s experience via Dynamic Configuration, return their individual configuration via the Authentication API call you implemented. Use ConfigClient.processAndSet() to implement the desired behavior before calling AuthenticationClient.publishAuthorization() to continue the Finsemble start-up process.


check   Finsemble is agnostic about which type of authentication you may choose to implement, but comes with hooks for you to add whatever authentication component best fits your organization's needs.
 

Further reading

The Authentication Client documentation provides additional context.

For more information on how Finsemble handles start-up, check out Finsemble's Lifecycle Events.

The following sources are useful as references for the authentication process:

This document describes the browser authentication protocols in more detail: