Setup Users for Access Control

Providing username, group, and roles

Form Runner uses the username, group, and roles to control who can access:

Form Runner can obtain information about username, group, and roles 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-driver method.

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>
    

Header driven method

You want to use header-driven method if you have a servlet filter, single sign-on software, or other system that sets the roles for the current user in an HTTP header.

1. Enable header-driven method

Set the following property in your properties-local.xml:

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

2. 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*)+"/>

3. Forwarding headers (Orbeon Forms 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"/>

4. LDAP-style header syntax (Optional)

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"/>

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
  • Persistence — These headers are forwarded to the persistence layer, which can make use of them. In particular, the relational persistence layers store the current username when doing any database update.

See also: Accessing liferay users and roles.