Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christinabannon/fd556a570e062dc4b08056eec2a1f179 to your computer and use it in GitHub Desktop.
Save christinabannon/fd556a570e062dc4b08056eec2a1f179 to your computer and use it in GitHub Desktop.
7/16/2019 attempt to authenticate a user in Orbeon Forms using a header-based authentication. Does not do what I would like it to do.
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Vector;
/**
* Filter which adds the configured header to every request
*/
public class RequestHeaderFilter implements Filter {
private String userNameHeader;
private String userNameValue;
private String roleNameHeader;
private String roleNameValue;
private String groupNameHeader;
private String groupNameValue;
public void init(FilterConfig filterConfig)
throws ServletException {
this.userNameHeader = "orbeon-username";
this.userNameValue = "wald-accountant";
this.roleNameHeader = "orbeon-roles";
this.roleNameValue = "wald-tax-form-runner";
this.groupNameHeader = "orbeon-group";
this.groupNameValue = "wald";
}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
System.out.println("**doFilter is happening");
HttpServletRequest request =
new EnsureHeaderPresent((HttpServletRequest) req,
userNameHeader, userNameValue,
roleNameHeader, roleNameValue,
groupNameHeader, groupNameValue);
HttpServletResponse response = (HttpServletResponse) res;
response.setStatus(200);
chain.doFilter(request, response);
response.setStatus(200);
}
// finish correcting these variables
public void destroy() {
this.userNameHeader = null;
this.userNameValue = null;
this.roleNameHeader = null;
this.roleNameValue = null;
this.groupNameHeader = null;
this.groupNameValue = null;
}
private class EnsureHeaderPresent extends HttpServletRequestWrapper {
private String uName;
private String uValue;
private String rName;
private String rValue;
private String gName;
private String gValue;
public EnsureHeaderPresent(HttpServletRequest request,
String uName, String uValue,
String rName, String rValue,
String gName, String gValue) {
super(request);
this.uName = uName;
this.uValue = uValue;
this.rName = rName;
this.rValue = rValue;
this.gName = gName;
this.gValue = gValue;
}
@Override
public String getHeader(String name) {
System.out.println("*** getHeader is being called for " + name);
String headerValue = null;
if (this.uName != null && this.uName.equals(name)) {
System.out.println("******* uValue : " + this.uValue);
headerValue = this.uValue;
}
else if (this.rName != null && this.rName.equals(name)) {
System.out.println("******** rValue : " + this.rValue);
headerValue = this.rValue;
}
else if (this.gName != null && this.gName.equals(name)) {
System.out.println("******** gValue : " + this.gValue);
headerValue = this.gValue;
} else {
headerValue = (String)super.getHeader(name);
System.out.println("******** " + name + " : " + headerValue);
}
return headerValue;
}
@Override
public Enumeration<String> getHeaders(String name) {
System.out.println("***getHeaders is being called for " + name);
ArrayList<String> headerValues = new ArrayList<>();
if (this.uName != null && this.uName.equals(name)) {
System.out.println("******** uValue : " + this.uValue);
headerValues.add(uValue);
}
else if (this.rName != null && this.rName.equals(name)){
System.out.println("******** rValue : " + this.rValue);
headerValues.add(rValue);
}
else if (this.gName != null && this.gName.equals(name)){
System.out.println("******** gValue : " + this.gValue);
headerValues.add(gValue);
} else {
headerValues = Collections.list(super.getHeaders(name));
}
return Collections.enumeration(headerValues);
}
@Override
public Enumeration<String> getHeaderNames() {
System.out.println("***getHeaderNames is being called");
Enumeration<String> headerNames = super.getHeaderNames();
ArrayList<String> all;
if (headerNames == null) {
all = new ArrayList<String>();
} else {
all = Collections.list(headerNames);
}
all.add(this.uName);
all.add(this.rName);
all.add(this.gName);
System.out.println(all);
return Collections.enumeration(all);
}
}
}
<!--
Copyright (C) 2011 Orbeon, Inc.
This program is free software; you can redistribute it and/or modify it under the terms of the
GNU Lesser General Public License as published by the Free Software Foundation; either version
2.1 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
-->
<roles>
<!--
The behavior is as follows:
- by default no <role> elements are present
- for the Form Builder Summary and New pages, this is equivalent to:
<role name="*" app="*" form="*"/>
- for the Form Runner Home page
- no <role> elements
- user cannot unpublish/publish any forms
- user cannot see unavailable forms
- with <role name="*" app="*" form="*"/>:
- user can unpublish/publish any forms
- user sees unavailable forms
This ensures:
- that Form Builder is usable out of the box even without setting Form Builder permissions
- that the Form Runner Home page, which can by default be accessed by any user unless it is explicitly
protected, does not inadvertently provide access to administrative functions
Examples:
Any user can create and administrate any form:
<role name="*" app="*" form="*"/>
User with role "orbeon-user" can create and administrate any "acme" forms:
<role name="orbeon-user" app="acme" form="*"/>
-->
<!--
WALD app's roles!
-->
<role name = "wald-tax-form-runner"
app = "wald"
form = "*"/>
</roles>
<properties xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:oxf="http://www.orbeon.com/oxf/processors">
<property
as="xs:boolean"
name="oxf.show-version"
value="true"/>
<!--This property enables using a
header-driven method ! -->
<!-- link: https://doc.orbeon.com/form-runner/access-control/users -->
<property
as="xs:string"
name="oxf.fr.authentication.method"
value="header"/>
<property
as="xs:string"
name="oxf.fr.authentication.header.username"
value="orbeon-username"/>
<property
as="xs:string"
name="oxf.fr.authentication.header.roles"
value="orbeon-roles"/>
<property
as="xs:string"
name="oxf.fr.authentication.header.group"
value="orbeon-group"/>
<property as="xs:anyURI"
name="oxf.url-rewriting.service.base-uri"
value="http://localhost:8080/orbeon"/>
<!--
<property
as="xs:anyURI"
processor-name="oxf:page-flow"
name="authorizer"
value="/orbeon-auth"/>
-->
<!-- https://doc.orbeon.com/configuration/properties/general -->
<property as="xs:anyURI"
name="oxf.url-rewriting.service.base-uri"
value="http://localhost:8080/orbeon"/>
<!-- "When Orbeon Forms performs XForms submissions,
or retrieves documents in XPL over HTTP,
it has the ability to forward incoming HTTP headers.
For example,
if you want to forward the Authorization header to your services:.." -->
<!-- https://doc.orbeon.com/configuration/properties/general -->
<property
as="xs:string"
name="oxf.http.forward-headers"
value="Authorization"/>
<!--
<property
as="xs:string"
name="oxf.xforms.forward-submission-headers"
value="orbeon-username orbeon-group orbeon-roles"/>
-->
<!--
<property as="xs:string"
name="page-public-methods"
value="GET HEAD POST PUT DELETE"
processor-name="oxf:page-flow"/>
<property as="xs:string"
name="service-public-methods"
value="GET HEAD POST PUT DELETE"
processor-name="oxf:page-flow"/>
-->
<!--
<property as="xs:anyURI" name="authorizer" value="/orbeon-auth" processor-name="oxf:page-flow"/>
-->
</properties>
<?xml version="1.0" encoding="UTF-8"?>
<web-app
version="2.4"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/j2ee">
<display-name>Orbeon Forms</display-name>
<description>
Orbeon Forms is an open source, standard-based web forms solution, which
includes Form Builder, a WYSIWYG browser-based authoring tool, and Form
Runner, a runtime environment which facilitates the deployment and
integration of a large number of complex forms. Orbeon Forms implements
different technologies, such as XForms and Ajax, with no need for
client-side software or plug-ins.
</description>
<!-- "A web application that is written so that it can be deployed in a web container distributed
across multiple Java virtual machines running on the same host or different hosts." -->
<!--Distributable when replication is enabled-->
<distributable/>
<!--Initialize main resource manager-->
<context-param>
<param-name>oxf.resources.factory</param-name>
<param-value>org.orbeon.oxf.resources.PriorityResourceManagerFactory</param-value>
</context-param>
<!--Web application resource manager for resources-->
<context-param>
<param-name>oxf.resources.priority.2</param-name>
<param-value>org.orbeon.oxf.resources.WebAppResourceManagerFactory</param-value>
</context-param>
<context-param>
<param-name>oxf.resources.priority.2.oxf.resources.webapp.rootdir</param-name>
<param-value>/WEB-INF/resources</param-value>
</context-param>
<!--Classloader resource manager-->
<context-param>
<param-name>oxf.resources.priority.6</param-name>
<param-value>org.orbeon.oxf.resources.ClassLoaderResourceManagerFactory</param-value>
</context-param>
<!--Set run mode ("dev" or "prod")-->
<context-param>
<param-name>oxf.run-mode</param-name>
<param-value>prod</param-value>
</context-param>
<!--Set location of properties.xml-->
<context-param>
<param-name>oxf.properties</param-name>
<param-value>oxf:/config/properties-${oxf.run-mode}.xml</param-value>
</context-param>
<!--Determine whether logging initialization must take place-->
<context-param>
<param-name>oxf.initialize-logging</param-name>
<param-value>true</param-value>
</context-param>
<!--Set context listener processors-->
<!-- Uncomment this for the context listener processors -->
<!--
<context-param>
<param-name>oxf.context-initialized-processor.name</param-name>
<param-value>{http://www.orbeon.com/oxf/processors}pipeline</param-value>
</context-param>
<context-param>
<param-name>oxf.context-initialized-processor.input.config</param-name>
<param-value>oxf:/apps/context/context-initialized.xpl</param-value>
</context-param>
<context-param>
<param-name>oxf.context-destroyed-processor.name</param-name>
<param-value>{http://www.orbeon.com/oxf/processors}pipeline</param-value>
</context-param>
<context-param>
<param-name>oxf.context-destroyed-processor.input.config</param-name>
<param-value>oxf:/apps/context/context-destroyed.xpl</param-value>
</context-param>-->
<!-- End context listener processors -->
<!--Set session listener processors-->
<!-- Uncomment this for the session listener processors -->
<!--
<context-param>
<param-name>oxf.session-created-processor.name</param-name>
<param-value>{http://www.orbeon.com/oxf/processors}pipeline</param-value>
</context-param>
<context-param>
<param-name>oxf.session-created-processor.input.config</param-name>
<param-value>oxf:/apps/context/session-created.xpl</param-value>
</context-param>
<context-param>
<param-name>oxf.session-destroyed-processor.name</param-name>
<param-value>{http://www.orbeon.com/oxf/processors}pipeline</param-value>
</context-param>
<context-param>
<param-name>oxf.session-destroyed-processor.input.config</param-name>
<param-value>oxf:/apps/context/session-destroyed.xpl</param-value>
</context-param>-->
<!-- End session listener processors -->
<!--Security filter for eXist-->
<filter>
<filter-name>orbeon-exist-filter</filter-name>
<filter-class>org.orbeon.oxf.servlet.TokenSecurityFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>orbeon-exist-filter</filter-name>
<url-pattern>/exist/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<!--Limit concurrent access to Form Runner-->
<filter>
<filter-name>orbeon-limiter-filter</filter-name>
<filter-class>org.orbeon.oxf.servlet.LimiterFilter</filter-class>
<!--Include Form Runner pages and XForms Ajax requests-->
<init-param>
<param-name>include</param-name>
<param-value>(/fr/.*)|(/xforms-server)</param-value>
</init-param>
<!--Exclude resources not produced by services-->
<init-param>
<param-name>exclude</param-name>
<param-value>(?!/([^/]+)/service/).+\.(gif|css|pdf|json|js|coffee|map|png|jpg|xsd|htc|ico|swf|html|htm|txt)</param-value>
</init-param>
<!--Minimum, requested, and maximum number of concurrent threads allowed-->
<!--The `x` prefix specifies a multiple of the number of CPU cores reported by the JVM-->
<init-param>
<param-name>min-threads</param-name>
<param-value>1</param-value>
</init-param>
<init-param>
<param-name>num-threads</param-name>
<param-value>x1</param-value>
</init-param>
<init-param>
<param-name>max-threads</param-name>
<param-value>x1</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>orbeon-limiter-filter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<!-- NEW -->
<!-- This filter will wrap around the incoming requests,
and add the authentication headers -->
<filter>
<filter-name>RequestHeaderFilter</filter-name>
<filter-class>RequestHeaderFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>RequestHeaderFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter>
<filter-name>orbeon-form-runner-auth-servlet-filter</filter-name>
<filter-class>org.orbeon.oxf.servlet.FormRunnerAuthFilter</filter-class>
<!--
<init-param>
<param-name>content-security-policy</param-name>
<param-value>default-src 'self'</param-value>
</init-param>
-->
</filter>
<filter-mapping>
<filter-name>orbeon-form-runner-auth-servlet-filter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<!--All JSP files under /xforms-jsp go through the XForms filter-->
<filter>
<filter-name>orbeon-xforms-filter</filter-name>
<filter-class>org.orbeon.oxf.servlet.OrbeonXFormsFilter</filter-class>
<!-- Uncomment this for the separate WAR deployment -->
<!--
<init-param>
<param-name>oxf.xforms.renderer.context</param-name>
<param-value>/orbeon</param-value>
</init-param>
<init-param>
<param-name>oxf.xforms.renderer.default-encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>-->
<!-- End separate WAR deployment -->
</filter>
<filter-mapping>
<filter-name>orbeon-xforms-filter</filter-name>
<url-pattern>/xforms-jsp/*</url-pattern>
<!--Servlet 2.4 configuration allowing the filter to run upon forward in addition to request-->
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<!--Orbeon context listener-->
<listener>
<listener-class>org.orbeon.oxf.webapp.OrbeonServletContextListener</listener-class>
</listener>
<!--Context listener for deployment with replication-->
<listener>
<listener-class>org.orbeon.oxf.xforms.ReplicationServletContextListener</listener-class>
</listener>
<!--XForms session listener-->
<listener>
<listener-class>org.orbeon.oxf.xforms.XFormsServletContextListener</listener-class>
</listener>
<!--General-purpose session listener-->
<listener>
<listener-class>org.orbeon.oxf.webapp.OrbeonSessionListener</listener-class>
</listener>
<!--Ehcache shutdown listener-->
<listener>
<listener-class>net.sf.ehcache.constructs.web.ShutdownListener</listener-class>
</listener>
<!--This is the main Orbeon Forms servlet-->
<servlet>
<servlet-name>orbeon-main-servlet</servlet-name>
<servlet-class>org.orbeon.oxf.servlet.OrbeonServlet</servlet-class>
<!--Set main processor-->
<init-param>
<param-name>oxf.main-processor.name</param-name>
<param-value>{http://www.orbeon.com/oxf/processors}pipeline</param-value>
</init-param>
<init-param>
<param-name>oxf.main-processor.input.config</param-name>
<param-value>oxf:/config/prologue-servlet.xpl</param-value>
</init-param>
<!--Set error processor-->
<init-param>
<param-name>oxf.error-processor.name</param-name>
<param-value>{http://www.orbeon.com/oxf/processors}page-flow</param-value>
</init-param>
<init-param>
<param-name>oxf.error-processor.input.controller</param-name>
<param-value>oxf:/config/error-page-flow.xml</param-value>
</init-param>
<!--Set supported methods-->
<init-param>
<param-name>oxf.http.accept-methods</param-name>
<param-value>get,post,head,put,delete,lock,unlock</param-value>
</init-param>
<!--Set servlet initialization and destruction listeners-->
<!-- Uncomment this for the servlet listener processors -->
<!--
<init-param>
<param-name>oxf.servlet-initialized-processor.name</param-name>
<param-value>{http://www.orbeon.com/oxf/processors}pipeline</param-value>
</init-param>
<init-param>
<param-name>oxf.servlet-initialized-processor.input.config</param-name>
<param-value>oxf:/apps/context/servlet-initialized.xpl</param-value>
</init-param>
<init-param>
<param-name>oxf.servlet-destroyed-processor.name</param-name>
<param-value>{http://www.orbeon.com/oxf/processors}pipeline</param-value>
</init-param>
<init-param>
<param-name>oxf.servlet-destroyed-processor.input.config</param-name>
<param-value>oxf:/apps/context/servlet-destroyed.xpl</param-value>
</init-param>
-->
<!-- End servlet listener processors -->
</servlet>
<!--This is the XForms Renderer servlet, used to deploy Orbeon Forms as a separate WAR-->
<servlet>
<servlet-name>orbeon-renderer-servlet</servlet-name>
<servlet-class>org.orbeon.oxf.servlet.OrbeonServlet</servlet-class>
<!--Set main processor-->
<init-param>
<param-name>oxf.main-processor.name</param-name>
<param-value>{http://www.orbeon.com/oxf/processors}page-flow</param-value>
</init-param>
<init-param>
<param-name>oxf.main-processor.input.controller</param-name>
<param-value>oxf:/ops/xforms/xforms-renderer-page-flow.xml</param-value>
</init-param>
<!--Set error processor-->
<init-param>
<param-name>oxf.error-processor.name</param-name>
<param-value>{http://www.orbeon.com/oxf/processors}pipeline</param-value>
</init-param>
<init-param>
<param-name>oxf.error-processor.input.config</param-name>
<param-value>oxf:/config/error.xpl</param-value>
</init-param>
</servlet>
<!-- Uncomment this for the eXist XMLRPC support -->
<!--
<servlet>
<servlet-name>exist-xmlrpc-servlet</servlet-name>
<servlet-class>org.exist.xmlrpc.RpcServlet</servlet-class>
</servlet>-->
<!-- End eXist XMLRPC support -->
<servlet>
<servlet-name>exist-rest-servlet</servlet-name>
<servlet-class>org.exist.http.servlets.EXistServlet</servlet-class>
<init-param>
<param-name>basedir</param-name>
<param-value>WEB-INF/</param-value>
</init-param>
<init-param>
<param-name>configuration</param-name>
<param-value>exist-conf.xml</param-value>
</init-param>
<init-param>
<param-name>start</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<!-- Uncomment this for the eXist WebDAV support -->
<!--
<servlet>
<servlet-name>exist-webdav-servlet</servlet-name>
<servlet-class>org.exist.http.servlets.WebDAVServlet</servlet-class>
<init-param>
<param-name>authentication</param-name>
<param-value>basic</param-value>
</init-param>
</servlet>-->
<!-- End eXist WebDAV support -->
<servlet-mapping>
<servlet-name>orbeon-main-servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>orbeon-renderer-servlet</servlet-name>
<url-pattern>/xforms-renderer</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>exist-rest-servlet</servlet-name>
<url-pattern>/exist/rest/*</url-pattern>
</servlet-mapping>
<!-- Uncomment this for the eXist XMLRPC support -->
<!--
<servlet-mapping>
<servlet-name>exist-xmlrpc-servlet</servlet-name>
<url-pattern>/exist/xmlrpc</url-pattern>
</servlet-mapping>-->
<!-- End eXist XMLRPC support -->
<!-- Uncomment this for the eXist WebDAV support -->
<!--
<servlet-mapping>
<servlet-name>exist-webdav-servlet</servlet-name>
<url-pattern>/exist/webdav/*</url-pattern>
</servlet-mapping>-->
<!-- End eXist WebDAV support -->
<!-- Uncomment this for the relational persistence, and change oracle if necessary -->
<!--
<resource-ref>
<description>DataSource</description>
<res-ref-name>jdbc/oracle</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>-->
<!-- End relational persistence, and change oracle if necessary -->
<!-- Form Runner authentication
For now, I have set it exclusively to builder,
<security-role>
<role-name>wald-tax-form-runner</role-name>
</security-role>
<security-role>
<role-name>wald-accountant</role-name>
</security-role>
<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>wald-tax-form-runner</role-name>
<role-name>wald-accountant</role-name>
</auth-constraint>
</security-constraint>
-->
<!-- The following pages and services are allowed without constraints by default -->
<security-constraint>
<web-resource-collection>
<web-resource-name>Form Runner services and public pages and resources</web-resource-name>
<url-pattern>/fr/service/*</url-pattern>
<url-pattern>/fr/style/*</url-pattern>
<url-pattern>/fr/not-found</url-pattern>
<url-pattern>/fr/error</url-pattern>
<url-pattern>/fr/login</url-pattern>
<url-pattern>/fr/login-error</url-pattern>
</web-resource-collection>
</security-constraint>
<!-- This will cause redirect from HTTP to HTTPS but not for eXist
<security-constraint>
<web-resource-collection>
<web-resource-name>Entire Application</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>eXist</web-resource-name>
<url-pattern>/exist/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
-->
</web-app>
@christinabannon
Copy link
Author

I believe now that the headers are being accepted, however the restricted resource (/fr/orbeon/builder/*) is not being accessed.

@christinabannon
Copy link
Author

Now it knows wald is able to see the forms, and shows the wald-accountant the forms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment