Spring MVC Login Logout

In this tutorial we will learn how to create a simple login and logout function with spring security and implement it in spring MVC.

Technologies and Tools

  • gradle
  • spring mvc
  • spring boot
  • spring security

The gradle file for the project

build.gradle

/*
 * This file was generated by the Gradle 'init' task.
 *
 * This generated file contains a sample Java project to get you started.
 * For more details take a look at the Java Quickstart chapter in the Gradle
 * User Manual available at https://docs.gradle.org/5.3/userguide/tutorial_java_projects.html
 */

plugins {
    // Apply the java plugin to add support for Java
    id 'java'
    id 'org.springframework.boot' version '2.1.3.RELEASE'
    id "io.spring.dependency-management" version "1.0.7.RELEASE"
	
    // Apply the application plugin to add support for building an application
    id 'application'
    id 'eclipse'
}

repositories {
    // Use jcenter for resolving your dependencies.
    // You can declare any Maven/Ivy/file repository here.
    mavenCentral()
    jcenter()
}

dependencies {
    // This dependency is found on compile classpath of this component and consumers.
    implementation 'com.google.guava:guava:27.0.1-jre'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    
    //spring security
    implementation 'org.springframework.boot:spring-boot-starter-security'

    // Use JUnit test framework
    testImplementation 'junit:junit:4.12'
}

// Define the main class for the application
mainClassName = 'my.cychew.App'

Login Controller

package my.cychew.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class LoginController {

	@GetMapping("/")
	public ModelAndView loginPage() {
		return new ModelAndView("loginForm");
	}

	@GetMapping("/end")
	public String logoutPage() {
		return "logout";
	}
}

the loginPage method will contain of the login form page and logoutPage is the page that will show after successfully logout.

Landing Controller

package my.cychew.controller;

import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class LandingController {

	@GetMapping("/landing")
	public ModelAndView landing(Authentication auth) {
		return new ModelAndView("landing").addObject("name", auth.getName());
	}
}

Landing Controller will get logged in user info from security context and display it at landing page.

AppConfig

package my.cychew;

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;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;

@Configuration
@EnableWebSecurity
public class AppConfig extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		//authentication manager
		auth.inMemoryAuthentication()
		//no operation password encoder is use for testing purpose only
		.passwordEncoder(NoOpPasswordEncoder.getInstance())
			.withUser("tester").password("password").roles("USER");
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		//disable csrf to test GET logout
		http.csrf().disable()
        .authorizeRequests()
            .antMatchers("/").permitAll()
            .anyRequest().authenticated()
            .and()
        .formLogin()
            .loginPage("/")
            .loginProcessingUrl("/login")
            .defaultSuccessUrl("/landing")
            .permitAll()
            .and()
        .logout()
        	.logoutSuccessUrl("/end")
        	.permitAll();
	}
	
}

This configuration file is the one who did all the tricks for login and logout.

In the protected void configure(AuthenticationManagerBuilder auth), we will create a in memory authentication manager for authenticate the password. For our case, I will just create one user name “tester” and password is “password” that having USER role.

First, we will have to deny all the request url except for login and logout page. So we will use .authorizeRequests() .antMatchers(“/”).permitAll() to allow login page and .anyRequest().authenticated() to ask all other request must be authenticated.

Then we will configure the formLogin() and logout() for the url, and it is quite straight forward. loginPage() is the login form page. loginProcessingUrl() is the POST url for login form, and of course the redirect url after successful login defaultSuccessUrl()

loginForm.html

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Login Form</title>
</head>
<body>
	<div th:if="${param.error}">Invalid username and password.</div>

	<form th:action="@{/login}" method="post">
		<div>
			Username: <input name="username" type="text" />
		</div>
		<div>
			Password: <input name="password" type="password" />
		</div>
		<div>
			<input type="submit" value="Submit" />
		</div>
	</form>
</body>
</html>

landing.html

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Landing Page</title>
</head>
<body>
	Hello <span th:text=${name}></span> !
	<div><a href="/logout">Logout</a></div>
</body>
</html>

logout.html

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Logout</title>
</head>
<body>
	You have logged out.
</body>
</html>

Now we test it out with application with gradle bootrun. If you are not familiar with spring boot or how to create a spring boot project, you can refer my previous post here.

If we enter wrong user and password, we will get redirect to /?error and prompt us the error message.

So we just enter the correct username and password, it should navigate us to the landing page.

And let’s click on the logout link.

This will actually logout us out, and if we change the url directly to /landing the application also will block us and route to the login page.

Spring MVC Login Logout
Tagged on:             

Leave a Reply

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