Tag Archives: configuration

Remove null values from JSON object and ignore unavailable properties

The definition of web services using Spring is quite easy (see here for details), based on Jackson, the data marshalling/unmarshalling is totally hidden to the developer and it works perfectly.
But I encountered performance issues with the null values, I had to manage some classes with a lot of data, and they often contain empty values, resulting in a Json which was mainly composed of empty attributes (a lot) and it takes time to transfer it on the wire. To reduce the amount of data to transfer and then improve the response performance, it is possible to ask Jackson to include only non null values:

<bean id="jacksonObjectMapper" class="com.fasterxml.jackson.databind.ObjectMapper">
	<property name="serializationInclusion">
		<value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value>
	</property>
</bean>

Another problem raised when I tried to pass json content with attribute which were not defined in my Java classes. The most obvious option is to change the implementation to add this new parameter, but I preferred to keep it unchanged and decided to manage it globally.
That’s how I did it:

<bean
	class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
	<property name="targetObject" ref="jacksonObjectMapper" />
	<property name="targetMethod" value="configure" />
	<property name="arguments">
		<list>
			<value type="com.fasterxml.jackson.databind.DeserializationFeature">FAIL_ON_UNKNOWN_PROPERTIES</value>
			<value>false</value>
		</list>
	</property>
</bean>
<mvc:annotation-driven >
	<mvc:message-converters register-defaults="true">
		<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
			<property name="objectMapper" ref="jacksonObjectMapper"/>
		</bean>
	</mvc:message-converters>
	
</mvc:annotation-driven>

Securing Restful web services using Spring-Security

After several months of silent, I woke up… With some security interests!
The security is a common requirement on many web projects, and fortunately, Spring helps us to implement it.
The most common way to do it is just defining a set of rules and letting Spring manage the login and so on.
In this demo, I will use Spring-boot (for its simplicity) but the security configuration is exactly the same with a web application.
And to be clear, I do not have the pretentiousness that this is THE way to follow when you need to secure your web services and I am convinced that someone else found another way to do it, but this is my solution, I used it several times, and it works perfectly, so maybe it will help someone else… One day 🙂

To start simply, I just built a simple web site with 2 pages:

  • the home page (/index.html), which is freely accessible
  • and another page (/secured/page.html) which is in a restricted area

Using Spring-boot, the structure is something like:

structure

By default, Spring boot published everything under the static directory and is accessible via http://localhost:8080/

For instance, everybody can access to our pages, it’s time to remedy to that state.

Let’s start with the interesting part of the Maven Configuration:

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>1.3.2.RELEASE</version>
	<relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<java.version>1.8</java.version>
</properties>

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-security</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>
</dependencies>

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>

The starter dependencies are somehow facilitators provided by Spring boot to add some dependencies, I think that we can guess their purpose just by their name. For more information about this pom, you can have a look to the Spring-boot site.

Now, we have to restrict access to the secured part of the site, this is done here:

@Configuration
@EnableWebSecurity
public class SecurityJavaConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().
          withUser("admin").password("password").roles("ADMIN", "USER").and().
          withUser("user").password("password").roles("USER");
    }
 
    @Override
    protected void configure(HttpSecurity http) throws Exception { 
        http
        .authorizeRequests()
        .antMatchers(HttpMethod.GET, "/secured/**").access("hasRole('USER')");
        
        //indicate that we are user login form authentication
        http.formLogin();
    }
}

For the demo, I define my users directly in the application, this is AuthenticationManagerBuilder.inMemoryAuthentication().

Inside the configure(HttpSecurity http) method, you can see that I just defined the URL of the secured part, indicating who can access it based on role.
And finally, I indicate that I want to use the form login authentication as it is provided by Spring.

According to the configuration, the users can access freely the home page, but only the users authenticated and with the right role can access to the secured part. This is a perfect configuration for a standard web site, but remember that we nee to secure a web service, the redirection to a login form is not an acceptable way for that purpose and we need to customise this behavior.

The first issue to solve is to avoid to redirection to the login form in case of unauthenticated access, I do it by changing the AuthenticationEntryPoint with mine:

@Component
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
	@Override
	public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
			throws IOException, ServletException {
		response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
	}
}

