Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Securing JSPs With Spring Security and Stormpath

DZone's Guide to

Securing JSPs With Spring Security and Stormpath

An in-depth tutorial to show you how to secure JSPs using Spring Security and Stormpath to ensure your enterprise infrastructures remain secure.

· Security Zone
Free Resource

Discover how to protect your applications from known and unknown vulnerabilities.

Even though JSPs have fallen out of fashion lately, they are still a core part of many enterprise infrastructures. In this tutorial, we’ll show you how to secure them using the excellent Spring Security suite and Stormpath’s Spring Boot integration for user management.

JSPs and Spring Boot

We’ll start by serving up a simple JSP homepage using Spring Boot. The most basic JSP is plain HTML with a variable or two thrown in.

<!doctype html>
<html>
<body>
  <p>Hello, <%="World"%>!</p>
</body>
</html>

If rendered correctly we should see ‘Hello, World!’ when loading the code. To do this we first put it into the src/main/webapp/WEB-INF/jsp directory.

JSP Directory

Then inside of application.properties we need to specify where our JSP files reside.

spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp

Now create a basic Application.java.

@SpringBootApplication
public class Application  {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

And then create an even more basic Request.java.

@Controller
public class Request {

    @GetMapping("/")
    String home() {
        return "home";
    }
}

Mapping a forward slash to home really means the file home.jsp with the path defined in our application.properties.

The last thing we need is a pom.xml. Here we include the Spring Boot Starter Parent (so we don’t have to specify dependency versions), the Spring Boot Maven Plugin (so we can run our app directly), the Tomcat Jasper (to serve our JSPs) and the Spring Boot Starter Web (for route controlling).

<project>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.stormpath.sample</groupId>
    <artifactId>stormpath-security</artifactId>
    <version>0.1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.0.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

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

Now when we run with mvn spring-boot:run and visit localhost:8080 we should see our hello world message.

JSP Hello World

Add Security

Spring Security is divided into two parts, authentication, and authorization. The first ensures your user identity while the second handles what the user can and can’t do.

To authenticate we are going to use Stormpath’s Java integration which is as simple as adding http.apply(stormpath()) to a basic security adapter.

@Configuration
public class Security extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.apply(stormpath());
    }
}

We also need to add our Stormpath application details to our application.properties.

stormpath.application.href = <your app href>
stormpath.client.apiKey.id = <your api key id>
stormpath.client.apiKey.secret = <your api key secret>

Note: For security reasons you should not store your Stormpath keys inside of Java files. Rather use environment variables. See here.

In addition we need to add the Stormpath starter to our pom.xml.

<dependency>
    <groupId>com.stormpath.spring</groupId>
    <artifactId>stormpath-default-spring-boot-starter</artifactId>
    <version>1.1.3</version>
</dependency>

However, this includes Thymeleaf templating which clashes with Jasper (which we use to serve our JSPs). We need to exclude it. Instead of the above code use the following.

<dependency>
    <groupId>com.stormpath.spring</groupId>
    <artifactId>stormpath-default-spring-boot-starter</artifactId>
    <version>1.1.3</version>
     <exclusions>
        <exclusion>
            <groupId>com.stormpath.spring</groupId>
            <artifactId>stormpath-thymeleaf-spring-boot-starter</artifactId>
        </exclusion>
    </exclusions> 
</dependency>

If you restart your application and refresh the homepage you should see Stormpath trying to log you in. This is because we haven’t specified access controls per page. By default everything is locked down.Login

Typing in the details for a user account in your Stormpath application should take you to the ‘Hello, World!’ message as before.

Authorization

Finally to illustrate authorization we will use Spring Security’s JSP tag libraries which allows us to control behaviour based on Access Expressions (we’ll deal with those in a second).

First we add the tag libraries to our pom.xml.

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-taglibs</artifactId>
</dependency>

Next we import the library to our JSP by adding the following line to the top.

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

With that we can use the special sec tags to control how the JSP is rendered. For example take the following section of code.

<sec:authorize access="hasAuthority('supervisor')">

This content will only be visible to users who have
the "supervisor" authority in their list of <tt>GrantedAuthority</tt>s.

</sec:authorize>

Only users with authority supervisor will be able to see the code in between the tags.

Role, Authority, and Access Expressions

Spring Security allows you to define policies on methods and attributes using the Spring Expression Language. For example you could use the @PreAuthorize annotation to specify whether a user can access a function.

@PreAuthorize("hasRole('ROLE_USER')")
public void create(Contact contact);

Part of the expression language is the concept of Role and Authority Spring Security uses in order to associate rights to users. To illustrate this take a look at the following xml config excerpt used before the Java configurations that are popular today today.

<http auto-config="true">
    <intercept-url pattern="/admin**" access="ROLE_ADMIN" />
    <intercept-url pattern="/dba**" access="ROLE_ADMIN,ROLE_DBA" />
</http>

This is how we would say who was allowed to see the /admin and /dba urls. It is not per user but per role. We then have to define who has what role when creating users.

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="karl" password="123456" authorities="ROLE_USER" />
            <user name="admin" password="123456" authorities="ROLE_ADMIN" />
            <user name="dba" password="123456" authorities="ROLE_DBA" />
        </user-service>
    </authentication-provider>
</authentication-manager>

Note: In Stormpath we use hasAuthority throughout. This is because hasRole is the same as hasAuthority but just with the string ‘ROLE_’ prepended. See details of our Spring Boot migration for more.

Stormpath Groups

Groups in Stormpath

Groups in Stormpath are analogous to Spring Security authorities. And to specify a group we use the href shown when you open the group up in the Stormpath Admin Console.

<sec:authorize access="hasAuthority('https://api.stormpath.com/v1/groups/<your href here>')">

If we add the referenced group to the user we logged in with previously and reload, we should see the message inside the sec tags.

In this way, we can control who is allowed to access which sections of code such as buttons and forms.

JSP + Stormpath FTW

Hopefully, you can see how easy it is to secure your JSPs using Stormpath and Spring Security. With just a few files you can create a flexible system that allows centrally managing users and controlling what they can see and do based on the groups they belong to.

Interested in learning more about user management with Stormpath? Well you’re in luck, because we’ve got everything you need to get started!

Find out how Waratek’s award-winning virtualization platform can improve your web application security, development and operations without false positives, code changes or slowing your application.

Topics:
jsp ,security ,user management ,spring ,stormpath

Published at DZone with permission of Karl Penzhorn. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}