Tag Archive | jsf

Securing a JSF application with Java EE security and JBoss AS 7.x

A common requirement for enterprise applications is to have all JSF pages protected behind a login page. Sometimes you even want to have protected areas inside the application that are only accessible by users that own a specific role. The Java EE standards come with all the means you need to implement a web application that is protected by some security constraints. In this blog post we want to develop a simple application that demonstrates the usage of these means and shows how you can build a complete JSF application for two different roles. As the solution might look straight forward at first glance, there are a few pitfalls one has to pay attention to.

The first point we have to care about, is the folder layout of our application. We have three different kinds of pages:

  • The login page and the error page for the login should be accessible by all users.
  • We have a home page that should only be accessible for authenticated users.
  • We have a protected page that should only be visible for users of the role protected-role.

These three types of pages are therefore put into three different folders: the root folder src/main/webapp, the folder src/main/webapp/pages and the protected page resides in src/main/webapp/pages/protected:

security-web-ide

The web.xml file is the place to define which roles we want to use and how to map the accessibility of some URL pattern to these roles:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>pages</web-resource-name>
        <url-pattern>/pages/*</url-pattern>
        <http-method>PUT</http-method>
        <http-method>DELETE</http-method>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>security-role</role-name>
        <role-name>protected-role</role-name>
    </auth-constraint>
</security-constraint>
<security-constraint>
    <web-resource-collection>
        <web-resource-name>protected</web-resource-name>
        <url-pattern>/pages/protected/*</url-pattern>
        <http-method>PUT</http-method>
        <http-method>DELETE</http-method>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>
    <auth-constraint>
        <role-name>protected-role</role-name>
    </auth-constraint>
</security-constraint>

<security-role>
    <role-name>security-role</role-name>
</security-role>
<security-role>
    <role-name>protected-role</role-name>
</security-role>

As you can see we define two roles: security-role and protected-role. URLs matching the pattern /pages/* are only accessible by users that own the roles security-role and protected-role, whereas the pages under /pages/protected/* are restricted to users with the role protected-role.

Another point you may stumble upon is the welcome page. At first guess you would want to the specify the login page as welcome page. But this does not work, as the login module of the servlet container automatically redirects all unauthorized accesses to the login page. Therefore we specify the home page of our application as welcome page. This is already a protected page, but the user will get redirected to the login page automatically when he calls its URL directly.

<welcome-file-list>
    <welcome-file>pages/home.xhtml</welcome-file>
</welcome-file-list>

Now we are nearly done with the web.xml page. All we to do is to define the authentication method as well as the login page and the error page, which is shown in case the user enters invalid credentials. One has to page attention that both pages don’t include protected URLs (e.g. CSS or JavaScript files), otherwise even the access to these two pages is forbidden and the user gets an Application Server specific error page to see.

<login-config>
    <auth-method>FORM</auth-method>
    <form-login-config>
        <form-login-page>/login.xhtml</form-login-page>
        <form-error-page>/error.xhtml</form-error-page>
    </form-login-config>
</login-config>

As we are going to deploy the application to the JBoss Application Server, we provide a file named jboss-web.xml that connects our application to a security-domain:

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
    <security-domain>java:/jaas/other</security-domain>
</jboss-web>

The “other” security-domain is configured inside the standalone.xml. The default configuration requires that the user passes the “RealmUsersRoles” login module, which gets its user and role definitions from the two files application-users.properties and application-roles.properties inside the configuration folder. You can use the provided add-user script to add a new user to this realm:

What type of user do you wish to add?
 a) Management User (mgmt-users.properties)
 b) Application User (application-users.properties)
(a): b

Enter the details of the new user to add.
Realm (ApplicationRealm) :
Username : bart
Password :
Re-enter Password :
What roles do you want this user to belong to? (Please enter a comma separated list, or leave blank for none) : security-role,protected-role
About to add user 'bart' for realm 'ApplicationRealm'
Is this correct yes/no? yes

Here it is important to choose the correct realm (ApplicationRealm), as this realm is configured by default in the standalone.xml for the “other” login module. This is also the place where you provide the roles the user possesses as a comma separated list.

<form method="POST" action="j_security_check" id="">
	<h:panelGrid id="panel" columns="2" border="1" cellpadding="4" cellspacing="4">
		<h:outputLabel for="j_username" value="Username:" />
		<input type="text" name="j_username"/>
		<h:outputLabel for="j_password" value="Password:" />
		<input type="password" name="j_password"/>
		<h:panelGroup>
			<input type="submit" value="Login"/>
		</h:panelGroup>
	</h:panelGrid>
</form>

The next step is to implement a simple login form that submits its data to the login module. Note the ids of the input fields as well as the action of the form. This way the form is posted to the login module, which extracts the entered username and password from the request. JSF developers may wonder why we use a standard HTML form instead of the element. The reason for this is that the JSF form elements spans its own namespace and therefore the ids of the input fields are prefixed with the id of the form (and this form id cannot be empty).

If the user has passed the login form, we present him a home page. But the link to the protected page should only be accessible for users that own the role protected-role. This can be accomplished by the following rendered condition:

<h:link value="Protected page" outcome="protected/protected" rendered="#{facesContext.externalContext.isUserInRole('protected-role')}"/>

Last but not least we need the logout functionality. For this case we implement a simple backing bean like the following one that invalidates the user’s session and redirects him back to the login page:

@Named(value = "login")
public class Login {

    public String logout() {
        FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
        return "/login";
    }
}

As usual the complete source code can be found on github.

Advertisements

Passing SFSBs as an argument to a custom JSF component?

Have you ever developed a custom JSF component that renders an img tag? If so, you will know that this component consists at least of two parts: The first part is the implementation of UIComponent that actually renders the img tag, the second part is the servlet filter or phase listener that answers the asynchronously incoming request for the image URL. Does it work, to use a stateful session bean (SFSB) to load the image data from the database?
First of all we start with the UIComponent. As base class we choose UIOutput, which is sufficient for the current case:

@FacesComponent("EjbComponent")
public class EjbComponent extends UIOutput {
    private static final Logger logger = LoggerFactory.getLogger(EjbComponent.class);
    private static final String COMPONENT_FAMILY = "martins.developer.world.jsf.component.helloWorld";

    private enum PropertyKeys {
        statefulEjb
    };

    @Override
    public String getFamily() {
        return COMPONENT_FAMILY;
    }
    ...
}

We override the encodeBegin() method to render the img tag. We get the stateful session bean, which is passed as an argument to the component, using JSF’s StateHelper:

    @Override
    public void encodeBegin(FacesContext facesContext) throws IOException {
        ResponseWriter writer = facesContext.getResponseWriter();
        String imageSrc = createImageUrl(facesContext);
        writer.startElement("img", this);
        writer.writeAttribute("src", imageSrc, "");
        writer.endElement("img");
        Map<String,Object> sessionMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
        sessionMap.put("ejbComponent", getStatefulEjb());
    }

    public StatefulEjbLocal getStatefulEjb() {
        return (StatefulEjbLocal) getStateHelper().eval(PropertyKeys.statefulEjb);
    }

    public void setStatefulEjb(StatefulEjbLocal statefulEjb) {
        getStateHelper().put(PropertyKeys.statefulEjb, statefulEjb);
    }

The createImageUrl() method adds a parameter to the HTTP request, such that we can detect this specific request later on in the PhaseListener:

    private String createImageUrl(FacesContext context) {
        StringBuilder builder = new StringBuilder(context.getExternalContext().getRequestContextPath());
        if (builder.indexOf("?") == -1) {
            builder.append('?');
        } else {
            builder.append('&');
        }
        builder.append("ejbComponent").append("=").append("ejbComponent");
        return builder.toString();
    }

The PhaseListener has the task to detect the incoming request issued by the img tag rendered by the component above:

public class EjbComponentPhaseListener implements PhaseListener {
    private static final Logger logger = LoggerFactory.getLogger(EjbComponentPhaseListener.class);

    @Override
    public void beforePhase(PhaseEvent phaseEvent) {
        FacesContext facesContext = phaseEvent.getFacesContext();
        ExternalContext externalContext = facesContext.getExternalContext();
        String ejbComponentParameter = requestParameter.get("ejbComponent");
        if (ejbComponentParameter != null) {
            Map<String, Object> sessionMap = externalContext.getSessionMap();
            StatefulEjbLocal ejbComponent = (StatefulEjbLocal) sessionMap.get("ejbComponent");
            if (ejbComponent != null) {
                byte[] image = ejbComponent.getImage();
                HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
                ServletOutputStream outputStream = null;
                try {
                    outputStream = response.getOutputStream();
                    IOUtils.copy(new ByteArrayInputStream(image), outputStream);
                    outputStream.flush();
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                } finally {
                    IOUtils.closeQuietly(outputStream);
                    facesContext.responseComplete();
                }
            } else {
                logger.debug("Could not retrieve ejbComponent from session.");
            }
        } else {
            logger.debug("Request parameter not found");
        }
    }

    @Override
    public void afterPhase(PhaseEvent phaseEvent) {
        logger.debug("afterPhase()");
    }

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.RENDER_RESPONSE;
    }

As you see, we try to see if the currently handled request has a parameter with the name “ejbComponent”. If this is the case, we look up the SFSB from the session map, as we have put it in there before (see code for the JSF component). Now that we have a reference to the SFSB, we can use it to load the image data and pass it to the browser.
In our web application we now create a simple backing bean that holds a reference to the SFSB, which later on is passed to the component on the JSF page:

@Named
public class HelloWorldBackingBean {
    @EJB
    private StatefulEjbLocal statefulEjb;
    ...

Finally we pass the SFSB from the backing bean to the component on our JSF page:

<mdw:ejbComponent statefulEjb="#{helloWorldBackingBean.statefulEjb}"/>

If we compile and deploy the application, the JSF will render the image as expected. But there is one caveat: If the same SFSB is used to render more than one image within the same web session, the concurrent access to the SFSB is serialized as the EJB 3.1 specification demands this in section 4.3.14. This means that each invocation locks/blocks the other threads until a timeout occurs. This timeout can be given with the @AccessTimeout annotation, the default in the JBoss AS 7.x container is 5 seconds. If the waiting threads therefore have to wait too long, a ConcurrentAccessException is thrown. This may lead to sporadic failures that only happen, if the system is under load.
Sample code can be found in my github repository.

Implementing a custom JSF 2.0 component with maven

Some time ago, I have written my own custom JSF component. But at that point in time, JSF 1.0 was still up to date and the project didn’t use maven as build system. Thus, I always wanted to write a custom JSF2 component with maven. So let’s start:

First of all we setup a maven project with two modules. Here is the pom.xml file of the parent project:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>martins-developer-world</groupId>
	<artifactId>jsf-component</artifactId>
	<packaging>pom</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>jsf-component Maven Webapp</name>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.11</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>javax.faces</groupId>
			<artifactId>jsf-api</artifactId>
			<version>2.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>com.sun.faces</groupId>
			<artifactId>jsf-impl</artifactId>
			<version>2.2.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>
	<build>
		<finalName>jsf-component</finalName>
	</build>
	<modules>
		<module>jsf-component-webapp</module>
		<module>jsf-component-impl</module>
	</modules>
</project>

As you can see, we have added the JSF dependencies in the top level pom.xml, so that we inherit them in the child modules. As we will use the JBoss Application Server to test our web application, we have to set the scope for the maven dependencies to provided, so that our war file and our component jar won’t deploy them.
The implementation of our component will reside in jsf-component-impl, thus we chose jar as packaging type for this module:

<?xml version="1.0"?>
<project
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>martins-developer-world</groupId>
		<artifactId>jsf-component</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>jsf-component-impl</artifactId>
	<name>jsf-component-impl</name>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<dependencies>
	</dependencies>
</project>

Now let’s implement a Java class that extends UIOutput. I have chosen UIOutput because as a first step I just want to implement a simple helloWorld tag, that prints the first and last name given as attribute within a span element. As this component doesn’t receive any input, UIOutput it appropriate:

package martins.developer.world.jsf.component.impl;

import java.io.IOException;

import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
import javax.faces.component.FacesComponent;
import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;

@ResourceDependencies({ @ResourceDependency(name = "css/jsf-component.css", target = "head") })
@FacesComponent("HelloWorld")
public class HelloWorldComponent extends UIOutput {
	private static final String COMPONENT_FAMILY = "martins.developer.world.jsf.component.helloWorld";

	private enum PropertyKeys {
		firstName, lastName
	};

	@Override
	public String getFamily() {
		return COMPONENT_FAMILY;
	}

	@Override
	public void encodeBegin(FacesContext context) throws IOException {
		ResponseWriter writer = context.getResponseWriter();
		writer.startElement("span", this);
		writer.writeAttribute("class", "helloWorldClass", "");
		writer.writeText(String.format("Hello %s %s!", getFirstName(), getLastName()), "");
		writer.endElement("span");
	}

	public String getFirstName() {
		return (String) getStateHelper().eval(PropertyKeys.firstName, "???firstName???");
	}

	public void setFirstName(String firstName) {
		getStateHelper().put(PropertyKeys.firstName, firstName);
	}

	public String getLastName() {
		return (String) getStateHelper().eval(PropertyKeys.lastName, "???lastName???");
	}

	public void setLastName(String lastName) {
		getStateHelper().put(PropertyKeys.lastName, lastName);
	}
}

The getFamily() method is the only method that we are enforced to implement. Interesting is here the method encodeBegin(). This is the place where we implement our span tag. As it should have a CSS class attribute, we add it with the writeAttribute() method of the Writer. The two attributes of the resulting JSF tag are modelled as simple properties with getter and setter methods. The implementation of these getters and setters uses the StateHelper available in JSF 2.0. In encodeBegin() we use the getters to retrieve the value given by the user.
Interesting is also the annotation @ResourceDependencies. With this annotation we can tell the JSF framework that we have some files we depend on. In this case it is a CSS file that resides with the folder src/main/resources/META-INF/resources/css.
The annotation @FacesComponent registers this component in the boot process at the JSF framework. The given name is used in the taglib file to reference this class:

<?xml version="1.0"?>
<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee">
	<namespace>https://martinsdeveloperworld.wordpress.com</namespace>
	<tag>
		<tag-name>helloWorld</tag-name>
		<component>
			<component-type>HelloWorld</component-type>
		</component>
	</tag>
</facelet-taglib>

In this taglib file under src/main/resources/META-INF we define the available components, here only our helloWorld tag. The attributes of the tag are derived from the properties of the Java class.
Finally we want to test our newly created component. To be able to do this, we setup a simple JSF2 webapp project and add the following snippet to the web.xml, in order to declare that we want to use our custom component:

	<context-param>
		<param-name>facelets.FACELETS_LIBRARIES</param-name>
		<param-value>/META-INF/jsf-component.taglib.xml</param-value>
	</context-param>

Now we can write a simple JSF page that references our new tag:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:mdw="https://martinsdeveloperworld.wordpress.com">
<h:head>
<title>Hello JSF 2!</title>
</h:head>
<h:body>
	<h2>Hello World!</h2>
	<mdw:helloWorld firstName="Martin" lastName="Developer"/>
</h:body>
</html>

When we deploy this application to the JBoss Application Server and call the corresponding URL, we get the following HTML output:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>Hello JSF 2!</title>
	<link type="text/css" rel="stylesheet" href="/jsf-component-webapp/faces/javax.faces.resource/css/jsf-component.css" />
</head>
<body>
	<h2>Hello World!</h2>
	<span class="helloWorldClass">Hello Martin Developer!</span>
</body>
</html>

Clearly we can see the span tag with the CSS class and the output. The CSS file is referenced in the head of the HTML document.

The sources of the whole project can be found on GitHub: https://github.com/siom79/jsf-component.