As you can see, this is very simple, I just need to send the right HTTP code to inform my client that it needs to authenticate before accessing the resource it requested.
And to indicate to Spring that I slightly changed the authentication, it is very complicated because… Well, it’s Spring, so, I just need to add the following in my SecurityJavaConfig:

[...]
@Autowired
private AuthenticationEntryPoint authenticationEntryPoint;
[...]
protected void configure(HttpSecurity http) throws Exception {
	http.exceptionHandling().authenticationEntryPoint(authenticationEntryPoint);
}

Now, when someone… As we are dealing with web services,I should say something tries to access to secured resources, it just receives an unauthorized HTTP code instead of a redirection to the login page.
That’s a good point but we have also to manage the successful and erroneous authentication. Instead of redirecting to a page, we have to inform the client that the credentials are valid or not .
For each case, we need to define two different classes:

  • in case of success, we let Spring clean-up the temporary data:
    @Component
    public class RestAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
    	@Override
    	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
    			Authentication authentication) throws IOException, ServletException {
    		clearAuthenticationAttributes(request);
    	}
    }
    
  • in case of error, we return an HTTP code and an optional message:
    @Component
    public class RestAuthenticationFailureHandler implements AuthenticationFailureHandler{
    	@Override
    	public void onAuthenticationFailure(HttpServletRequest arg0, HttpServletResponse arg1, AuthenticationException arg2)
    			throws IOException, ServletException {
    		arg1.sendError(HttpServletResponse.SC_FORBIDDEN, "Wrong username or password");
    	}
    }
    
  • And then the last step is to add them to the Spring configuration:

    [...]
    @Autowired
    private AuthenticationFailureHandler authenticationFailureHandler;
    
    @Autowired
    private AuthenticationSuccessHandler authenticationSuccessHandler;
    [...]
    protected void configure(HttpSecurity http) throws Exception {
    	[...]
    	FormLoginConfigurer formLogin = http.formLogin();
    	[...]
    	formLogin.successHandler(authenticationSuccessHandler);
    	formLogin.failureHandler(authenticationFailureHandler);
    
    }
    

    Now, we can define our web services, and Spring will manage authentication for us.
    To protect your services, obviously, you need to add something like:

    http
    .authorizeRequests()
    [...]
    .antMatchers(HttpMethod.GET, "/secured/services/**")
    .access("hasRole('SERVICE_USER')");
    

    And you can also restrict access by the HTTP methods, someone can read data (GET method) but could not be allowed to modify it (POST/PUT methods).
    That’s it!

    In a next post, I will show how I used it with Angular-js, stay tuned 😀

    (the full project is available on Github)

Oracle proxy user with Spring

The standard solution to manage the database connections in a web application is to let the server manage it, and use Spring to inject it wherever it is needed. By doing so, we can let also the transaction management to be done by a third party API, Spring fits perfectly this need.
But this option assumes that the user/password used to connect to the database are the server responsibility. But sometimes…
I had a project of migration of a heavy client written in Visual Basic into a web application, and this application uses a connection per user, meaning that the credentials are user specific.
This should not be an issue except if the Visual Basic application makes an heavy usage of Oracle variables, and, unfortunately, it was the case. It means that, for each HTTP request, we need to connect to the database by creating a new connection with the connected user credentials. This kind of behavior is resource consuming and this is something that we commonly address with a pool of connections.

To remedy to that situation, luckily, Oracle provides a mechanism to reflect this usage. The idea is to define a user proxy which will be used by the real user to connect through:

>CREATE USER proxy_user IDENTIFIED BY password;

>ALTER USER scott GRANT CONNECT THROUGH proxy_user;

Now, we can create a datasource with this proxy user and use the real user to access to the data.

But now, what about our application?
Fortunately, Spring provides classes to manage this particular database configuration but it does not allow us to use the server managed datasource.
The Maven dependency we need to add:

<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-oracle</artifactId>
	<version>1.0.0.RELEASE</version>
</dependency> 

And the Spring configuration:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:orcl="http://www.springframework.org/schema/data/orcl"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/data/orcl http://www.springframework.org/schema/data/orcl/spring-data-orcl-1.0.xsd">

