New "Authentication Challenge" Feature in Perspective

Tomorrow’s 8.1.16 early access build should include a new “Authentication Challenge” feature in Perspective.

The purpose of this feature is to help customers build better 21 CFR Part 11 compliant applications in Perspective. A common scenario is validating that one or more people are present (without logging out and back in for each user), before proceeding to the next step in a production workflow. For example: a plant-floor operator will attempt to initiate some action which requires a supervisor’s approval. The supervisor must digitally authenticate themselves as a part of the workflow and approve the action initiated by the plant-floor operator. The operator and supervisor typically perform these actions on the same shared client / host.

Before this new feature, building such workflows was challenging in Perspective because of Perspective’s use of IdPs. Since Perspective delegates authentication to an IdP, Perspective cannot control the authentication workflow. Also, IdPs use web-based technologies such as cookies to maintain an SSO session per web browser session. This makes it challenging to force the secondary user to login as a different user than the primary user within a single web browser session.

Authentication Challenge Action

To overcome these challenges, we introduced a new action called “Authentication Challenge”. The purpose of this new action is to redirect the client to an IdP in order to give the opportunity for a user (other than the user currently logged into the client) to login. Once this other user logs in, a special session event “onAuthChallengeCompleted” is triggered with contextual information about this user’s identity and their security levels (more about this new event below). The authentication state of the client session will remain unchanged - in other words, this other user will only be logged in for the duration of the aforementioned message handler’s execution. Those building 21 CFR Part 11 compliant applications may write an onAuthChallengeCompleted event handler to stamp an electronic signature for the temporary approving user on a “pending” action of some sort, and may use Ignition’s auditing capabilities to write the event to the audit log.

This new action has the following configuration options:

  1. IdP Name - name of the IdP that will execute the authentication challenge. If set to None, the project default IdP is used.
  2. Ask the IdP to re-authenticate users - Radio Options [Project, Enable, Disable] - If enabled, and if the IdP supports this option, the IdP will ask the user to re-enter their credentials, even if the user is already signed into the IdP. This option may be necessary when an external IdP is used since neither OIDC or SAML specs support the sort of “sessionless mode” that we are adding to the internal IdP. By default, this setting is set to Project, which uses the re-authentication setting located in the General category of Project Properties. This is the same set of options that the Login Action currently has.
  3. Timeout - an integer representing the number of minutes the system will wait in between the authentication request and the authentication response before timing out the request. If set to zero, the default of two minutes will be used as the timeout.
  4. Payload - an opaque payload that may contain any information the user wants to pass to the event handler (more below)
  5. Framing Options - how the challenge should be presented to the user’s current page
    a. Same Tab / Window - this works just like a normal IdP login / logout - user is navigated away from the client and to the IdP in the same window/tab, and once authentication is complete at the IdP, they are redirected back to the client on the page they were on last
    b. New Tab / Window - a new tab is opened in the user’s browser, leaving the current client tab open while it waits for the new tab to complete the auth challenge at the IdP. Once the user completes authentication in the new tab and is brought back to the client, the new tab is automatically closed. Mobile and workstation clients will fall back to the “Same Tab / Window” option if this option is selected because mobile and workstation clients do not support multiple tabs.
    c. Embedded Frame - the redirect to the IdP is embedded in an Iframe within the current client’s page. This is likely the most desirable option from a UI perspective, but may not be feasible with external IdPs due to the security issues that are opened up by allowing other web applications to frame the authentication process. Mobile clients will fall back to the “Same Tab / Window” option if this option is selected due to limitations in the mobile apps.

Authentication Challenge Script Function

A new system.perspective.authenticationChallenge scripting function was added which mirrors the action described above.

