Orbeon Forms
  • Getting started
  • Installation
    • Logging
    • Configuration banner
    • Docker
    • Azure
    • Tomcat
    • WildFly
    • WebSphere
    • WebLogic
    • GlassFish
    • Caches
    • Replication
    • Upgrading
  • Configuration
    • Properties
      • General
        • HTTP client
      • Form Runner
        • Detail page
          • Attachments
          • Email properties
          • PDF
          • Table of contents
        • Persistence
        • Summary page
      • Form Builder
      • XForms
    • Advanced
      • Workflows
      • Session management
      • State handling
      • Client-side error handling
      • Clustering and High Availability
      • Configuring a Form Runner eXist database
      • Creating a production WAR
      • Environments
      • JavaScript and CSS assets
      • Limiter filter
      • Run modes
      • Security
        • Content-Security-Policy header
      • SAP Hybris Module
      • XForms logging
    • Troubleshooting
      • Troubleshooting with the orbeon.log
      • Memory and threads
      • Relational database logging
      • Misc
  • Form Builder
    • Form settings
      • Time window
    • Form editor
      • Form area
      • Toolbox
      • Buttons bar
      • Control settings
      • Dependent fields and sections
      • Validation
      • Choices editor
      • Publishing
      • Cut, copy and paste
      • Section and grid settings
      • Section settings
      • Grid settings
      • Quick control search
      • Repeat settings
      • Repeated grids
      • Undo and redo
      • Keyboard shortcuts
    • Formulas
      • Examples of formulas
      • Formulas inspector
      • Formulas console
    • Summary page
    • Form localization
    • Advanced
      • Edit source
      • Services and actions
        • HTTP services
        • Database services
        • Simple Actions
        • Action Syntax
        • Action Syntax examples
        • Synchronizing repeated content
      • Testing a form in web mode
      • Testing PDF production
      • Testing offline functionality
      • Email Settings dialog
      • Field-level encryption
      • Messages
      • Section templates
      • Template syntax
      • XML Schemas support
      • Extensibility
        • Extension API
        • Integration
        • Toolbox component metadata
  • Form Runner
    • Overview
      • Terminology
    • Pages
      • Landing page
      • Published Forms page
      • Forms Admin page
      • Summary page
    • Components
      • Alert dialog
      • Attachment
      • Autocomplete
      • Captcha
      • Character counter
      • Checkbox input
      • Currency
      • Date
      • Dropdown date
      • Static and dynamic dropdown
      • Error summary
      • Grid
      • Handwritten signature
      • Hidden field
      • Image
      • Image annotation
      • Image attachment
      • Number
      • Open selection
      • Repeater
      • Formatted Text / Rich Text Editor
      • Section
      • Single-selection tree
      • Source code editor
      • Time
      • US phone
      • US state
      • Video
      • Video attachment
      • Wizard
      • XForms inspector
      • Yes/No answer
    • Features
      • Automatic calculations dependencies
      • Datasets
      • Excel and XML import
      • Excel and XML export
      • Summary page Excel Export
      • Form definitions and form data Zip Export
      • Purging historical data
      • Lease
      • Localization
      • Supported languages
      • Mobile support
      • Multitenancy
      • Form Runner navigation bar
      • PDF production
        • Automatic PDF
        • Automatic PDF header and footer configuration
        • PDF templates
      • Responsive design
      • Revision history
      • S3 storage
      • Simple data migration
      • TIFF production
      • Versioning
      • Wizard view
      • Workflow stage
    • Persistence
      • Using a relational database
      • Relational database schema
      • Purging old data using SQL
      • Auditing
      • Autosave
      • Database support
      • Flat view
    • Linking and embedding
      • Linking
      • Java Embedding API
      • JavaScript Embedding API
      • Liferay full portlet
      • Liferay proxy portlet
      • Securing Form Runner access
      • Form Runner offline embedding API
      • Angular component
      • React component
    • Access control and permissions
      • Users
      • Login & Logout
      • Deployed forms
      • Form fields
      • Editing forms
      • Owner and group member
      • Organizations
      • Scenarios
      • Token-based permissions
    • Styling
      • CSS
      • Grids CSS
      • Automatic PDF styling and CSS
    • APIs
      • Authentication of server-side service APIs
      • Persistence API
        • CRUD API
        • Search API
        • List form data attachments API
        • Form Metadata API
        • Lease API
        • Reindexing API
        • Caching
        • Versioning
        • Revision History API
        • Zip Export API
        • Custom persistence providers
      • Other APIs
        • Connection context API
        • Duplicate form data API
        • File scan API
        • Form Runner JavaScript API
        • Generate XML Schema API
        • PDF API
        • Publish form definition API
        • Run form in the background API
      • Data formats
        • Form data
        • Date and time
        • Form definition
    • Architecture and integration
      • Architecture
      • Access form data
      • Integration
    • Advanced
      • Buttons and processes
        • Simple process syntax
        • Core actions
        • Form Runner actions
          • Save action
          • Send action
          • Email action
        • XForms actions
        • Predefined buttons, processes and dialogs
        • Summary page buttons and processes
      • Custom dialogs/model logic
      • Services
      • Singleton form
      • Monitoring HTTP requests
  • XForms
    • Core
      • Attribute Value Templates (AVTs)
      • Binds
      • Validation
      • Variables
      • Keyboard focus
      • XForms JavaScript API
      • Error handling
        • Detailed behavior
      • Model-Bind variables
      • XForms 2.0 support
    • Events
      • Standard support
      • UI refresh events
      • Keyboard events
      • Extension events
      • Extension context information
      • Other event extensions
    • Actions
      • Repeat, insert and delete
      • Scripting actions
      • Extensions
    • Controls
      • Label, hint, help
      • Input
      • Output
      • Text area
      • Button
      • Upload
      • Dialog
    • Submission
      • Standard support
      • JSON support
      • Asynchronous submissions
      • Caching extension
      • Other submission extensions
    • XPath
      • Type annotations
      • Expression analysis
      • Tips
      • Compatibility
      • Standard functions
      • Maps and arrays Functions
      • Extension functions
        • Core functions
        • Utility functions
        • Model functions
        • Controls functions
        • XML functions
        • JSON functions
        • HTTP functions
        • Form Runner functions
        • Other functions
        • Deprecated functions
    • XBL components
      • FAQ
      • Guide
        • XBL Tutorial
        • Bindings
        • XForms models
        • Including content
        • Event handling
        • Conventions
        • Map XBL example
        • Learning from existing components
      • Advanced topics
        • XBL Modes
        • JavaScript companion classes
        • XBL library
        • Extensions
        • Attachment controls
    • XForms tutorial
      • Introduction
      • Installation
      • The Hello application
      • The Bookcast application
        • The basic app
        • Database access
        • Polishing the app
        • Adding a feed
    • Using XForms from Java apps
  • XML Platform
    • Page Flow Controller
      • Basics
      • XML submission
      • Navigating between pages
      • Paths and matchers
      • Other configuration elements
      • Typical combinations of page model and page view
      • Examples
      • Authorizing pages and services
    • Processors
      • URL generator
      • Request generator
      • PDF to image converter
    • Resources
      • Resource managers
      • Setting up an external resources directory
    • Other
      • Binary and text documents
  • FAQ
    • Licensing
    • PE and Dev Support
    • Form Builder and Form Runner
    • Resources and support
    • Other technical questions
  • Contributors
    • Automated tests
    • Building Orbeon Forms
    • Localizing Orbeon Forms
    • Validation functions
    • Contributor License Agreement
  • Release notes
    • Orbeon Forms 2022.1.9
    • Orbeon Forms 2024.1.1
    • Orbeon Forms 2023.1.7
    • Orbeon Forms 2024.1
    • Orbeon Forms 2023.1.6
    • Orbeon Forms 2023.1.5
    • Orbeon Forms 2021.1.11
    • Orbeon Forms 2022.1.8
    • Orbeon Forms 2023.1.4
    • Orbeon Forms 2023.1.3
    • Orbeon Forms 2023.1.2
    • Orbeon Forms 2022.1.7
    • Orbeon Forms 2023.1.1
    • Orbeon Forms 2023.1
    • Orbeon Forms 2022.1.6
    • Orbeon Forms 2021.1.10
    • Orbeon Forms 2022.1.5
    • Orbeon Forms 2021.1.9
    • Orbeon Forms 2022.1.4
    • Orbeon Forms 2022.1.3
    • Orbeon Forms 2021.1.8
    • Orbeon Forms 2022.1.2
    • Orbeon Forms 2022.1.1
    • Orbeon Forms 2022.1
    • Orbeon Forms 2021.1.7
    • Orbeon Forms 2021.1.6
    • Orbeon Forms 2021.1.5
    • Orbeon Forms 2021.1.4
    • Orbeon Forms 2021.1.3
    • Orbeon Forms 2021.1.2
    • Orbeon Forms 2021.1.1
    • Orbeon Forms 2021.1
    • Orbeon Forms 2020.1.6
    • Orbeon Forms 2019.2.4
    • Orbeon Forms 2019.1.2
    • Orbeon Forms 2018.2.5
    • Orbeon Forms 2018.1.4
    • Orbeon Forms 2020.1.5
    • Orbeon Forms 2020.1.4
    • Orbeon Forms 2020.1.3
    • Orbeon Forms 2020.1.2
    • Orbeon Forms 2019.2.3
    • Orbeon Forms 2020.1.1
    • Orbeon Forms 2020.1
    • Orbeon Forms 2019.2.2
    • Orbeon Forms 2019.2.1
    • Orbeon Forms 2019.1.1
    • Orbeon Forms 2019.2
    • Orbeon Forms 2019.1
    • Orbeon Forms 2018.2.4
  • Release history
  • Use cases
  • Product roadmap
  • Index of features