<orcl:pooling-datasource id="dataSource"
	url="jdbc:oracle:thin:@${net.classnotfound.jdbc.server}:${net.classnotfound.jdbc.port}:${net.classnotfound.jdbc.sid}"
	username="${net.classnotfound.jdbc.user}" 
	password="${net.classnotfound.jdbc.password}">
	<orcl:connection-properties>validationQuery=select 1 from dual</orcl:connection-properties>
	<orcl:connection-cache-properties>
		ValidateConnection=true
	</orcl:connection-cache-properties>
	<orcl:username-connection-proxy connection-context-provider="usernameProvider" />
</orcl:pooling-datasource>

<bean id="usernameProvider" class="net.classnotfound.core.jdbc.support.UserProvider" />

<bean id="transactionManager"
	class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
	depends-on="dataSource">
	<property name="dataSource" ref="dataSource" />
</bean>

We see that we have to use a specific namespace to define the datasource and the attribute are enough explicit.

The user-name-connection-proxy is used to provide the username of the connected user. In my case, as I am using Spring-Security for that purpose, the user provider looks like:

package net.classnotfound.core.jdbc.support;

import org.springframework.data.jdbc.support.ConnectionUsernameProvider;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;

public class UserProvider implements ConnectionUsernameProvider {
    /**
     * return the username of the current security context
     * 
     * @return the user provided by the current request
     */
    @Override
    public String getUserName() {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof UserDetails) {
            return ((UserDetails) principal).getUsername();
        } else {
            return principal.toString();
        }
    }
}

Basically, it gets the information from the Spring Security context and returns the username.

Define configuration file outside of the classpath

Here I describe the way I use to configure my applications. The main idea is to define a property file outside of the application, doing this, it is possible to deploy the same application in several environments (dev/test/prod) without any changes.

First of all, the property file:

net.classnotfound.app.jdbc.server=db-server
net.classnotfound.app.jdbc.port=1521
net.classnotfound.app.jdbc.sid=xe
net.classnotfound.app.jdbc.user=scott
net.classnotfound.app.jdbc.password=koala

The tips is to define a parameter in the Tomcat context file which points to the file location:

<Parameter name="directoryConfig" override="false" value="FILE_PATH"/>

And now, to get the value in the application, I use Spring this way:

<bean id="placeholderConfig"
	class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	<property name="location"
		value="file:#{contextParameters.directoryConfig}/app-config.properties" />
</bean>

This is an example of its usage to set up an Oracle datasource:

<orcl:pooling-datasource id="dataSource"
	url="jdbc:oracle:thin:@${net.classnotfound.app.jdbc.server}:${net.classnotfound.app.jdbc.port}:${net.classnotfound.app.jdbc.sid}"
	username="${net.classnotfound.app.jdbc.user}" password="${net.classnotfound.app.jdbc.password}">
</orcl:pooling-datasource>

Now, we can just change the path of the configuration file, depending on each environment, to automatically have the related parameters.

Spring MyBatis configuration

Here I describe the project configuration to use MyBatis as ORM and benefit of the transactions management provided by Spring.
For that, we have to add the MyBatis-Spring library to the basic MyBatis.

First, the Maven POM is like:

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.2.3</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.2.1</version>
</dependency>

And now, the Spring configuration file where we define the SqlSessionFactoryBean:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
    
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="mapperLocations" value="classpath:xml/*Mapper.xml" />
    </bean>
</beans>

The SqlSessionFactoryBean needs a datasource, and also the location of the MyBatis xml mappers.

Now, the configuration is done and the mappers will be managed by Spring using with this:

<!-- this is the parent of our Mappers. It defines the sqlSessionFactory which is common to all our mapper beans -->
<bean id="mapper" abstract="true">
	<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<!-- Place MyBatis Mappers here -->
<bean id="entityMapper" class="org.mybatis.spring.mapper.MapperFactoryBean" parent="mapper">
	<property name="mapperInterface"
		value="net.classnotfound.data.mapper.EntityMapper" />
</bean>

We can see that the mappers are instantiated by the org.mybatis.spring.mapper.MapperFactoryBean which needs a reference to the SqlSessionFactory object we defined earlier.
To avoid some oversights (and reduce the mount of lines I have to write 🙂 ), I use the “abstract” Spring feature to put the session factory in the abstract mapper, then I can reference it as a parent in all my MapperFactories.

Now the entityMapper we defined is “injectable” in our Spring managed beans and we can use our preferred way of transaction management.

