Blog Detail

  • Home
  • Spring Security DAO authentication

Spring Security DAO authentication

In this post I posted the sample code for Spring Security 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 user details service.

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

Login
Login Page
Login Error Page
Login Error Page
Login Success
Login Success Page

Write a comment