Powered by GitBook
On this page
  • Providing information about the user
  • Why Orbeon Forms might need user's information?
  • Container-driven or header-driven, which to choose?
  • Container driven method
  • OIDC with WildFly
  • Header-driven method
  • Overview
  • Individual headers or single header with JSON?
  • When to set the headers
  • Enable header-driven method
  • If using individual headers
  • If using a single header with JSON
  • Beware of ModHeader
  • Accessing username, group and roles in Orbeon Forms
  • See also
  1. Form Runner
  2. Access control and permissions

Users

PreviousAccess control and permissionsNextLogin & Logout

Last updated 1 month ago

Providing information about the user

Why Orbeon Forms might need user's information?

Form Runner can use information about the user to control whether that user can access:

  • Form Builder to edit forms – for more on this, see ;

  • Deployed forms you created with Form Builder – for more on this, see .

Form Runner can obtain this information either by:

  • Calling a standard servlet API implemented by your application server, referred to as container-driven method.

  • Using HTTP headers set by a reverse proxy or a servlet filter, referred to as header-driven method.

Container-driven or header-driven, which to choose?

  1. Are you using the Liferay proxy portlet? In this case, you'll be using the header-driven method, since the Orbeon Forms Liferay proxy portlet .

  2. Otherwise, are your permissions dependent on more than users being authenticated and on their roles? In this case you need to use header-based permissions. This would for instance be the case if:

    • You are using and you need finer-grained control over what the user's group is. More specifically, with container-based permissions, users information is obtained through the servlet API, which doesn't have a notion of user's group. So in that case, Form Runner takes the first role to be the group, which is fine in certain use cases, but not in others that require more control over what the user's group is.

    • You are using , as the servlet API doesn't have any support for organizations.

  3. Otherwise, do you want to use the provided by Form Runner? If so, you'll want to go with container-based permissions, as those pages rely on facilities provided by the container to do the authentication.

  4. Otherwise, you can use either container-based or header-based permissions, going with the one that is the most convenient for you. If your information about users is stored in a system supported by your application server, e.g. you are using LDAP and Tomcat, then container-based is most likely the simplest option. If not, you could do such an integration, e.g. creating a custom security realm for Tomcat, and user container-based permissions, but it is in that case most likely simpler for you to go with header-based permissions and set headers in servlet filter or reverse proxy.

