Skip to main content
Version: 7.2405.x.x LTS

Authentication processing AuthStates and state flow

In nevisAuth, the authentication operations configured are modeled as a state flow. A new user session is associated with a starting state by the dispatching algorithm (see Initial request-dispatching. The session will then progress from one state to another, as defined by configured transitions (see AuthState results and transitions). In turn, each state is processed and returns one of a known list of possible results: identifiers that trigger either the flow to another state or remain in the same state.

State may also be configured to send a response to the user under specific circumstances. In some cases, the processing of the state will be skipped entirely and a response will be sent right away or a transition to another state will be made (see The final flag and Input processing). The following chapters explain the underlying mechanism in detail.

Initial request-dispatching

The client addresses the domain dispatcher by providing the authentication domain that should be used to validate authentication requests.

info

For this purpose, nevisProxy sends the Realm attribute value configured in the IdentityCreationFilter.

The dispatcher selects the matching authentication domain (or uses the default domain if none can be found) and selects the AuthState to invoke as follows. The dispatcher

  1. Checks the authentication session for the next AuthState to process. It is stored when stateful dispatching is used (see Authentication processing) and a previous authentication request processing triggered a transition to this other AuthState.
  2. Selects the AuthState based on the current authentication method (authenticate, stepup, logout, ...) and the most specific URL selector (selector="/resource"). By default, the URL selector checks the initial request resource (i.e., the URL that was requested during the authentication operation). This default behavior can be changed by specifying the attribute resource or by changing the default expression via JAVA_OPTS: -Dch.nevis.esauth.dispatch.resource=\${request:currentResource}
  3. Selects the AuthState, based on the current authentication method and an input argument, provided by the login-renderer or user (selector="${inargs:takeAlternateLoginPath}").
  4. Selects the AuthState, based on the current authentication method.

The following list shows the configuration attributes for the Domain element:

  • Domain required multiple are configurable

    • name (String, required, -)

      The name used to address this domain.

    • default (Boolean, optional)

      Default value: true

      If set to true, incoming requests with no matching domain will be dispatched by this domain.

      info

      Pay attention to the following:

      • Only one domain may be configured as default domain.
      • If no domain is configured as default domain, then the first domain configured will act as default domain.
    • inactiveInterval (Integer, optional, 3601)

      Default value: 3601

      Inactivity interval hint (in seconds) to send to nevisProxy. If this interval elapses without user interaction, the authentication will be revoked.

    • reauthInterval (Integer, optional, 1801)

      Default value: 1801

      Re-authentication interval hint (in seconds) to send to nevisProxy. If this interval elapses without user interaction, the authentication will be locked and the next user request will trigger an unlocking procedure.

    • statelessAuth (Boolean, optional, false)

      Default value: false

      If set to true, all user sessions will be dropped after each response. This behavior may be used for one-pass, non-interactive authentications where no follow-up processes are needed and explicit logouts are not expected. This is typically used in combination with the WS-Trust authentication facades.

      info

      Using this attribute in conventional domains may result in miscommunication between nevisAuth and nevisProxy. The issue is that there are certain properties of the SecToken which are expected by nevisProxy, but not necessarily populated by nevisAuth in a statelessAuth domain. Such an example is the property domain in the SecToken. To get around this - in domains where statelessAuth is set to true -, it is recommended to create a TokenAssembler for the domain and hardcode the domain value there, to make sure it is included in the SecToken.

      Example configuration
      <TokenAssembler name="StatelessToken">
      <Selector default="false" domain="StatelessRealm" />
      <TokenSpec ttl="28800">
      <field src="const" key="StatelessRealm" as="domain"/>
      ...
      </TokenSpec>
      <Signer key="Signer_StatelessToken"/>
      </TokenAssembler>
    • issueToken (Boolean, optional, true)

      Default value: true

      When disabled, nevisAuth will not generate a SecToken when an authentication operation has been completed successfully. Use this option to improve performance in cases where the client does not need a SecToken. Setting issueToken to false probably only makes sense if statelessAuth is enabled.

    • resetAuthenticationCondition (String, -)

      Default value: not set

      Condition for resetting all authentication-relevant values of the session and restarting of the state dispatching. See the section about Authentication conversations.

    • selector (String, -)

      Configures the selector that should be used to decide which domain to use. Usually specifies a URL path, e.g., /nevis/login, but could also be an expression, e.g., ${inargs:SAMLResponse}. When the URL path is used, the path is checked against a resource expression The default resource expression is ${request:resource}. It can be changed globally with the system property ch.nevis.esauth.dispatch.resource or locally by specifying the attribute resource, e.g., resource="${request:currentResource}".

    • resource (String, -)

      Locally defines the resource expression used for path dispatching. The default is ${request:resource} if not specified otherwise with the system property ch.nevis.esauth.dispatch.resource.

The final flag

The final attribute of an AuthState can be activated to ensure that the defined GUI is always displayed first when transitioning into the AuthState. In this case, inputValidation and processing of the state are skipped entirely.

info

The final flag has no impact on the initial AuthState of a domain dispatching. An initial AuthState will always pass through inputValidation and, if successful, will always be processed, even if final="true" is configured.

The purpose of presenting the defined GUI is to request interaction from the user, e.g., awaiting user data sent through an HTML form. When the engine receives the subsequent request, it continues its execution at the state that displayed the GUI, or, if resumeState is set to false, at a previous state. If this state has its resumeState flag set to false, subsequent requests will continue at a previous state stored in the session. The flag resumeState is set to true by default.

Input processing

The input processing of nevisAuth provides a basic integrity check and validation for user requests. This enables an early detection of input errors and can help to prevent the submission of malicious data through form parameters. The input processing itself involves the following stages:

  • Input parameter check

    When a request is received, the input validation reads the name of the incoming form and compares it to the configured GUI element in the esauth4.xml. In this stage, nevisAuth ensures that all mandatory fields are present.

  • Transition handling

    If a dispatching type is found, e.g., a checkbox, radio button, submit or reset button, the transition is set to the GUI element name or to ${GUI element name}-${received value}, but only if the value is equal to the value of the checkbox that was sent in the last response. This prevents false transitions through input value manipulation. For details about the dispatching, see the section Defining transitions through buttons and checkboxes.

  • Input validation

    Next, the content of the input is validated. Three attributes can be configured in the GUI element to allow input validation: length, format and validation.

Input validation

The input validation of nevisAuth for GuiElements consists of three parts, which can be configured with the length, format, and validation attribute. See also the following table.

  • length (Integer, optional, 255)

    Example: 100

    The maximum length of an input value; the default maximum length is 255 characters.

  • format (String, optional, -)

    Example: E-mail:^[a-zA-Z.0-9+_%-.]@[a-zA-Z0-9+_%-.]+\.[a-zA-Z0-9_%-.]+$

    A regex that must be matched before the input value gets processed.

  • validation (String, optional, -)

    return parseInt(this.value) > 0
    this.value != this.defaultValue
    this.value == this.form.elements['email'].value

    A JavaScript expression that validates the user input on client and server side.

    The JavaScript evaluation has to return a boolean indicating whether the validation was successful or not. Expressions without an explicit return statement (i.e., this.value != this.defaultValue) get automatically wrapped into a JavaScript function:

    var res = function() {
    return this.value != this.defaultValue;
    }.call(doc.forms.theGui.email);

    Optionally, further JavaScript libraries can be made available through the following JAVA_OPTS parameter: -Dch.nevis.esauth.JavaScript.libs

    In case of a validation error, nevisAuth behaves as follows:

    1. Stores the validation error in the notes scope *input.<input-name>.invalid For example: notes:input.isiwebuserid.invalid = true
    2. Sets the transition to <input-name>-validation-failed. For example: isiwebuserid-validation-failed. If such a transition is not configured, nevisAuth continues with the next step.
    3. Sets the transition to validation-failed. If such a transition is not configured, nevisAuth continues with the next step.
    4. Generates and displays the GUI with appropriate warn messages in the browser. The attribute validationMessage enables an individual configuration of this message.

AuthState results and transitions

Having passed inputValidation, the AuthState itself is executed. The engine will call the process method. If it is not overloaded by an implementation in the AuthState class, then the base AuthState class will call the method.

The process method of the base AuthState class will dispatch calls to the methods authenticate, logout, stepup, stepdown and unlock, depending on what the entry method of the request was. Those methods can be overloaded by the specific AuthState. If the AuthState itself does not contain an implementation for the method, the base AuthState class will throw an exception indicating that the method is not implemented, or it will delegate to another method (e.g., unlock delegates to authenticate).

Structure of a typical *AuthStates* configuration
<AuthState name="MyLogin" class=".." final="false">
<ResultCond name="ok" next="AuthDone" authLevel="auth.weak"/>
<Response value="AUTH_ERROR">
<Gui name="MyDialog" label="MyDialog.title">
<GuiElem name="error" type="text" label="${notes:lasterrorinfo}"
value="${notes:lasterror}"/>
<GuiElem name="loginid" type="text" label="MyDialog.loginid.label"/>
<GuiElem name="password" type="text" label="MyDialog.password.label"/>
</Gui>
<Arg name="my.outarg" value="${inargs:loginid}"/>
</Response>
<property name="myprop" value="${sess:a.value}"/>
</AuthState>
info

The order of the AuthStates parameters in the XML configuration has no influence on the parsing order and the value evaluation. It is not guaranteed that the system parses the configuration parameters of AuthStates in the order they are represented in the XML configuration.

After processing an authentication request in an AuthState, the result (set by the AuthState implementation) is used to make a transition to the next AuthState to process (if non-final) or generate (the GUI, if final). These transitions are configured as with the ResultCond element, and additional qualifiers may be specified.

Example: If an AuthState sets the result ok (signaling successful processing of the authentication request), transitions can be configured as follows:

  • ok

    Unconditional transition for the specified result.

  • ok:/resource

    Conditional transition, if the request is processed in the context of the specified resource (e.g., the URL the user accesses).

  • ok:SSO1

    Conditional transition, if the request is processed in the context of the specified domain (authentication realm). This is helpful to reduce redundancy if multiple authentication domains are implemented in a single nevisAuth instance. Understanding a configuration like this is more challenging.

  • ok:${sess:user.email}

    Conditional transition, if the request can evaluate the expression to a string that is non-empty and not equal to "false".

  • authenticate:ok

    Conditional transition, if the authentication method is authenticate.

  • SOAP:ok

    Conditional transition, if an AuthState is used by users (via a browser) and technical clients (e.g., a web-service client) at the same time and, e.g., the technical client is not able to perform additional authentication steps or the error handling is solved differently. The SOAP condition triggers when a client sends the HTTP SOAPAction header.

The list shows the attributes of the AuthState element and its subelements.

  • AuthState optional element, multiple are configurable

    Name to use for addressing in the Domain and ResultCond elements.

    • class required

      Class extending AuthState that handles processing (and optionally inputValidation and session finishing) for this AuthState. AuthStates are described in Authentication Plug-ins (AuthStates).

    • authLevel (String, optional, -)

      If the AuthState is processed, this authentication level is set before doing the transition to the next AuthState (only if the level was not set by the implementation already).

      caution

      Setting the authLevel in this manner (on an AuthState) is discouraged. It is difficult for the AuthEngine to guess if the result of an AuthState represents success or failure and whether the configured authLevel should be set or not. In some cases, using this syntax can result in users receiving wrong authLevel.

    • final (Boolean, optional, true)

      Default value: true

      See the sections The final flag and Authentication conversations.

    • classPath (String, optional, -)

      Colon-separated list of paths that forms the ClassPath in which the AuthState is loaded and executed. If left undefined, the ClassPath of the AuthEngine is used. See also Classpath configuration.

    • classLoadStrategy (String, optional, -)

      Default value: PARENT_FIRST

      One of PARENT_FIRST, PARENT_LAST

      ClassLoading strategy for the ClassLoader specific to the AuthState. This specifies whether the parent ClassLoader (the ClassLoader of the AuthEngine) is to be consulted before or after the AuthState ClassLoader. See also Classpath configuration.

Transition limit

caution

To prevent infinite loops due to misconfiguration, the AuthEngine limits the number of transitions that can be made when executing an AuthState method (authenticate, logout, stepup, stepdown or unlock). The limit is set at 100 transitions (including self-targeted transitions). When this limit is reached, the AuthEngine halts the execution.

The transition counter is reset for every call to nevisAuth (on every HTTP request). So if an authentication flow requires multiple subsequent calls to nevisAuth, the transition limit is scoped to every individual call and not to the sum of all of them.

Defining transitions through buttons and checkboxes

It is possible to define transitions through submit, reset and radio buttons or checkboxes. During the input validation, nevisAuth checks whether the transitions ${gui_element_name}-${value} (only for radio buttons and checkboxes) or ${gui_element_name} exist. Suppose you configured a GuiElement

<GuiElem name="submit" type="submit" label="submit.button.label" value="Continue"/>

then your AuthState may contain a ResultCond element:

<ResultCond name="submit" next="IdmGetPropertiesState"/>

If a user clicks on Continue, the submit transition will be triggered.

For radio buttons and checkboxes, transition handling is similar. If the following GuiElements are configured:

<GuiElem name="loginMethod" type="radio" label="Login with Password" value="PW"/>
<GuiElem name="loginMethod" type="radio" label="Login with Certificate" value="CERT"/>

Then the AuthState may contain the following Result elements:

<ResultCond name="loginMethod-PW" next="LoginPassword"/>
<ResultCond name="loginMethod-CERT" next="LoginX509Certificate"/>

Depending on whether the user checked the first or the second radio button, the first or second transition will be triggered. Checkboxes work similar to radio buttons. However, if multiple checkboxes were selected and multiple checkboxes contain transitions to other AuthStates, only the transition configured for the first checkbox will be triggered.

Response generation

The following table lists the attributes of the Response element and its subelements.

  • Response required, exactly one

    • value (String, required)

      The value specifies what authentication status is valid after generating the response. It signals to the client, if the authentication continues or is finished:

      • AUTH_CONTINUE

        Ask further input from the client and continue processing authentication requests.

      • AUTH_ERROR

        Terminate authentication operation with a failure and signal startover to the client (nevisProxy clears the authentication state when receiving this. The authentication resets).

      • AUTH_DONE

        Authentication operation is finished successfully. The client should establish an authenticated context.

  • Gui optional, multiple are configurable

    • name (String, required, -)

      An AuthState may just set a GUI name to be used for input. The content of the GUI is configured. The name can be tagged to support the selection of different GUI descriptors for different context. These tags are:

      • <method:>GuiName Authentication method selector (one of authenticate, unlock, stepup, ...)
      • SOAP:GuiName The client is a web service client.
      • CERT:GuiName The client has used an X509 certificate for authentication.
      • GuiName:/resource The client was intercepted on the URL/resource. Note that /resource and /resource/ are treated as different resources.
      • GuiName:<domain> The authentication is performed in the specified authentication domain.
    • label (String, optional, -)

      Can be used by the login renderer to render a title. See Language support for further details.

  • GuiElem optional, multiple are configurable

    • name (String, required, -)

      The name of the input field which the AuthState expects for further processing.

    • type (String, required, -)

      The type of the GUI element which the login renderer should display to the user:

      • error, info: Information or error text to be displayed to the user. No input required.
      • text: Normal input field$
      • pw-text: Input field with obfuscation
      • hidden: Hidden context to be sent back by the client
      • checkbox, radio, select: Selection input fields
      • button, submit, reset: Command buttons
      • image: Image link where value denotes the image location
    • label (String, optional, -)

      Can be used by the login renderer to render a title. See Language support for further details.

      The label attribute supports Java EL expressions.

    • value (String, optional, -)

      Default value for the GUI element. This value can contain a constant or an expression. See Configuration expressions.

    • checked (Boolean, optional, false)

      Default value: false

      Default state for selection elements (radio and checkbox).

    • optional (Boolean, optional, false)

      Default value: false

      Specifies if an input value is optional or required.

    • length (Integer, optional, 255)

      Default value: 255

      Maximum length of the user input, checked during input validation.

    • format (String, optional, -)

      RegularExpression that is used to validate the input for this GuiElem.

    • escapeXSS (Boolean, optional, false)

      Default value: false

      Set to true to apply basic XML/HTML-escaping to the value of the GuiElem. This is a protection against XSS attacks targeting login form fields.

    • validation (String, optional, -)

      A JavaScript expression that is used on both the server-side and, optionally, the client-side to validate the value of the GuiElem.

    • validationMessage (String, optional, -)

      A message or label to display if the input validation has failed.

    • renderElement (String, optional, true)

      Default value: true

      Defines whether the GuiElem will be rendered as HTML element. This controls whether the HTML element will be shown at all. If the value evaluates to false the element will not be sent to nevisLogRend. The attribute supports Java EL expressions.

      Note that if the value evaluates to any other value than false, the element will be rendered.

      Examples
      <GuiElem name="render" type="text"  label="render me" value="1" renderElement="true"/>
      <GuiElem name="donotrender" type="text" label="don't render me" value="2" renderElement="false"/>
      <GuiElem name="renderbasedoncomparision" type="text" label="render me based on inargs values" value="3" renderElement="#{inargs.get('value1') == inargs.get('value2')}"/>
      <GuiElem name="renderbasedoninargs" type="text" label="render me if inargs not empty" value="4" renderElement="#{not empty inargs.get('value1')}"/>
  • GuiGroup optional, multiple are configurable

    Defines a gui group. As it shares common attributes with GuiElem, refer to GuiElem for additional details.

    • name (String, required, -)

    • type (String, required, "select")

    • label (String, optional, -)

    • format (String, optional, -)

    • renderElement (String, optional, true)

    • validation (String, optional, -)

    • validationMessage (String, optional, -)

    • multiple (Boolean, optional, false)

      Defines if multiple option elements can be selected, this will lead to either Radio buttons or checkboxes being rendered.

  • Arg optional, multiple are configurable

    • name (String, required, -)

      Output argument name to be sent to the client. Usually, output is only meaningful on AUTH_DONE. The corresponding output can be used by nevisProxy to propagate authentication data to the application back end (see DelegationFilter).

    • value (String, required, -)

      The value for this argument. The content is a string that may contain variables. See Configuration expressions