Spring Security

By Maurizio Farina | Posted on November 2017

This post does not want to be a Spring Session Guide because there are already many tutorials available but rather describe how Spring Session was used to implement ListFeeds RESTful services.

Overview

The security protocol types:

  • Basic Authentication via TLS (formerly known as SSL): sending username and password using Base64 encoding. Basic authentication must be used always using SSL.
  • OAuth1.0a: cryptographic signature in combination with token secret
  • OAuth2: completely different from OAuth1.0a. Removes signatures all the encryption is handled by TLS.

Session Management

Spring Session manages user’s session information.

It provides integration with:

  • HttpSession: replacing the HttpSession adding additional features:
    • Clustered Sessions: easy to implement
    • Multiple Browser Sessions: supports multiple users' sessions in a single browser instance
    • RESTful APIs: provides session ids in headers
  • WebSocket: keep the HttpSession alive when receiving WebSocket messages

Maven dependencies

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
 <dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
    <version>1.3.1.RELEASE</version>
    <type>pom</type>
</dependency>
<dependency>
    <groupId>biz.paluch.redis</groupId>
    <artifactId>lettuce</artifactId>
    <version>3.5.0.Final</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.3.4.RELEASE</version>
</dependency>

Managing Session repository using Redis

The steps are the following:

  • configure Spring Application context
  • configure the web application to use Spring application configuration file
  • configure the web application so that the application container uses Spring session

configure Spring Application context

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<context:annotation-config/>

<bean id="httpSessionStrategy" 
    class="org.springframework.session.web.http.CookieHttpSessionStrategy" 
    p:cookieName="ListFeeds"/>

<bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration" 
    p:httpSessionStrategy-ref="httpSessionStrategy"/>

<bean class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory" 
    p:host-name="server" 
    p:port="6379"/>

The above declarations:

  • Redis as session repository;
  • Declare "Coockie" as session strategy
  • uses lattice to access to Redis

Lettuce is a netty-based open-source connector supported by Spring Data Redis. Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.

Dealing with high available Redis there is support for Redis Sentinel using RedisSentinelConfiguration. In this case the ConnectionFactory is defined by java code:

1
2
3
4
5
6
7
8
@Bean
public RedisConnectionFactory lettuceConnectionFactory() {
  RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration()
  .master("mymaster")
  .sentinel("127.0.0.1", 26379)
  .sentinel("127.0.0.1", 26380);
  return new LettuceConnectionFactory(sentinelConfig);
}

Session Fixation Protection: on authentication a new HTTP Session is created, the old one is invalidated and the attributes from the old session are copied over.

1
<session-management session-fixation-protection="migrateSession">

Two other options are available:

  • none: the original session will not be invalidated
  • newSession: a clean session will be created without any of the attributes from the old session being copied over

configure the web application: src/main/webapp/WEB-INF/web.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring/*.xml
    </param-value>
</context-param>
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

Warning

The above configuration may already be present as it is the basis of all web applications developed with the Spring framework

configure the web application: src/main/webapp/WEB-INF/web.xml to use Spring servlet for all incoming requests

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

The DelegatingFilterProxy filter class will be used for Spring Security too.

Using Session

Using Spring Session through HttpServletRequest via Java code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
@Controller
public class SessionDataController {

    @RequestMapping("/user/session")
    public String addToSession(
        HttpServletRequest request,
        @RequestParam("attr") String attribute,
        @RequestParam("val") String value) {

            HttpSession session = request.getSession();
            session.setAttribute(attribute, value);
            return "redirect:/";
        }
    }

Session Scoped Beans

1
2
3
@Component
@Scope("session")
public class UserData { .. }

Or with XML:

1
<bean id="UserData" scope="session"/>

Raw Session

The raw HTTP Session can also be injected directly into a Controller method:

@RequestMapping(..) public void fooMethod(HttpSession session) { session.addAttribute(Constants.FOO, new Foo(); //... Foo foo = (Foo) session.getAttribute(Constants.Foo); }

Concurrent Session Control

Session Timeout

References

Resource Description
Spring Session 1.3.1.RELEASE reference a comprehensive guide written directly from Spring