Container driven method

With the container-driven method, Orbeon Forms uses a standard API to ask the container, typically Tomcat, about the current user. Users are typically setup in a directory service, like Active Directory or LDAP, and you setup the container to interface with that directory service. With Tomcat:

In addition to the configuration at the container level, at the Orbeon Forms level, you'll want to:

  1. Enable container-driven method – To do so, set the following property in your properties-local.xml:

    <property
        as="xs:string"
        name="oxf.fr.authentication.method"
        value="container"/>
  2. List possible roles – There is no container API for Orbeon Forms to ask for all the roles for the current user; instead Orbeon Forms can only ask if the current user has a specific role. Because of this, you need to list the possible roles in the following property. For instance, if you have two roles form-builder-hr and form-builder-finance define them as:

    <property
        as="xs:string"
        name="oxf.fr.authentication.container.roles"
        value="form-builder-hr form-builder-finance"/>

    Header names are split on commas, pipes, and white space (using the regular expression ,|\s+). [SINCE Orbeon Forms 4.9] The splitting of header names can be overridden with the following property:

    <property
        as="xs:string"
        name="oxf.fr.authentication.container.roles.split"
        value=",|\s+"/>
  3. Setup groups – There is no container API for Orbeon Forms to get the user's group; in fact the concept of group is foreign the container API. So, when using container-driven method, Orbeon Forms takes the first role listed in oxf.fr.authentication.container.roles that the user has as the user's group. If you need more flexibility in determining what the user's group is, you might want to use the header-driven method instead, which allows you to explicitly set through a header what the user's group is (more on this below).

  4. Require authentication – You'll also want to have another role, say form-builder, that you grant to all the users who can access Form Builder. Hence, in our example, users will have either the two roles form-builder and form-builder-hr, or the two roles form-builder and form-builder-finance. In Orbeon Forms WEB-INF/web.xml, add the following to require users to login to access Form Builder. This assumes that you're using basic authentication:

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Form Builder</web-resource-name>
            <url-pattern>/fr/orbeon/builder/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>form-builder</role-name>
        </auth-constraint>
    </security-constraint>
    <login-config>
        <auth-method>BASIC</auth-method>
    </login-config>
    <security-role>
        <role-name>form-builder</role-name>
    </security-role>

