Steps :
- Create DB Table that will support your authentication
- Create User Bean with all the required fields.
- Create a @Repository Bean that creates the User Bean using username
- Test step 1 and 2 by directly calling the repository via a controller
- Create implementation of UserDetails interface (UserPrincipal) using decorator pattern
- Create implementation of UserDetailsService interface (UserPrincipalDetailsService)
- Hook the new Authentication provider created into the implementation of WebSecurityConfigurerAdapter class
- Test the implementation
- This implementation almost 90% does not work at the first attempt so debug will most effeminately will be required, below points shall help
- Check if the username is getting correctly passed into loadUserByUsername() method
- Check base 64 encoding
- Check the password encoder setting
- Check the logs
- Disable the CSRF
Step 1 : Create DB Table that will support your authentication
create table emp_temp ( EMP_ID number(2), EMP_USERNAME varchar2(10), EMP_PASS varchar2(10), EMP_ROLES varchar2(50), EMP_PERMISSIONS varchar2(50) ); insert into emp_temp values (1,'Tyson','123','ADMIN',''); insert into emp_temp values (2,'Justin','123','USER',''); insert into emp_temp values (3,'Martin','123','ADMIN','MANAGER'); insert into emp_temp values (4,'Jake'',123','USER','MANAGER'); insert into emp_temp values (5,'Duke','123','ADMIN','LEAD'); insert into emp_temp values (6,'Fade'',123','USER','LEAD');

Step 2 : Create User Bean with all the required fields.
User.java
package com.springSecurity.user;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class User {
private String id;
private String username;
private String password;
private String roles;
private String permissions;
public User() {
}
public User(String id, String username, String password, String roles, String permissions) {
this.id = id;
this.username = username;
this.password = password;
this.roles = roles;
this.permissions = permissions;
}
public String getId() {
return id;
}
public void setId(String 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 getRoles() {
return roles;
}
public void setRoles(String roles) {
this.roles = roles;
}
public String getPermissions() {
return permissions;
}
public void setPermissions(String permissions) {
this.permissions = permissions;
}
public List<String> getRolesList(){
List<String> arrayList = new ArrayList<>();
if(this.roles.length()>0) {
Collections.addAll(arrayList,this.roles.split(","));
}
return arrayList;
}
public List<String> getPermissionsList(){
List<String> arrayList = new ArrayList<>();
if(this.roles.length()>0) {
Collections.addAll(arrayList,this.permissions.split(","));
}
return arrayList;
}
}
Step 3 : Create a @Repository Bean that creates the User Bean using username
UserDAO.java
package com.springSecurity.user;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
@Repository
public class UserDAO {
@Autowired
JdbcTemplate jdbcTemplate;
public User getEmpDetails(String userName) {
StringBuilder query = new StringBuilder();
query.append("select EMP_ID, EMP_USERNAME, EMP_PASS, EMP_ROLES, EMP_PERMISSIONS from emp_temp where EMP_USERNAME=?");
User user =jdbcTemplate.queryForObject(query.toString(),new Object[] {userName}, new RowMapper<User>() {
@Override
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
return new User(
rs.getString("EMP_ID"),
rs.getString("EMP_USERNAME"),
rs.getString("EMP_PASS"),
rs.getString("EMP_ROLES"),
rs.getString("EMP_PERMISSIONS"));
}
});
return user;
}
}
Step 4 :Test step 1 and 2 by directly calling the repository via a controller
Controller File
package com.springSecurity;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.springSecurity.user.User;
import com.springSecurity.user.UserService;
@RestController
public class DBController {
@Autowired
JdbcTemplate jdbcTemplate;
@Autowired
UserService userService;
@PostMapping("/empList")
public User getEmpList2(@RequestBody Map<String,String> data){
return userService.getEmpDetails(data.get("loginId"));
}
}
Service File
package com.springSecurity.user;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
UserDAO userDAO;
public User getEmpDetails(String userName) {
return userDAO.getEmpDetails(userName);
}
}
Test Using Rest Tool

