what is spring boot security?
Spring Security is a powerful and highly customizable authentication and access-control. Its framework that focuses on providing both authentication and authorization to Java applications. We can also extend spring boot security to our requirement.
spring boot security dependency
To implement spring boot security in our project we need to add the below maven dependencies in pom.xml file.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
Once above dependencies are added to the class path Spring Boot will
automatically configure security to our application so now application will
requires the Basic Authentication for all HTTP Endpoints expect “/” and
“/home” does not require any authentication. All other endpoints require
authentication.
Project Structure
spring boot security configuration
Create a class "WebSecurityConfig" and add below annotations. Now this class acts as configuration for spring security.
@Configuration
@EnableWebSecurity
To override spring boot security we need to extends "WebSecurityConfigurerAdapter" class and override "configure" method.
import org.springframework.context.annotation.Configuration;
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;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/js/**", "/css/**", "/images/**").permitAll()
.antMatchers("/signup").permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin().loginPage("/login")
.defaultSuccessUrl("/home")
.failureUrl("/login?error=true").permitAll();
}
}
spring boot security custom login page
Create login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1" />
<title>Insert title here</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" />
<link rel="stylesheet" href="css/logincss.css" />
</head>
<body>
<div class="global-container">
<div class="card login-form">
<div th:if="${error}" class="alert alert-danger">
<p class="font-weight-bold error" th:text="${errorMessge}"></p>
</div>
<div class="card-body">
<h3 class="card-title text-center">Log in to Codepen</h3>
<div class="card-text">
<!--
<div class="alert alert-danger alert-dismissible fade show" role="alert">Incorrect username or password.</div> -->
<form id="c_form-h" class="my-3" th:action="@{/login}" method="post">
<!-- to error: add class "has-danger" -->
<div class="form-group"><label for="exampleInputEmail1">Email address</label> <input type="text" class="form-control form-control-sm" id="username" name="username" saria-describedby="emailHelp" /></div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label> <a href="#" style="float: right; font-size: 12px;">Forgot password?</a>
<input type="password" class="form-control form-control-sm" id="password" name="password" />
</div>
<button type="submit" class="btn btn-primary btn-block">Sign in</button>
<div class="sign-up">Don't have an account? <a href="#">Create One</a></div>
</form>
</div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>
The form input name must be username and password because by default spring security take this name as parameter. We can also specify other parameter name in form.
create logincss.css file.
html,
body {
height: 100%;
}
.global-container {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: #f5f5f5;
}
form {
padding-top: 10px;
font-size: 14px;
margin-top: 30px;
}
.card-title {
font-weight: 300;
}
.btn {
font-size: 14px;
margin-top: 20px;
}
.login-form {
width: 330px;
margin: 20px;
}
.sign-up {
text-align: center;
padding: 20px 0 0;
}
.alert {
margin-bottom: -30px;
font-size: 13px;
margin-top: 20px;
}
Now we will create controller to handle the request endpoint.
spring boot security custom login controller
The logincontroller handle the login request and show error message in login page if login is failed.
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class LoginController {
@GetMapping(path = "/login")
public String login(@RequestParam(value = "error", required = false, defaultValue = "false") boolean error,
Model model) {
String errorMessge = null;
if (error) {
errorMessge = "Username or Password is incorrect !!";
}
model.addAttribute("error", error);
model.addAttribute("errorMessge", errorMessge);
return "login";
}
}
Once the login is passed then home controller will return home page.
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HomeController {
@GetMapping(path = "/home")
public String showCandidates(Model model) {
System.out.println("inside home");
return "home";
}
}
Now let run the application
If provided username and password is valid then request goes to home page
If provided username and password is invalid.
How to Configure Default Username, Password?
Sometime we don’t need to login each time in testing the application in
such case we can configure default username and password in
application.properties file
spring.security.user.name=admin
spring.security.user.password=admin