OIDC with WildFly

[SINCE Orbeon Forms 2024.1.2]

WildFly provides native support for OpenID Connect (OIDC) using the <auth-method>OIDC</auth-method> authentication method. WildFly exposes a proprietary OidcSecurityContext as a servlet request attribute. This object contains the OIDC access token, which includes the roles as OIDC claims. If Orbeon Forms detects the WildFly-provided OidcSecurityContext, it extracts the access token to determine the user's roles, which are then used for further processing, without needing to list them in the oxf.fr.authentication.container.roles property.

Limitation: Entra ID roles are included in the OIDC tokens as IDs. Future versions of Orbeon Forms might be able to retrieve the actual names of the roles.

Header-driven method

Overview

With the header-driven method, you are responsible for, in the block labeled as "reverse proxy" in the above diagram, to:

  1. Authenticate users, preventing requests from going through to Orbeon Forms if unauthenticated access isn't authorized (e.g. redirecting users to a login page if they haven't logged in yet, or otherwise issuing a 403).

  2. Set the headers discussed below to pass information about the user to Orbeon Forms.

When using the header-driven method, as it is your reverse proxy performing that performs user authentication, and not the container, you must remove or comment out the <security-constraint> in the web.xml.

Individual headers or single header with JSON?

You can pass information about the user either using:

  • 3 headers, one for the username, one for the user's roles, and one for user's group.

  • 1 header, that contains the user's information in a JSON format specified below.

The following should help you choose whether to use individual headers or a single header with JSON:

  1. If using Orbeon Forms 2016.2 or earlier, go for individual headers. (The single header with JSON was introduced in Orbeon Forms 2016.3.)

  2. Otherwise, you can whichever technique is more convenient for you, and in most cases using individual headers might be simpler.

When to set the headers

  • [SINCE Orbeon Forms 2020.1] You should provide the headers with every request made to Orbeon Forms for which you want the user to be authenticated, including Ajax requests. If you set the authentication headers for some requests, and then stop passing them, Orbeon Forms will assume the user has logged out, and clear the user's session. You can get the behavior implemented until Orbeon Forms 2019.2 (described below), by setting the oxf.fr.authentication.header.sticky property to true.

  • [UNTIL Orbeon Forms 2019.2] When you provide information about the user through headers, Orbeon Forms stores that information in the session. So for any subsequent request in the same session, you don't need to provide the headers anymore, and in fact even if you do they will be ignored.

<property
    as="xs:boolean"
    name="oxf.fr.authentication.header.sticky"
    value="true"/>

Enable header-driven method

Whether using individual headers or a single header with JSON, in all cases you need to enable header-based permissions with the following property in your properties-local.xml:

<property
    as="xs:string"
    name="oxf.fr.authentication.method"
    value="header"/>

If using individual headers

Header names

Tell Orbeon Forms the name of the HTTP headers that contain the username, group, and roles for the current user.

<property
    as="xs:string"
    name="oxf.fr.authentication.header.username"
    value="My-Username-Header"/>
<property
    as="xs:string"
    name="oxf.fr.authentication.header.group"
    value="My-Group-Header"/>
<property
    as="xs:string"
    name="oxf.fr.authentication.header.roles"
    value="My-Roles-Header"/>

The header oxf.fr.authentication.header.roles consists of a list of comma- or pipe-separated role names (using the regular expression (\s*[,\|]\s*)+), for example:

Administrator, Power User, User

or:

Administrator | Power User | User

White space around the commas or pipes is ignored.

In addition or alternatively, multiple role headers can be provided, and each of them is split according to those roles. The resulting set of roles is the combination of all roles extracted from all role headers.

[SINCE Orbeon Forms 4.9] The splitting of header names can be overridden with the following property:

<property
    as="xs:string"
    name="oxf.fr.authentication.header.roles.split"
    value="(\s*[,\|]\s*)+"/>

Forwarding headers with 4.6 and earlier

NOTE: This step is not necessary for Orbeon Forms 4.7 and newer.

When using header-based authentication, in addition to defining the name of the headers Form Runner gets the username and role from oxf.fr.authentication.header.username and oxf.fr.authentication.header.roles, you need to add those header names to the oxf.xforms.forward-submission-headers property, so the headers are forwarded by the XForms engine to Form Runner. For instance:

<property
    as="xs:string"
    name="oxf.xforms.forward-submission-headers"
    value="My-Username-Header My-Group-Header My-Roles-Header"/>

LDAP-style header syntax

The value of the header is a list of roles separated by spaces, commas, or pipes (|). Furthermore, they can optionally be composed of properties in the form of name=value, where name is specified by a configuration property, and value is the value of the role. This is typically useful the value if the header follows an LDAP-style syntax, for instance:

cn=role1,dc=acme,dc=ch|cn=role2,dc=acme,dc=ch

If your header follows a LDAP-style syntax, set the following property to configure what "name" contains the header, which in this example is cn:

<property
    as="xs:string"
    name="oxf.fr.authentication.header.roles.property-name"
    value="cn"/>

If using a single header with JSON

Tell Orbeon Forms the name of the HTTP header that contain the user's information in JSON format:

<property
    as="xs:string"
    name="oxf.fr.authentication.header.credentials"
    value="My-Credentials-Header"/>

The value of the header must be valid JSON, and follow the format described below. An example