This new scripting function will have the following arguments:

  1. sessionId - Optional. Identifier of the session to target. If omitted, the current session will be used automatically.
  2. pageId - Optional. Identifier of the page to target. If omitted, the current page will be used automatically.
  3. idp - The name of the IdP to use for this authentication challenge. If omitted, the Project default IdP will be used.
  4. forceAuth - True if Ignition should ask the IdP to re-authenticate the user, even if the user is already signed into the IdP. False if Ignition should not ask the IdP to re-authenticate the user. If the IdP supports this option, the IdP will ask the user to re-enter their credentials, even if the user is already signed into the IdP. If omitted, the default value for this argument will fall back to the value in the Project Properties.
  5. timeout - An integer representing the number of minutes the system will wait in between the authentication request and the authentication response before timing out the request. If set to any number <= zero, the request is rejected. If omitted, the default of two minutes will be used as the timeout.
  6. payload - An opaque payload object that may contain any information. This object will be passed to the onAuthenticationChallengeCompleted session event script.
  7. framing - A string representing the type of framing that should be used. A value of “self” indicates that the same window should be used. A value of “new” indicates that a new tab should be used. A value of “embedded” indicates that an embedded iframe should be used. If omitted, the default value of “self” (same window) is used. The same limitations for “new” and “embedded” options apply here as they do for the “New Tab / Window” and “Embedded Frame” options in the auth challenge action configuration, respectively (see previous section).

onAuthChallengeCompleted Perspective Session Event

As mentioned above, the handler for this event is invoked each time the user returns from an IdP triggered by the “Authentication Challenge” action within the same session. Handlers will be invoked with the following arguments:

  1. session: The perspective project session
  2. payload: The opaque payload from the action’s initial invocation
  3. result: A Result containing the following:
    a. isSuccess(): function which returns true if the authentication challenge was a success. If true, the result type is Result.Success. If false, the result type is Result.Error.
    b. isError(): opposite of isSuccess()

Result.Success object: represents a successful authentication challenge result

  1. getContext(): function which returns a WebAuthUserContext object, which has the following properties:
    a. idp: the name of the IdP which challenged the user
    b. securityZones: a collection of the names of the security zones associated with the challenged user
    c. securityLevels: a string array of security level paths representing all of the security levels associated with the challenged user
    d. user: a WebAuthUser object which contains the following properties:
    • id: the unique identifier associated with the challenged user
    • userName: the challenged user’s username
    • firstName: the challenged user’s first name or null / None if not defined for this user
    • lastName: the challenged user’s last name or null / None if not defined for this user
    • email: the challenged user’s email address or null / None if not defined for this user
    • roles: the challenged user’s roles as a string array

Result.Error object: represents an error authentication result

  1. isGeneric(): function which returns true if the error is generic (in other words: a catch-all error scenario which is not specific). When true, the type of this object is Result.Error.Generic.
  2. isTimeout(): function which returns true if the error is due to a timeout. When true, the type of this object is Result.Error.Timeout.
  3. isCancelled(): function which returns true if the error is due to the user canceling the authentication challenge. When true, the type of this object is Result.Error.Cancelled.

Result.Error.Generic object: represents a generic error authentication result

  1. getMessage(): function which returns a diagnostic message pertaining to the generic error, or null / None if such a message does not exist

Result.Error.Timeout object: represents a timeout error authentication result

  1. getTimeout(): function which returns the integer timeout value in minutes that was used to configure the timeout which eventually got triggered

Result.Error.Cancelled object: represents a canceled error authentication result. This object has no special functions or properties at this time.

Internal IdP - Sessionless Authentication

When an authentication challenge is triggered from a Perspective client session, and the target IdP is an internal Ignition IdP, a special “sessionless” authentication flag will be set on the authentication request. The internal IdP detects this flag and enables sessionless authentication mode for the duration of the authentication challenge workflow. Sessionless authentication means that the internal IdP will ignore any existing session that exists within the current web browser session, and will force the user to authenticate no matter what. After authentication is complete, any existing session is left untouched, meaning that if a user was already logged into the IdP in the current browser session, the user will remain logged into the IdP. The authentication challenge user is only logged in for the duration of the authentication challenge. This is a proprietary IdP feature and is not currently supported by OIDC or SAML specs.