Step 5 : Create implementation of UserDetails interface (UserPrincipal) using decorator pattern
UserPrincipal.java
package com.springSecurity.user;
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;
public class UserPrincipal implements UserDetails{
private static final long serialVersionUID = 1L;
private User user;
public UserPrincipal(User user) {
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> authorityList = new ArrayList<>();
this.user.getPermissionsList().forEach(p -> {
GrantedAuthority authority = new SimpleGrantedAuthority(p);
authorityList.add(authority);
});
this.user.getRolesList().forEach(p -> {
GrantedAuthority authority = new SimpleGrantedAuthority("ROLE_"+p);
authorityList.add(authority);
});
return authorityList;
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
Step 6 : Create implementation of UserDetailsService interface (UserPrincipalDetailsService)
UserPrincipalDetailsService.java
package com.springSecurity.user;
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;
@Service
public class UserPrincipalDetailsService implements UserDetailsService{
@Autowired
UserDAO userDAO;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userDAO.getEmpDetails(username);
UserPrincipal userPrincipal = new UserPrincipal(user);
return userPrincipal;
}
}
Step 7 : Hook the new Authentication provider created into the implementation of WebSecurityConfigurerAdapter class
SecurityConfig.java
package com.springSecurity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
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.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.springSecurity.user.UserPrincipalDetailsService;
@Configuration
@EnableWebSecurity
@ConditionalOnProperty (name = "myproject.security.enabled", havingValue = "true", matchIfMissing = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
UserPrincipalDetailsService userPrincipalDetailsService;
/**@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("admin1").password(passwordEncoder().encode("admin")).roles("ADMIN").and()
.withUser("admin2").password(passwordEncoder().encode("admin")).roles("ADMIN").authorities("MANAGER").and()
.withUser("user1").password(passwordEncoder().encode("user")).roles("USER").and()
.withUser("user2").password(passwordEncoder().encode("user")).roles("USER").authorities("LEAD");
}*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http
.authorizeRequests()
.antMatchers("/").permitAll()//bypass authetication and authorization
.antMatchers("/empList").permitAll()//bypass authetication and authorization
.antMatchers("/empList2").permitAll()//bypass authetication and authorization
.antMatchers("/profile").authenticated()//Authentication only required
.antMatchers("/user/**").hasRole("USER")//Authetication and Authorization required
.antMatchers("/admin/**").hasRole("ADMIN")//Authetication and Authorization required
.antMatchers("/useroradmin").hasAnyRole("ADMIN","USER")//Either admin or user role required
//permissions
.antMatchers("/listTeam").hasAuthority("LEAD")//Authetication, Authorization (since /user/** is required) and permission required
.antMatchers("/listEmp").hasAuthority("MANAGER")//Authetication, Authorization and permission required
.antMatchers("/**").denyAll()
.and()
.httpBasic();
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Bean
DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
daoAuthenticationProvider.setUserDetailsService(userPrincipalDetailsService);
return daoAuthenticationProvider;
}
@Bean
PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
// return new BCryptPasswordEncoder();
}
}
Step 8 : Test the implementation

Below is the sample controller used for testing
package com.springSecurity;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.security.RolesAllowed;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class Controller {
/**
* Accessable without Authentication and authorization
* @return
*/
@GetMapping("/")
public String getWelcomePage() {
return "Hello....welcome to our website";
}
/**
* All logged in users
* Accessable with authentication but authorization not required
* @return
*/
@GetMapping("/profile")
public String getProfile() {
return "Welcome to profile page";
}
/**
* Only logged in user with role USER can access this
* @return
*/
@GetMapping("/user")
public String getUser() {
return "Hello User Role";
}
/**
* Only loggged in admin can access this
* @return
*/
@GetMapping("/admin")
public String getAdmin() {
return "Hello Admin Role";
}
/**
* Either User or Admin
* @return
*/
@GetMapping("/useroradmin")
public String getUserOrAdmin() {
return "Hello User or Admin Role";
}
@GetMapping("/listTeam")
public List<String> listTeam() {
List<String> list = new ArrayList();
list.add("Team Memeber 1");
list.add("Team Memeber 2");
list.add("Team Memeber 3");
return list;
}
@GetMapping("/listEmp")
public List<String> listEmp() {
List<String> list = new ArrayList();
list.add("Team Memeber 1");
list.add("Team Memeber 2");
list.add("Team Memeber 3");
list.add("Team Lead 1");
list.add("Team Lead 2");
return list;
}
}
Get the UserDetails from the Spring Security using below steps :
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
username = ((UserDetails)principal).getUsername();
} else {
username = principal.toString();
}
Reference :
Code :
GitHub : Branch – spring-security-db-authentication