{
  "username"      : "ljohnson",
  "groups"        : [ "employee" ],
  "roles"         : [
                      { "name": "Power User"                                  },
                      { "name": "Full-time"                                   },
                      { "name": "Manager",      "organization": "iOS"         },
                      { "name": "Scrum master", "organization": "Engineering" }
                    ],
  "organizations" : [
                      [ "Acme", "Engineering", "iOS" ],
                      [ "Acme", "Support"            ]
                    ]
}
  • username is mandatory.

  • groups is optional. If present, its value must be an array with one string, representing the user's group. (An array is used here as we can envision futures version of Orbeon Forms supporting users being part of more than one group.)

  • organizations is optional. If present, its value must be an array. Each element of the array must in turn be an array, in which the last element is the organization the user is a member of, and preceding elements list where that organization is in the organization hierarchy. For instance, ["Acme", "Engineering", "iOS"] signifies that the user is a member of the "iOS" organization, and that, in the organization hierarchy, "iOS" is a child organization of "Engineering", and "Engineering" is a child organization of "Acme".

Beware of ModHeader

If using the ModHeader extension to test sending custom headers to Orbeon Forms, you also need to disable both JavaScript and CSS source maps in Chrome, or you'll get the following error:

SessionListeners object not found in session. OrbeonSessionListener might be missing from web.xml.

This is because, out-of-the-box, that is unless you set oxf.fr.authentication.header.sticky to true, you are expected to send the authentication headers with every request. Orbeon Forms takes missing authentication headers as a sign that you want to tell Orbeon Forms that the user logged out, and consequently Orbeon Forms kills the "previous" user's session. ModHeader sends the headers you specified with every request, except for source maps. So after Chrome makes a request for a source maps, the session is cleared, and you'll have a problem on the next request that relies on a session, like an Ajax request.

Accessing username, group and roles in Orbeon Forms

  • Username/role from headers or container — Orbeon Forms automatically adds two headers, which are available within Form Runner:

    • Orbeon-Username — if present, the value contains the current username

      • if oxf.fr.authentication.method == "container":

        • obtained through the servlet/portlet container's getRemoteUser() function

      • if oxf.fr.authentication.method == "header"

        • obtained via the header specified by oxf.fr.authentication.header.username

    • Orbeon-Group — if present, the value contains the current group

    • Orbeon-Roles — if present, is a list of values, each with one role

      • if oxf.fr.authentication.method == "container":

        • each role listed in oxf.fr.authentication.container.roles is checked against the container's isUserInRole() function

      • if oxf.fr.authentication.method == "header"

        • obtained via the header specified by oxf.fr.authentication.header.roles

See also

See for more on how to setup Tomcat with Active Directory.

See for more on how to setup Tomcat with LDAP.

OIDC providers such as can be configured to include the users' groups as roles in the OIDC tokens, which can be useful in this context.

If using you'll need to use the single header with JSON, as this is the only way to pass organization-related information to Orbeon Forms.

roles is optional. If present, its value must be an array of roles. Each role is an object with a mandatory name attribute, and an optional organization attribute. When the latter is present, it ties the role to the specified organization, for instance: "Linda is the manager of the iOS organization". For more on the latter, see .

Persistence — These headers are forwarded to the persistence layer, which can make use of them. In particular, the store the current username when doing any database update.

See also .

- Optional user menu for providing links to login and logout functions.

- How to control access to deployed forms.

- How to control access to specific form fields based on the user's roles.

- How to control access to Form Builder.

- Access based on ownership and groups.

– Access based on organizational structure.

- Token-based permissions

Tomcat's Windows Authentication How-To
Tomcat's JNDIRealm
Microsoft Entra ID
organization-based permissions
Organization-based permissions
relational persistence layers
Login & Logout
Access control for deployed forms
Form fields
Access control for editing forms
Owner and group member permissions
Organization-based permissions
Token-based permissions
Scenarios
access control for editing forms
access control for deployed Forms
group-based permissions
organization-based permissions
login and logout pages
Accessing liferay users and roles
uses headers to pass information about the user to Form Runner