This article contains Spring Security CSRF Example for authentication using Spring Security. This article help you to solve Cross Site Request Forgery (CSRF) problem using spring security. As of Spring Security 4.0, CSRF protection is enabled by default.

 

Spring Security csrf example

Spring Security csrf example

Dependency

<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>com.javadeveloperzone</groupId>
    <artifactId>spring-security-java-configuration</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>spring-security-java-configuration</name>

    <properties>
        <spring.version>4.3.1.RELEASE</spring.version>
        <spring.security.version>4.2.0.RELEASE</spring.security.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- Spring Security -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-web</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>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

    </dependencies>

    <build>
        <finalName>spring-security-java-configuration</finalName>

        <plugins>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

 

Configuration:

WebConfigs.java

package com.javadeveloperzone.configs;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;


/**
 * Created by Subhash Lamba on 19-01-2017.
 */

public class WebConfigs extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringWebConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringWebConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

SpringWebConfig.java

package com.javadeveloperzone.configs;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

/**
 * Created by JavaDeveloperZone on 19-01-2017.
 */
@EnableWebMvc
@Configuration
@ComponentScan({"com.javadeveloperzone.*"})
@Import({ SpringSecurityWebConfig.class })
public class SpringWebConfig extends WebMvcConfigurerAdapter {

    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/pages/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;

    }
}

SpringSecuirtyWebConfig.java

package com.javadeveloperzone.configs;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;



/**
 * Created by JavaDeveloperZone on 18-03-2017.
 */
@Configuration
@EnableWebSecurity
public class SpringSecurityWebConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("javadeveloperzone").password("javadeveloperzone").roles("USER");
        auth.inMemoryAuthentication().withUser("javadeveloperzone1").password("javadeveloperzone1").roles("ADMIN");
        auth.inMemoryAuthentication().withUser("javadeveloperzone2").password("javadeveloperzone2").roles("CLIENT");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .formLogin()
                .loginPage("/login").defaultSuccessUrl("/admin/home")
                .permitAll()
                .and()
                .authorizeRequests()
                .anyRequest().authenticated();

        http.logout().logoutSuccessUrl("/logoutSuccess").permitAll();
    }
}

SecurityWebApplicationInitializer.java

package com.javadeveloperzone.configs;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

/**
 * Created by Java Developer Zone on 18-03-2017.
 */
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

}

JSP Pages:

index.jsp

Logging In

In order to protect against forging log in requests the log in form should be protected against CSRF attacks too. Since the CsrfToken is stored in HttpSession, this means an HttpSession will be created as soon as CsrfToken token attribute is accessed. While this sounds bad in a RESTful / stateless architecture the reality is that state is necessary to implement practical security. Without state, we have nothing we can do if a token is compromised. Practically speaking, the CSRF token is quite small in size and should have a negligible impact on our architecture.

<%--
  Created by IntelliJ IDEA.
  User: Java Developer Zone
  Date: 18-03-2017
  Time: 07:34
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Spring Security CSRF Example</title>
</head>
<body>
<h2>Spring Security CSRF Example Demo Login page </h2>
<form name='f' action='/login' method='POST'>
    User<input type='text' name='username' value=''>
    Password:<input type='password' name='password'/>

    <input type="hidden"
           name="${_csrf.parameterName}"
           value="${_csrf.token}"/>            <%--CSRF hidden field--%>
    <input name="submit" type="submit" value="Login"/>
</form>

</body>
</html>

home.jsp

Logging Out

Adding CSRF will update the LogoutFilter to only use HTTP POST. This ensures that log out requires a CSRF token and that a malicious user cannot forcibly log out your users.

<%--
  Created by IntelliJ IDEA.
  User: Lenovo
  Date: 18-03-2017
  Time: 11:38
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Spring Security CSRF Example</title>
</head>
<body>
     <h2>String Security CSRF Example Home Page</h2>
    ${message}
    <form name='f' action='/logout' method='POST'>


        <input type="hidden"
               name="${_csrf.parameterName}"
               value="${_csrf.token}"/>  <%--CSRF hidden field--%>
        <input name="submit" type="submit" value="Login"/>
    </form>

</body>
</html>

logoutsuccess.jsp

<%--
  Created by IntelliJ IDEA.
  User: Lenovo
  Date: 10-06-2017
  Time: 11:58
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Spring Security CSRF Example</title>
</head>
<body>
        <h2>Spring Security CSRF Example logout success page</h2>
        <h2>Logout Success</h2>
</body>
</html>

Output:

Output:

Login Page

Spring Security csrf example

Spring Security csrf example

Home Page

Spring Security csrf home page example

Spring Security csrf home page example

Logout Success Page

Spring Security csrf example logout success

Spring Security csrf example logout success

References:

https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html

Leave a Reply

Your email address will not be published. Required fields are marked *