We hope you all enjoy this new feature. As usual, please reach out if there are any questions or issues with this new feature.

12 Likes

can we pass username to login page so that user need to key in only password to reduce authentication cycle time?

This is not possible right now, but we might be able to add this capability.

Which type of IdP are you using - Internal, or External? If external, is it OIDC or SAML?

HI @jspecht sorry for late reply. Its external, Microsoft AD and it uses SAML.

Can you provide documentation for your IdP which explains how the SP (Ignition) can pass the username to the IdP during login? Perhaps a sample SAML AuthnRequest as well?

Reading the SAML spec, it seems as though some IdPs might support receiving the username from the SP by looking for an optional Subject element as a child of the AuthnRequest element, but I am curious what your IdP supports...

Sorry I'm not aware of all the terms "SP", "sample SAML AuthnRequest" that you specified.
Let me explain what we expect here.
This is a simple gatepass application which we created in Vision 4 years back and now we are trying to redevelop in Perspective as we have AuthChallenge feature.

With reference to attached image, in Vision project we used to initiate inbuilt authentication popup based on the user name selected on "Approver Name" and just enter password to approve a gatepass, where as in Perspective every time approver has to key in his username and password in IdP login page, which is time consuming for approver. Everyday there will be approximate 300 passes.

So we are looking to pass the username based on the selected "Approver Name" to IdP login page to reduce the approval cycle time.

Right, I understand what you are asking for. What I need to know is whether or not your SAML IdP supports the feature that you want, and if so, what do they require Ignition to do in order to show that username on their login page? This gets into the technical details of the SAML protocol and the message structures.

Thanks @jspecht
I would like to update you that we are using AD/Internal Hybrid. Just wanted to let you know if this can simplify passing the username to login IdP.

So are you using an internal Ignition IdP (not a SAML IdP)?

Yes, i’m using an internal Ignition IdP (not a SAML IdP).

Ok, I've created a feature ticket (IGN-6703) to add a "user hint" argument to the scripting function, where you can pass a username or email or whatever your IdP uses for the user ID as a hint to the IdP, which it can use to pre-fill the user ID field on the login form.

In the case of the internal IdP built into Ignition, this would be pretty straightforward. OIDC and SAML might not be as straight-forward (SAML in particular).

2 Likes

Is there a way to hide the close button ('x' icon) from the embedded frame AuthChallenge? Seems like closing the popup from there doesn't return a result.isError() or anything, unless I am mistaken.

There is currently no way to hide the close button. Eventually, you should get a timeout result once the auth challenge has timed out.

The close button is causing me an issue that I'm hoping you can help me with. The ACCEPT/REJECT field has an authentication challenge scripting function on it, and if the authentication fails, I change the value to None (so that whatever the user selected will not get applied), if the authentication succeeded, the value that the user selected gets applied. So Authentication Challenge session script is something like this:

if result.isSuccess():
	#the value changes to whatever the user selected.
else:
	#the value changes back to None

The issue is that if I click on the close button, the 'else' part of the code does not execute and the value stays at whatever the user selects.

AuthChallengeGif

You should move the change in value to only happen after the authentication challenge completes successfully?

That's how it's currently set up. Here's the workflow.

  1. The checkbox has a change script that executes the system.perspective.authenticationChallenge scripting function. So the change in value is what's triggering the function
  2. The challenge popup opens and the user is required to enter credentials
  3. If the authentication completes successfully, the value will stay at whatever the user selects, if not, I send a message back to the "ACCEPT/REJECT" embedded view that changes the value back to the previousValue

Don't use a checkbox's change script. It obviously fires after the change happens. Use a regular button's action, and only perform the "accept" functionality when the challenge passes. Authentication failures don't and won't put anything "back the way it was". The auth challenge logic doesn't know "the way it was."

Hello , Is there a way to resize the embedded iframe ? I a smaller screen to enter the credentials.
Thanks

Yes - you should be able to grab the edges of the frame and resize.