Role Based Login in Spring Boot

OnlineJobPortalApplication.java


package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
	
@SpringBootApplication
public class OnlineJobPortalApplication {
	
	public static void main(String[] args) {
		SpringApplication.run(OnlineJobPortalApplication.class, args);
	}
	
}
	

SecurityConfig.java


package com.example.demo.config;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
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.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import com.example.demo.model.Login;
import com.example.demo.respository.LoginRepository;
import com.example.demo.service.CustomLoginDetailService;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	@Autowired
	private CustomLoginDetailService customLoginDetailService;
	@Autowired
	private LoginRepository loginRepository;

	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
		auth.userDetailsService(customLoginDetailService).passwordEncoder(passwordEncoder());
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		
		http.csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("**/login")).and().authorizeRequests().antMatchers("/", "/register","/login").permitAll().antMatchers("/recruiter/**")
				.hasAuthority("Recruiter").antMatchers("/seeker/**").hasAuthority("Seeker").anyRequest().authenticated()
				.and().formLogin().loginPage("/login").usernameParameter("username").permitAll().successHandler(new AuthenticationSuccessHandler() {

					@Override
					public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
						Authentication authentication) throws IOException, ServletException {
						
						Login login=loginRepository.getLoginByEmail(request.getParameter("username"));
						response.sendRedirect(login.getRole().toLowerCase());
					}
				}).failureForwardUrl("/error").and().logout().permitAll();
	}

	@Bean
	@Override
	public AuthenticationManager authenticationManagerBean() throws Exception {
		return super.authenticationManagerBean();
	}

	@Bean
	public BCryptPasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}

}

LoginController.java


package com.example.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import com.example.demo.model.Login;
import com.example.demo.respository.LoginRepository;

@Controller
public class LoginController {

	@Autowired
	private LoginRepository loginRepository;

	@Autowired
	private BCryptPasswordEncoder bCryptPasswordEncoder;

	@PostMapping("/register")
	public String register(Login login) {
		String encodepassword = bCryptPasswordEncoder.encode(login.getPassword());
		login.setPassword(encodepassword);
		loginRepository.save(login);
		return "redirect:/" + login.getRole().toLowerCase();
	}

	@PostMapping("/home")
	public String home(Login login) {
		return login.getRole();
	}

	@GetMapping("/recruiter")
	public String recruiterPage(Login login) {
		return "recruiter";
	}

	@GetMapping("/seeker")
	public String seekerPage(Login login) {
		return "seeker";
	}

	@GetMapping("/login")
	public String loginPage() {
		return "login";
	}

}

PageController.java


package com.example.demo.controller;

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

@Controller
public class PageController {

	@GetMapping("/")
	public String mainPage() {
		return "index";
	}

	@GetMapping("/error")
	public String errorPage() {
		return "redirect:/404";
	}
	@GetMapping("/404")
	public String error() {
		return "error";
	}

}

RecruiterController.java


package com.example.demo.controller;

public class RecruiterController {

}

SeekerController.java


package com.example.demo.controller;

public class SeekerController {

}

CustomLoginDetail.java


package com.example.demo.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

@Component
public class CustomLoginDetail implements UserDetails {
	private Login login;

	public CustomLoginDetail(Login login) {
		this.login = login;
	}

	public CustomLoginDetail() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
		authorities.add(new SimpleGrantedAuthority(login.getRole()));
		return authorities;
	}

	@Override
	public String getPassword() {
		return login.getPassword();
	}

	@Override
	public String getUsername() {
		return login.getEmail();
	}

	@Override
	public boolean isAccountNonExpired() {
		return true;
	}

	@Override
	public boolean isAccountNonLocked() {
		return true;
	}

	@Override
	public boolean isCredentialsNonExpired() {
		return true;
	}

	@Override
	public boolean isEnabled() {
		return true;
	}
}

Login.java


package com.example.demo.model;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "logins")
public class Login {
	@Id
	private String email;
	private String password;
	private String role;

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	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;
	}

}

Recruiter.java


package com.example.demo.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.springframework.beans.factory.annotation.Value;

@Entity
@Table(name = "recruiters")
public class Recruiter {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private int id;
	@Value("")
	private String name;
	@Value("")
	private String company;
	@Column(unique = true)
	private String email;
	@Column(unique = true)
	@Value("")
	private String contact;
	@Value("")
	private String website;
	@Value("")
	private String companydesc;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getCompany() {
		return company;
	}

	public void setCompany(String company) {
		this.company = company;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getContact() {
		return contact;
	}

	public void setContact(String contact) {
		this.contact = contact;
	}

	public String getWebsite() {
		return website;
	}

	public void setWebsite(String website) {
		this.website = website;
	}

	public String getCompanydesc() {
		return companydesc;
	}

	public void setCompanydesc(String companydesc) {
		this.companydesc = companydesc;
	}

}

Seeker.java


package com.example.demo.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.springframework.beans.factory.annotation.Value;

@Entity
@Table(name = "seekers")
public class Seeker {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private int id;
	@Value("")
	private String name;
	@Column(unique = true)
	private String email;
	@Value("")
	private String mobile;
	@Value("")
	private String resumeurl;
	@Value("")
	private String image;
	@Value("")
	private String category;
	@Value("")
	private String experience;
	@Value("")
	private String technology;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getMobile() {
		return mobile;
	}

	public void setMobile(String mobile) {
		this.mobile = mobile;
	}

	public String getResumeurl() {
		return resumeurl;
	}

	public void setResumeurl(String resumeurl) {
		this.resumeurl = resumeurl;
	}

	public String getImage() {
		return image;
	}

	public void setImage(String image) {
		this.image = image;
	}

