When it comes to access control, Orbeon Forms leverages and delegates as much as possible to your existing security infrastructure:
- You define users and roles outside of Orbeon Forms.
- Whenever possible, access control is path-based, so you can define who can access what based on the path in the URL with your existing security infrastructure.
You can have access control at two levels:
- Form level – Can the current user access this form?
- Field level – If the current user can access the form, can they access a particular field? If they can, can they change the field or just read its value?
You implement the later in your form definition, by using the
in the in the visibility
XPath expressions of the Form Builder control validation dialog
. You can make a control non-visible to the current user by defining a visibility
expression that returns false. If the control is visible, you can make it read-only to current user by defining a read-only
expression that returns true. The rest of this page focuses on form-level access control.
Accessing the username and roles
- Username/role from headers or container — Orbeon Forms automatically adds two headers, which are available within Orbeon Forms applications, in particular Form Runner:
Orbeon-Username — if present, the value contains the current username
oxf.fr.authentication.method == "container":
- obtained through the servlet/portlet container's
- if oxf.fr.authentication.method == "header"
- obtained via the header specified by oxf.fr.authentication.header.username
Orbeon-Roles — if present, is a list of values, each with one role
oxf.fr.authentication.method == "container":
- each role listed in oxf.fr.authentication.container.roles is check against the container's
- if oxf.fr.authentication.method == "header"
- obtained via the header specified by
- Forwarding headers — 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.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"
- Persistence — These headers are forwarded to the persistence layer, which can make use of them. In particular, the Oracle and MySQL persistence layers stores the current username when doing any database update.
Access control for deployed forms
With Orbeon Forms 3.9
You control access to forms entirely based on paths. For this discussion, let's assume that:
- You deployed Orbeon Forms on
/orbeon. (You can choose to deploy Orbeon Forms on any context, including just on
- You have two applications (or group of forms), which correspond to two services of your company:
- HR has a number of forms including one called
Given this, here is how paths will look like:
|To create a new expense report.
|To edit an expense report having that given, system-generated id.
|To view all the submitted expense reports.
Now, consider the following access rules you might want to put in place:
|What you want
|How to implement it
|All the employes should be able to create a new expense report.
||Give access to
hr/expense-report/new to any authenticated employee.
|Only HR persons should be able to view or edit submitted expense reports.
||Restrict access to
hr/expense-report/summary to authenticated users with the appropriate "HR" role defined in your authentication system.
|Only persons in the sales department should be able to access the any of the forms in the
|Restrict access to
sales/* to authenticated users with the appropriate "sales" role defined in your authentication system.
With Orbeon Forms 4.0[SINCE 2011-07-22]
You can restrict which users can access forms you create in Form Builder
and what operations they can perform. Those restrictions apply to the
forms you create once they are deployed, not to editing those forms in
Form Builder (for the latter, see the section that follows: Access control for editing forms
Access control is role-based: you define what roles users must have to perform certain operations. By default, no restriction is imposed on who can do what with forms you create in Form Builder. You enable role-based permissions by going to the Form Builder sidebar, and under Advanced
, clicking on Set Permissions
. This shows the following dialog:
After you click on the checkbox, you'll be able to set access restriction on the create
, read, update
, and delete
permissions. On the first line, set the operations allowed to all the users who can access the form. You can also add lines, to grant more rights to users with specific roles. For instance, the following configuration, authorizes:
- Any user to fill out a new form.
- Users with the role clerk to read data.
- Users with the role admin to do any operation, including deleting form data.
When you select a checkbox for a given operation on the first Anyone
row, that checkbox will be automatically checked and disabled so you can't change it, for any additional row, since you wouldn't want to authorize users with additional roles to perform less operations.
Which operations the current user can perform drives what page they can access, and on some pages which buttons are shown:
- On the Form Runner home page, all the forms on which the current user can perform at least one operation are displayed. Then, for each one of those forms:
- If they can perform the create operation on the form, a link to the new page is shown.
- If they can perform any of the read, update, or delete operation on the form, a link to the summary page for that form is shown.
- For the summary page:
- Access is completely denied if the current user can't perform any of the read, update, or delete operations.
- The delete button is disabled if the current user can't perform the delete operation.
- The review and pdf button are disabled if the current user can't perform the read operation.
- Clicking in a row of the table will open the form in edit mode if the current user can perform the update operation, in view mode if they can perform the read operation, and do nothing otherwise.
- For the view page, access is denied if the current user can't perform the read operation.
- For the new page, access is denied if the current user can't perform the create operation.
- For the edit page, access is denied if the current user can't perform the update operation.
Role-based permissions you set in Form Builder can only be driven by container-based roles. At this point it doesn't support header-driven roles, ignoring the value of the
Access control for editing forms
Access to Form Builder as a whole
Given the assumptions made in the previous section, the paths used by Form Builder look as follows:
|To create a new form.
|To edit a form having that given, system-generated id.
|To view all the editable forms.
If you have multiple classes want to give access to Form Builder to one class of users, and those users are able to edit any form in any app, the you can use path-based access restrictions, as described the previous section.
Access to specific apps/forms in Form Builder
If you'd like to have multiple classes of Form Builder users where some case edit, say, form in the
app, while other can edit forms in the
app, then you'll want to setup the
NOTE: [SINCE 2011-09-07] The file is now called form-builder-permissions.xml file. It replaces the file called form-runner-roles.xml. For backward compatibility, form-runner-roles.xml is still supported.
In this file you map role names to applications and forms. For instance, the following tells Orbeon Forms that only users with the role
hr-form-editor can edit or create forms in the
hr app, and only users with the role
sales-form-editor can edit or create forms in the
sales app. As you can infer from the syntax, you could be even more specific and only give access to users with a given role to a specific form in a specific app.
<role name="hr-form-editor" app="hr" form="*"/>
<role name="sales-form-editor" app="sales" form="*"/>
Orbeon Forms can infer the roles for the current user either based on information it gets from the container or from an HTTP header. Those two cases are detailed in the following two sections. Once you've defined your
and done the appropriate setup for container-driven or header-driven roles, as described below:
- The Form Builder summary page will only show the forms users have access to.
- When they create a new form, if users don't have the right to create a form in any app, instead of seeing a text field where they can enter the application name, they will see a drop-down listing the possible application, as shown in the following screenshot:
Restrictions on the form name in
are at this point not supported; only restrictions on the app name are supported. This means that you should always use
. If you define a restriction on the form name, it won't be enforced at the time the form is created, allowing users to create, save, and publish a form with an undesirable name. However they then won't be able to see the form they created when going back to the summary page.
You want to use container roles if your users are setup at the application server level, with container managed security. In Tomcat, this would correspond to using a security realm
, which in its simplest form gets users from Tomcat's
. To setup container-driven roles, configure your
as described above, then:
- Enable container-driven roles — To do so, set the following property in your
<property as="xs:string" name="oxf.fr.authentication.method" value="container"/>
- 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, which if you have
form-builder-finance will look like:
<property as="xs:string" name="oxf.fr.authentication.container.roles"
- 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-hr, or the two roles
form-builder-finance. In Orbeon Forms
web.xml, add the following to require users to login to access Form Builder. This assumes that you're using basic authentication:
You want to use header-driven roles 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. To use header-driven roles, configure your
as described above, then:
- Enable header-driven roles — To do so, set the following property in your
<property as="xs:string" name="oxf.fr.authentication.method" value="header"/>
- Header name — Tell Orbeon Forms what is the name of the HTTP header that will
contain the roles for the current user. For instance, if that header is
<property as="xs:string" name="oxf.fr.authentication.header.roles" value="My-Roles-Header"/>
- 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 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
<property as="xs:string" name="oxf.fr.authentication.header.roles.property-name" value="cn"/>