In this post I posted the sample code for Spring DAO authentication. This post is continuation of https://samplecoder.com/create-custom-login-page-for-spring-security/. In that post I posted the sample code for custom login with In-Memory Authentication but in this post I post the sample code for DAO authentication provider by using the user details service.
Spring Security
The spring security is a good framework, which is helping you to secure your web application. You can easily implement the spring security in your application. You have to follow the below steps .
- Add spring boot starter security dependency in your POM file.
- Create the configuration class by extending the WebSecurityConfigurerAdapter class.
- Override the configure method
- Declare variable for Password encoder and User Details Service.
- Define implementation class for UserDetailsService
What is DAO Authentication?
If you are using the in-memory authentication you do not need the any kind of database, you can add user details on configuration. But if you are using the DAO authentication, you should have some database and there you can maintain the user details in a separate table. User details consist of username, password and others. For my example I have used the MySQL.
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- For MVC - Start -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!-- For MVC - End -->
SecurityConfiguration.java
package com.samplecoder.emo.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
@Autowired
private UserDetailsService userDetailsService;
@Bean
public BCryptPasswordEncoder passwordEncoder() {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
return passwordEncoder;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable();
http.authorizeRequests()
.antMatchers("/loginPage","/authenticate").permitAll()
.anyRequest().authenticated()
.and().formLogin()
.loginProcessingUrl("/authenticate").usernameParameter("username").passwordParameter("password")
.loginPage("/loginPage")
.failureForwardUrl("/loginPage?error=Y")
.defaultSuccessUrl("/index", true)
.and().sessionManagement().sessionFixation().migrateSession();
}
}
SystemUser.java
package com.samplecoder.emo.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class SystemUser {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(nullable = false, unique = true)
private String username;
private String password;
@Column(nullable = false)
private String role;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
UserDetailsServiceImpl.java
package com.samplecoder.emo.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.samplecoder.emo.entity.SystemUser;
import com.samplecoder.emo.repository.UserRepository;
@Service
public class UserDetailsServiceImpl implements UserDetailsService{
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// TODO Auto-generated method stub
SystemUser user = userRepository.findByUsername(username);
if(user == null)
throw new UsernameNotFoundException("Invalid Credentials");
return new User(user.getUsername(), user.getPassword(), AuthorityUtils.createAuthorityList(user.getRole()));
}
}
UserRepository.java
package com.samplecoder.emo.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.samplecoder.emo.entity.SystemUser;
public interface UserRepository extends JpaRepository<SystemUser, Integer>{
SystemUser findByUsername(String username);
}
application.properties
spring.mvc.view.prefix=/WEB-INF/view/
spring.mvc.view.suffix=.jsp
spring.datasource.url=jdbc:mysql://localhost:3306/samplecoder
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
spring.jackson.serialization.order-map-entries-by-keys=true
spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false
ApplicationController.java
package com.samplecoder.emo.controller;
import org.springframework.boot.autoconfigure.neo4j.Neo4jProperties.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import com.samplecoder.emo.entity.SystemUser;
@Controller
public class ApplicationController {
@GetMapping("/index")
public ModelAndView index(Authentication auth) {
ModelAndView modelAndView = new ModelAndView("index");
modelAndView.addObject("user", auth.getUsername());
return modelAndView;
}
@RequestMapping(value = {"/loginPage"})
public ModelAndView loginPage(@RequestParam(name = "error", defaultValue = "N") String error,
@ModelAttribute("user") SystemUser user) {
ModelAndView modelAndView = new ModelAndView("loginpage");
user = user != null ? user : new SystemUser();
modelAndView.addObject("user", user);
modelAndView.addObject("error", error);
return modelAndView;
}
}
index.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Spring Login</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<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>
</head>
<body>
<div class="d-flex justify-content-center">
<div class="col-lg-6 card">
<div class="card-body">
<h1>Hello <c:out value="${user}"/>!. This is my spring boot MVC application</h1>
<a href="/logout" class="btn btn-danger">Logout</a>
</div>
</div>
</div>
</body>
</html>
loginpage.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Spring Login</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<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>
</head>
<body>
<div class="d-flex justify-content-center">
<div class="col-lg-4 col-md-6 col-sm-12 card">
<div class="card-body">
<h1 class="card-title">Login Here...</h1>
<c:if test="${error == 'Y'}">
<div class="alert alert-danger" role="alert">
Invalid username or password!.
</div>
</c:if>
<form:form action="/authenticate" method="post" class="col-lg-12" modelAttribute="user">
<div class="form-group">
<label>Username</label>
<form:input name="username" path="username" class="form-control"/>
</div>
<div class="form-group">
<label>Password</label>
<form:input type="password" name="password" path="password" class="form-control"/>
</div>
<div class="col-lg-12 text-right">
<button type="submit" class="btn btn-primary">Login</button>
</div>
</form:form>
</div>
</div>
</div>
</body>
</html>
Result: http://localhost:8080/loginPage



One Comment on “Spring DAO authentication”
Comments are closed.