	public String getCategory() {
		return category;
	}

	public void setCategory(String category) {
		this.category = category;
	}

	public String getExperience() {
		return experience;
	}

	public void setExperience(String experience) {
		this.experience = experience;
	}

	public String getTechnology() {
		return technology;
	}

	public void setTechnology(String technology) {
		this.technology = technology;
	}

}

LoginRepository.java


package com.example.demo.respository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.example.demo.model.Login;

@Repository
public interface LoginRepository extends JpaRepository<Login, String> {

	Login getLoginByEmail(String email);

}

RecruiterRepository.java


package com.example.demo.respository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.example.demo.model.Recruiter;

@Repository
public interface RecruiterRepository extends JpaRepository<Recruiter, Integer> {

}

SeekerRepository.java


package com.example.demo.respository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.example.demo.model.Seeker;

@Repository
public interface SeekerRepository extends JpaRepository<Seeker, Integer> {

}

CustomLoginDetailService.java


package com.example.demo.service;

import org.springframework.beans.factory.annotation.Autowired;
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.example.demo.model.CustomLoginDetail;
import com.example.demo.model.Login;
import com.example.demo.respository.LoginRepository;

@Service
public class CustomLoginDetailService implements UserDetailsService {
	@Autowired
	private LoginRepository loginRepository;

	@Override
	public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
		System.out.println("loaduserbyusername " + email);
		Login login = loginRepository.getLoginByEmail(email);

		if (login == null) {
			throw new UsernameNotFoundException("Could not find login user");
		}

		return new CustomLoginDetail(login);
	}
}

LoginService.java


package com.example.demo.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.demo.model.Login;
import com.example.demo.model.Recruiter;
import com.example.demo.model.Seeker;
import com.example.demo.respository.LoginRepository;
import com.example.demo.respository.RecruiterRepository;
import com.example.demo.respository.SeekerRepository;

@Service
public class LoginService {

	@Autowired
	private LoginRepository loginRepository;
	@Autowired
	private RecruiterRepository recruiterRepository;
	@Autowired
	private SeekerRepository seekerRepository;

	public Login login(Login login) {
		Login loginDB = loginRepository.getLoginByEmail(login.getEmail());
		return login;
	}

	public String register(Login login) {
		try {
			if (login.getRole().equalsIgnoreCase("recruiter")) {
				Recruiter recruiter = new Recruiter();
				recruiter.setEmail(login.getEmail());
				recruiterRepository.save(recruiter);
			} else {
				Seeker seeker = new Seeker();
				seeker.setEmail(login.getEmail());
				seekerRepository.save(seeker);
			}
			loginRepository.save(login);
			return "Successfully Registered";
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		return "Registered Failed";
	}

}

RecruiterService.java


package com.example.demo.service;

public class RecruiterService {
	
}	

SeekerService.java


package com.example.demo.service;

public class SeekerService {

}

login.js


	$(document).ready(function() {
		$("#register").click(function() {
			var email = $("#email").val();
			var pwd = $("#pwd").val();
			var role = $("#role").val();
	
			if (email == "") {
				alert("Please Enter Email");
				$("#email").focus();
			} else if (pwd == "") {
				alert("Please Enter Password");
				$("#pwd").focus();
			} else if (role == "Select Role") {
				alert("Please Select Role");
				$("#role").focus();
			} else {
				$.post("register", {
					email : email,
					password : pwd,
					role : role,
				}, function(response) {
					alert(response);
				});
			}
		});
	
	});

add.html


<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<span th:insert="head.html"></span>

error.html


<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<span th:insert="head.html"></span>
<div class="container">
	<div align="center">
		<div>
			<button onclick="function go(){location.replace('/')}go()">GO TO HOME PAGE</button>
		</div>
		<br>
		<div>
			<img
				src="https://mir-s3-cdn-cf.behance.net/project_modules/fs/6b443b70759853.5bade2d0a6685.png"
				width="80%" height="500px">
		</div>
	</div>

</div>

head.html


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
	xmlns:sec="http://www.thymeleaf.org/extras/spring-security">

<head>
<title>Online Job Portal</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
	
<style>
.navbar {
	border-radius: 0px !important;
}
</style>
</head>

<nav class="navbar navbar-inverse" style="background-color: maroon;">
	<div class="container-fluid">
		<div class="navbar-header">
			<button type="button" class="navbar-toggle" data-toggle="collapse"
				data-target="#myNavbar">
				<span class="icon-bar"></span> <span class="icon-bar"></span> <span
					class="icon-bar"></span>
			</button>
			<a class="navbar-brand" href="#">JOB PORTAL</a>
		</div>
		<div class="collapse navbar-collapse" id="myNavbar">

			<ul class="nav navbar-nav">
				<li><a href="/">Home</a></li>
			</ul>


			<div sec:authorize="isAuthenticated()">
				<ul class="nav navbar-nav navbar-right">
					<li><a>Add Job</a></li>
					<li><a>Job List</a></li>
					<li><a>Profile</a></li>
					
					<li>
						<form action='/logout' method="post"
							style="margin-top: 5px;">
							<input type="submit" value="Logout" class="btn btn-link"> <input type="hidden"
								name="${_csrf.parameterName}" value="${_csrf.token}"/>
						</form>
					</li>
				</ul>

			</div>


		</div>
	</div>
</nav>

application.properties


server.port=9999
debug=true
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.url=jdbc:mysql://localhost:3306/jobportal
#spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update

pom.xml


	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-mail</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</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>
		<dependency>
			<groupId>org.thymeleaf.extras</groupId>
			<artifactId>thymeleaf-extras-springsecurity5</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

Output Screens:







No comments: