In this tutorial, we will look at:

Configuring and wiring a flow executor

Securing web flows

Understanding security flows

Understanding Spring Security modules

Intercepting requests

Authenticating users

Securing views

As already mentioned in our previous articles of the series, Spring framework is an open source Java platform that provides MVC infrastructure support for developing robust Java applications very easily and very rapidly using recommended MVC pattern.

Look’s like we have a lot to cover again, so let’s get started.

Spring Web Flow

Spring Web Flow is a web framework that enables the development of components following a prescribed flow. In this tutorial, we’ll explore Spring Web Flow and see how it fits into the Spring web framework world.

Spring Web Flow extends Spring MVC and enables the development of flow based web apps. It does this by separating the definition of an application’s flow from the classes and views that implement the flow’s behavior.

In this article, we will define an item ordering process and we’ll use Spring Web Flow to define the order process.

Configuring Web Flow

The following XML based configuration shows how to take a user through the order process. There is an obvious question here, why not configure Web flow in Java? Actually we can’t as there’s no support for configuring Spring Web Flow in Java, so we have no choice but to configure it in XML.

<?xml version="1.0" encoding="UTF-8"?> <flow xmlns="http://www.springframework.org/schema/webflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow-2.3.xsd"> <var name="order" class="com.springinaction.pizza.domain.Order"/> <subflow-state id="identifyCustomer" subflow="pizza/customer"> <output name="customer" value="order.customer"/> <transition on="customerReady" to="buildOrder" /> </subflow-state> <subflow-state id="buildOrder" subflow="pizza/order"> <input name="order" value="order"/> <transition on="orderCreated" to="takePayment" /> </subflow-state> <subflow-state id="takePayment" subflow="pizza/payment"> <input name="order" value="order"/> <transition on="paymentTaken" to="saveOrder"/> </subflow-state> <action-state id="saveOrder"> <evaluate expression="pizzaFlowActions.saveOrder(order)" /> <transition to="thankCustomer" /> </action-state> <view-state id="thankCustomer"> <transition to="endState" /> </view-state> <end-state id="endState" /> <global-transitions> <transition on="cancel" to="endState" /> </global-transitions> </flow>

Let’s look at each component in the above configuration individually:

We start with a namespace declaration.

The first element after the namespace definition is a flow executor. The flow executor drives the execution of a flow. When a user enters a flow, the flow executor creates and launches an instance of the flow execution for that user. Although the flow executor is responsible for creating and executing flows, it’s not responsible for loading flow definitions. That responsibility falls to a flow registry, which we’ll create next.

A flow registry’s job is to load flow definitions and make them available to the flow executor.

We need to handle the flow request next.

Components of a flow

Let us look at components of a flow.

States: There are five states in which a flow can be in.

View: A view state shows information to a user or takes user input using a web form. A model can be passed to bind the elements of the form. The view may be implemented as any view defined in Spring MVC, like a JSP.



Action: In this state, actions are performed using spring beans. The action state transitions to another state. This generally has an evaluate property that describes what needs to be done. The evaluate is generally a method of one of the registered spring beans. The evaluate expression is a SpEL. More than one action can be configured in which case the actions will be executed one after the other.



Decision: Decision state is where a decision is made. It has two transitions depending on whether the decision evaluates to true or false.



Subflow: It may be advantageous to call another flow from one flow to complete some steps. The sub flow returns to the original flow when it is complete. Data may be passed from the calling flow into the subflow and output data from the subflow may be retrieved into the calling flow.



End: The end state signifies the end of a flow. If the end state is part of a root flow then the execution is ended. However, if it is part of a sub flow then the root flow is resumed.

Transitions: These connect states to a flow. The to attribute is used to specify the next state in the flow.

Securing Web flows

States, transitions, and entire flows can be secured in Spring Web Flow by using the <secured> element as a child of those elements. For example, to secure access to a view state, you might use the following:

<view-state id="restricted"> <secured attributes="ROLE_ADMIN" match="all"/> </view-state>

As configured here, access to the view state will be restricted to only those users who are granted ROLE_ADMIN access.

Spring Security

Spring security is a security module which provides declarative security for our Spring-based applications. Basically, Spring security is divided into eleven modules:

ACL: Provides support for domain object security through access control lists (ACLs) Aspects: A small module providing support for AspectJ-based aspects instead of standard Spring AOP when using Spring Security annotations CAS Client: Support for single sign-on authentication using Jasig’s Central Authentication Service (CAS) Configuration: Contains support for configuring Spring Security with XML and Java (Java configuration support introduced in Spring Security 3.2.) Core: Provides the essential Spring Security library Cryptography: Provides support for encryption and password encoding LDAP: Provides support for LDAP-based authentication OpenID: Contains support for centralized authentication with OpenID Remoting: Provides integration with Spring Remoting Tag Library: Spring Security’s JSP tag library Web: Provides Spring Security’s filter-based web security support

In the very least, you’ll want to include the Core and Configuration modules in your application’s classpath.

Intercepting requests

To start with any kind of Spring security functionality, we need to have a configuration class. Clearly, we’ll use Java based configuration. Let’s look at the simplest Java based configuration class:

import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web. configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web. configuration.WebSecurityConfigurerAdapter; @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { }

As its name suggests, the @EnableWebSecurity annotation enables web security. Also, Spring Security must be configured in a bean that extens WebSecurityConfigurerAdapter. Let’s do this next:

import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web. configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.servlet. configuration.EnableWebMvcSecurity; @Configuration @EnableWebMvcSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user").password("password").roles("USER").and() .withUser("admin").password("password").roles("USER", "ADMIN"); } }

Here, we’re adding two users ‘user’ and ‘admin’ with the password ‘password.’ Clearly, the and() method is used to chain them together.

Authenticating users against Database

It’s quite common to authenticate users from an actual database, accessed via JDBC. To use JDBC based authentication, we need to use jdbcAuthentication() method.

@Autowired DataSource dataSource; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.jdbcAuthentication().dataSource(dataSource); }

The only thing we must configure is a DataSource so that it’s able to access the relational database. The DataSource is provided here via autowiring.

Securing the views

When rendering HTML views, it’s good to reflect the security constraints like ‘you are logged in as...’, or conditionally render some view elements depending upon what authorization the currently logged in user has.

Let’s see how Spring Security works with JSPs with the HSP tag library.

Using Spring Security’s JSP tag library

Spring Security’s JSP tag library is small and includes only three tags:

<security:accesscontrollist> : Conditionally renders its body content if the user is granted authorization by an access control list

<security:authentication> : Renders details about the current authentication

<security:authorize> : Conditionally renders its body content if the user is granted certain authorizations or if a SpEL expression evaluates to true

To start, the taglib definition is required at the top of the JSP file like:

<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>

Here's how you could assign it to a property named loginId:

<security:authentication property="principal.username" var="loginId"/>

The variable is created in page scope by default.

Conditional rendering

Sometimes portions of the view should or shouldn’t be rendered, depending on what the user is privileged to see. There’s no point in showing a login form to a user who’s already logged in or in showing a personalized greeting to a user who’s not logged in.

Spring Security’s JSP tag conditionally renders a portion of the view depending on the user’s granted authorizations.

<sec:authorize access="hasRole('ROLE_SPITTER')"> <s:url value="/spittles" var="spittle_url" /> <sf:form modelAttribute="spittle" action="${spittle_url}"> <sf:label path="text"><s:message code="label.spittle" text="Enter spittle:"/></sf:label> <sf:textarea path="text" rows="2" cols="40" /> <sf:errors path="text" /> <br/> <div class="spitItSubmitIt"> <input type="submit" value="Spit it!" class="status-btn round-btn disabled" /> </div> </sf:form> </sec:authorize>

The access attribute is given a SpEL expression whose result determines whether the body is rendered. Here you’re using the hasRole ('ROLE_SPITTER') expression to ensure that the user has the ROLE_SPITTER role. But we have the full power of SpEL at your disposal when setting the access attribute, including the Spring Security-provided expressions.

Conclusion

In this long article, we learned a lot. From configuring Spring security, intercepting user requests and securing our views from attacks.

Security is a crucial aspect of many applications. Spring Security provides a mechanism for securing your application that’s simple, flexible, and powerful.

In the next article, we will continue our journey and study some important concepts regarding configuring JDBC data sources and start to integrate JPA and Neo4J in our application.

Be sure to use DiscoverSDK to search and compare the best java SDKs.