Enable transactions on Informix DB

We need to have the following variables set:

INFORMIXDIR=/opt/IBM/informix
INFORMIXSQLHOSTS=/opt/IBM/Informix/etc/sqlhosts.ol_informix1170
INFORMIXSERVER=ol_informix1170
  1. Now, we can enable the transactions, in first we need to put the database in “quiescent mode” (???):

    >/opt/IBM/informix/bin/onmode –uy
    

    Note: doing this disable access to the database.

  2. enable transactions:

    >/opt/IBM/informix/bin/ontape –s –L 0 –B d9exp
    
  3. Re-enable the connections:

    >/opt/IBM/informix/bin/onmode -m
    
  4. Helpful information: Jdbc configuration

    jdbc:oracle:thin:@server:port:db
    

    More information here

Spring Security with JSF 2 and custom login form

Here, I am integrating Spring Security with JSF 2 using a custom login form.

First, the maven dependencies for Spring-Security (I consider that the JSF project is already set-up, if it is not the case, you can check here):

<properties>
    ...
    <spring.security.version>3.2.4.RELEASE</spring.security.version>
</properties>
...
<!-- Spring-Security dependencies -->
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
    <version>${spring.security.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-config</artifactId>
    <version>${spring.security.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-web</artifactId>
    <version>${spring.security.version}</version>
</dependency>

In the web.xml, we have to configure the Spring-Security filter as follow:

<!-- Enable Spring Filter: Spring Security works on the concept of Filters -->
<!-- Declare the Spring filter -->
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>
        org.springframework.web.filter.DelegatingFilterProxy
    </filter-class>
</filter>
<!-- Defines urls pattern on which the filter is applied -->
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

Note: if you don’t add the forward to it, the managed bean will not be able to send the request to the filter (I experienced that!!).

We need a simple index.xhtml which will be protected by Spring (I don’t describe it here) and a custom login page which receive the credentials typed by the user.
This page contains only the user name, the password and another field method which is here to show how we can get it on the server:

<h:form id="loginFormId" prependId="false">
    <div class="full-box" style="text-align: center">
        <div class="child-box box-c3">
            <h3>Login</h3>
            <div class="fluid-row">
                <div class="fluid-column fluid-c12">
                    <div class="forLabel" style="width: 30%">
                        <h:outputLabel for="username" value="User" />
                    </div>
                    <div class="forField" style="width: 65%">
                        <h:inputText id="username" required="true"
                            requiredMessage="Please enter username (or go to hell...)" />
                        <h:messages for="username" />
                    </div>
                </div>
                <div class="fluid-column fluid-c12">
                    <div class="forLabel" style="width: 30%">
                        <h:outputLabel for="password" value="Password" />
                    </div>
                    <div class="forField" style="width: 65%">
                        <h:inputSecret id="password" required="true"
                            requiredMessage="Please enter password (otherwise you'll die!!)"
                            name="password" />
                        <h:messages for="password" />
                    </div>
                </div>
                <div class="fluid-column fluid-c12">
                    <div class="forLabel" style="width: 30%">
                        <h:outputText value="Authentication" />
                    </div>
                    <div class="forField" style="width: 65%">
                        <h:selectBooleanCheckbox id="method" name="method" />
                        <h:outputLabel for="method" value="LDAP" />
                    </div>
                </div>
            </div>
            <ui:fragment rendered="${!empty param['error']}">
                <div>Connection failed: user and/or password are wrong.</div>
            </ui:fragment>
            <div id="loginBtnPanelId">
                <h:commandButton id="btnLoginId" value="Login" type="submit"
                    action="${loginManager.doLogin()}" styleClass="loginPanelBtn" />
            </div>
        </div>
    </div>
</h:form>

The form is very simple, we can see the 3 fields and a portion which is conditionally rendered if error param is available.
The content of this form is sent to a managed bean which is responsible of forwarding data to the Spring-Security filter:

import java.io.IOException;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

@ManagedBean
@RequestScoped
public class LoginManager {

    public String doLogin() throws IOException, ServletException {
        ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
        RequestDispatcher dispatcher = ((ServletRequest) context.getRequest()).getRequestDispatcher("/j_spring_security_check");
        dispatcher.forward((ServletRequest) context.getRequest(), (ServletResponse) context.getResponse());
        FacesContext.getCurrentInstance().responseComplete();
        return null;
    }

}

Now, we need to have a look to the Spring configuration file, the security is configured as follow:

<security:http use-expressions="true">
    <!-- refers to http://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html -->
    <security:intercept-url pattern="/faces/login.xhtml"
        access="anonymous" />
    <security:intercept-url pattern="/css/**"
        access="anonymous" />
    <security:intercept-url pattern="/**"
        access="authenticated" />
    <security:form-login login-page="/faces/login.xhtml"
        authentication-failure-url="/faces/login.xhtml?error=1"
        default-target-url="/faces/index.xhtml"
        authentication-details-source-ref="myAuthenticationDetailsSource"
        username-parameter="username" password-parameter="password" />
</security:http>

We can see that we have to enable anonymous access to the login form (otherwise, you will see some strange messages in your browser, I let you guess why). To have a beautiful login page, we also allow anonymous access to the CSS, the rest of the site has a restricted access controlled by Spring.
As we use a custom login form, the form-login element must indicate which one we want to use with the login-page attribute.
To be able to store the custom field (the method if you forgot it), we have to implement a custom class, it is the one we see in the authentication-details-source-ref attribute.

This is how it is defined in the Spring configuration file:

<bean id="myAuthenticationDetailsSource"
    class="net.classnotfound.jsf.spring.security.security.MyAuthenticationDetailsSource">
</bean>

And the class which implements the org.springframework.security.authentication.AuthenticationDetailsSource interface:

import javax.servlet.http.HttpServletRequest;

import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.web.authentication.WebAuthenticationDetails;

/**
 * This class provides a custom AuthenticationDetail which stores the connection
 * type method (Oracle/Ldap)
 *
 */
public class MyAuthenticationDetailsSource implements AuthenticationDetailsSource {

    /**
     * returns the {@link WebAuthenticationDetails} according to LuxFact rule
     * 
     * @param context
     */
    @Override
    public WebAuthenticationDetails buildDetails(final HttpServletRequest context) {
        return new MyAuthenticationDetails(context);
    }

}

This class provides an implementation of a org.springframework.security.web.authentication.WebAuthenticationDetails which will store our extra parameter, its implementation is very simple:

import javax.servlet.http.HttpServletRequest;

import org.springframework.security.web.authentication.WebAuthenticationDetails;

/**
 * this class stores data used for authentication (mainly the authentication
 * method)
 * 
 */
public class MyAuthenticationDetails extends WebAuthenticationDetails {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private final String method;

    public MyAuthenticationDetails(final HttpServletRequest request) {
        super(request);
        method = request.getParameter("method");
    }

    public String getMethod() {
        return method;
    }

}

As we can see, this class does nothing else than getting the custom parameter from the request and storing it.

Now, to use this extra parameter, we need to customize the way a user is authenticated. As this task is, by default, done by Spring, it means that we have to write a new class which implements the org.springframework.security.authentication.AuthenticationProvider interface. We can see its declaration in the Spring configuration file here:

<bean id="myAuthenticationProvider"
    class="net.classnotfound.jsf.spring.security.security.MyAuthenticationProvider">
</bean>

<security:authentication-manager>
    <!-- create a custom AuthenticationProvider class to tune the login 
        process -->
    <security:authentication-provider
        ref="myAuthenticationProvider" />
</security:authentication-manager>

And its implementation:

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

public class MyAuthenticationProvider implements AuthenticationProvider {

    @Override
    public Authentication authenticate(final Authentication authentication) throws AuthenticationException {

        Authentication res = isValid(authentication);
        if (!res.isAuthenticated()) {
            throw new BadCredentialsException("Bad credentials");
        }
        return res;
    }

    private Authentication isValid(final Authentication authentication) {
        Authentication res = authentication;
        System.out.println("Selected method: "+((MyAuthenticationDetails)authentication.getDetails()).getMethod());
        if ("Admin".equals(authentication.getPrincipal())&&"Password".equals(authentication.getCredentials())) {
            res = createSuccessAuthentication(authentication);
        }
        return res;
    }

    @Override
    public boolean supports(final Class authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }

    protected Authentication createSuccessAuthentication(final Authentication authentication) {
        // Ensure we return the original credentials the user supplied,
        // so subsequent attempts are successful even with encoded passwords.
        // Also ensure we return the original getDetails(), so that future
        // authentication events after cache expiry contain the details
        final UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(authentication.getPrincipal(), authentication.getCredentials(), authentication.getAuthorities());
        result.setDetails(authentication.getDetails());

        return result;
    }

}

As we can see, the extra parameter is extracted from the org.springframework.security.core.Authentication.getDetails() method.

The whole Spring configuration file looks like:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:security="http://www.springframework.org/schema/security"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">


    <!-- Enable security annotations usage -->

    <bean id="myAuthenticationDetailsSource"
        class="net.classnotfound.jsf.spring.security.security.MyAuthenticationDetailsSource">
    </bean>

    <bean id="myAuthenticationProvider"
        class="net.classnotfound.jsf.spring.security.security.MyAuthenticationProvider">
    </bean>


    <security:authentication-manager>
        <!-- create a custom AuthenticationProvider class to tune the login 
            process -->
        <security:authentication-provider
            ref="myAuthenticationProvider" />
    </security:authentication-manager>

    <security:http use-expressions="true">
        <!-- refers to http://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html -->
        <security:intercept-url pattern="/faces/login.xhtml"
            access="anonymous" />
        <security:intercept-url pattern="/css/**"
            access="anonymous" />
        <security:intercept-url pattern="/**"
            access="authenticated" />
        <security:form-login login-page="/faces/login.xhtml"
            authentication-failure-url="/faces/login.xhtml?error=1"
            default-target-url="/faces/index.xhtml"
            authentication-details-source-ref="myAuthenticationDetailsSource"
            username-parameter="username" password-parameter="password" />
    </security:http>

</beans>

Source files are available here.

Change web context using Maven

<packaging>war</packaging>
<build>
<plugins>
  <plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.1.1</version>
    <configuration>
        <packagingExcludes>WEB-INF/web.xml</packagingExcludes>
        <warName>exp-elec-web</warName>
    </configuration>
</plugin>
</plugins>
</build>

Maven config for JSF2/RichFaces

Here is my Maven configuration for a JSF2/Richfaces 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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>net.classnotfound</groupId>
    <artifactId>jsf</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>jsf</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <org.apache.myfaces.version>2.2.0</org.apache.myfaces.version>
        <org.richfaces.version>4.3.5.Final</org.richfaces.version>
    </properties>

    <dependencies>

        <!-- web container dependencies -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jasper</artifactId>
            <version>7.0.50</version>
            <scope>provided</scope>
        </dependency>
        <!-- JSF dependencies -->
        <dependency>
            <groupId>org.apache.myfaces.core</groupId>
            <artifactId>myfaces-bundle</artifactId>
            <version>${org.apache.myfaces.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-digester</groupId>
            <artifactId>commons-digester</artifactId>
            <version>2.1</version>
        </dependency>
        <!-- end JSF dependencies -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- RichFaces dependencies -->
        <dependency>
            <groupId>org.richfaces.core</groupId>
            <artifactId>richfaces-core-api</artifactId>
            <version>${org.richfaces.version}</version>
        </dependency>
        <dependency>
            <groupId>org.richfaces.core</groupId>
            <artifactId>richfaces-core-impl</artifactId>
            <version>${org.richfaces.version}</version>
        </dependency>
        <dependency>
            <groupId>org.richfaces.ui.common</groupId>
            <artifactId>richfaces-ui-common-api</artifactId>
            <version>${org.richfaces.version}</version>
        </dependency>
        <dependency>
            <groupId>org.richfaces.ui.core</groupId>
            <artifactId>richfaces-ui-core-api</artifactId>
            <version>${org.richfaces.version}</version>
        </dependency>
        <dependency>
            <groupId>org.richfaces.ui</groupId>
            <artifactId>richfaces-components-api</artifactId>
            <version>${org.richfaces.version}</version>
        </dependency>
        <dependency>
            <groupId>org.richfaces.ui</groupId>
            <artifactId>richfaces-components-ui</artifactId>
            <version>${org.richfaces.version}</version>
        </dependency>
        <dependency>
            <groupId>org.w3c.css</groupId>
            <artifactId>sac</artifactId>
            <version>1.3</version>
        </dependency>
        <!-- End RichFaces dependencies -->
    </dependencies>
</project>