I was working on Spring Boot Security project and i did the authentication on some endpoints to prevent from access from USERS and granted the authority to ADMIN when ever i hit this URL : admin/users i got the login page i put the credentials and instead of returning the actual content its return type=Forbidden, status=403
here is my SecurityConfig
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// inject spring user details interface
#Autowired
private UserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(encoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/api/**" , "/").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and().formLogin();
}
#Bean
public BCryptPasswordEncoder encoder(){
return new BCryptPasswordEncoder();
}
}
admin users controller
#RestController
#RequestMapping("admin/users")
public class UserController {
//
#Autowired
private UserRepository userRepository;
#Autowired
private BCryptPasswordEncoder passwordEncoder;
// get all users
#PreAuthorize("hasAnyRole('ADMIN')")
#GetMapping
public List<User> getAllUsers(){
return userRepository.findAll();
}
// test
#PreAuthorize("hasAnyRole('ADMIN')")
#GetMapping("/test")
public String message() {
return "secured end point";
}
//create new users
#PreAuthorize("hasAnyRole('ADMIN')")
#PostMapping
public User registerUser(#RequestBody User user){
String password = user.getPassword();
String encodedPassword = passwordEncoder.encode(password);
user.setPassword(encodedPassword);
return userRepository.save(user);
}
}
userDetail
public class CustomUserDetails implements UserDetails {
/**
*
*/
private static final long serialVersionUID = 1256711395932122675L;
private User user;
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return user.getRoles().stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role))
.collect(Collectors.toList());
}
#Override
public String getPassword() {
return user.getPassword();
}
#Override
public String getUsername() {
return user.getUsername();
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return true;
}
}
userDetailsService
[![#Service
public class CustomUserDetailsService implements UserDetailsService {
#Autowired
private UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
CustomUserDetail userDetail = null;
if(user != null) {
userDetail = new CustomUserDetail();
userDetail.setUser(user);
}
else {
throw new UsernameNotFoundException("user not exist with username " + username);
}
System.out.println("user details" + userDetail);
return userDetail;
}
}][2]][2]
I fixed the issue by simply correcting the getAuthorities() I removed "ROLE_" in simpeGrantedAuthority() , extracted the return into a variable in userDetail.java and used hasAuthority() instead of hasRole()
the code which was getting 403 - forbidden
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return user.getRoles().stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role))
.collect(Collectors.toList());
}
**the solution **
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<SimpleGrantedAuthority> authorities = user.getRoles().stream().map(role ->
new SimpleGrantedAuthority(role.getRole()))
.collect(Collectors.toList());
return authorities;
}
Related
I added spring security to my app. I would like to secure any endpoints, and open "/users" for all
User configuration:
#Entity
#Table(name = "users")
#AllArgsConstructor
#NoArgsConstructor
public class UserEntity implements UserDetails {
#Id
private String id;
private String login;
private String password;
private String role;
public UserEntity(UserCreateRequestModel userCreateRequestModel) {
this.id = UUID.randomUUID().toString();
this.login = userCreateRequestModel.getLogin();
this.password = PasswordService.codePassword(userCreateRequestModel.getPassword());
this.role = "USER";
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<SimpleGrantedAuthority> list = new ArrayList<>();
list.add(new SimpleGrantedAuthority(role));
return new ArrayList<SimpleGrantedAuthority>();
}
#Override
public String getUsername() {
return login;
}
#Override
public String getPassword() {
return password;
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return true;
}
My custom WebSecurityConfigurerAdapter:
#Configuration
#EnableWebSecurity
#RequiredArgsConstructor
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
private final MyUserDetailsService myUserDetailsService;
#Override
public void configure(HttpSecurity http) throws Exception {
http
.cors().and().csrf().disable()
.authorizeRequests()
.antMatchers("/users", "/users/**").permitAll()
.anyRequest().hasAuthority("USER")
;
}
#Override
protected UserDetailsService userDetailsService() {
return myUserDetailsService;
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailsService);
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
and next I added custom UserDetailsService
#Service
#RequiredArgsConstructor
public class MyUserDetailsService implements UserDetailsService {
private final UserEntityRepository userEntityRepository;
#Override
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
System.out.println(userEntityRepository.findByLogin(login));
return userEntityRepository.findByLogin(login).orElseThrow((() -> new ObjectNotFoundException(login)));
}
and now I am getting problem. Endpoint for "/users" is open to all, I can send request with any problem. But when I am trying for example any #PostMapping on endpoint "/shapes"
I am getting 403 status response. In postman I think everything is OK:
of course user exists in database. In UserEntity user isEnabled, isAccountNonExpired, isAccountNonLocked and isCredentialsNonExpired - everything is on true.
In your getAuthorities() method of UserEntity class you're returning an empty List, so spring-security sees no authorities (roles) for an authenticated user.
Change this method like this:
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.singletonList(new SimpleGrantedAuthority(role));
}
I am trying to learn Spring security where I am facing a problem with Role based security.
There are 2 tables User and Role having One to Many realtions.
When I enter username and password in spring default form, I successfully fetch correct Users deatails through loadUserByUserName() method. But on screen I get a message like
This application has no explicit mapping for /error, so you are seeing
this as a fallback.
There was an unexpected error (type=Forbidden, status=403). Forbidden
Only #GetMapping("/user") method works properly.
Here is the controller part
#RestController
#RequestMapping("/admin")
public class AdminController {
#Autowired
UserRepository userRepo;
#Autowired
RoleRepository roleRepo;
#PreAuthorize("hasAnyRole('ADMIN')")
#PostMapping("/add")
public String addUserByAdmin(#RequestBody User user)
{
user.getRoles().forEach(role -> role.setUser(user));
userRepo.save(user);
return "User added Successfully";
}
#PreAuthorize("hasAnyRole('ADMIN')")
#GetMapping("/process")
public String process()
{
return "Processing....";
}
#GetMapping("/user")
public String users() // This code is working properly
{
System.out.println("U r in user area's");
return "User's space";
}
}
Configuration part
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
#EnableJpaRepositories(basePackageClasses = UserRepository.class)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
protected void configure(HttpSecurity http)throws Exception
{
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/admin/**").authenticated()
.anyRequest().permitAll()
.and()
.formLogin().permitAll();
}
}
Service part
#Service
public class CustomeUserDetailsService implements UserDetailsService
{
#Autowired
UserRepository userRepo;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User u = userRepo.findByName(username);
CustomeUserDetails cUserDetails = new CustomeUserDetails();
if(u == null)
{
throw new UsernameNotFoundException("User "+username +"not found");
}
else
{
cUserDetails.setUser(u);
}
return cUserDetails;
}
}
Where am I wrong ?
What if I want to add one more URL which does not require any authnetication and authorization , how to add it ?
I think you should use "ROLE_ADMIN" instead of "ADMIN". The "ROLE_ADMIN" key can be saved in the database and turned into Collection. Below how I did.
CLASS THAT IMPLEMENTS USERDETAILS
public class UsuarioSS implements LdapUserDetails {
private static final long serialVersionUID = 1164806375870272028L;
private String cdusuariorede;
private Collection<GrantedAuthority> authorities;
public UsuarioSS() {
}
public UsuarioSS(String cdusuariorede,List<Perfil> perfis) {
super();
this.cdusuariorede = cdusuariorede;
this.authorities = new ArrayList<GrantedAuthority>();
for (Perfil perfil : perfis) {
this.authorities.add(new SimpleGrantedAuthority(perfil.toString()));
}
}
public String getId() {
return cdusuariorede;
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
#Override
public String getPassword() {
return null;
}
#Override
public String getUsername() {
return cdusuariorede;
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return true;
}
public boolean hasRole(String springSecurityKey) {
return getAuthorities().contains(new SimpleGrantedAuthority(springSecurityKey));
}
#Override
public void eraseCredentials() {
// TODO Auto-generated method stub
}
#Override
public String getDn() {
// TODO Auto-generated method stub
return null;
}
}
ENUM THAT REPRESENTS MY USER PROFILES (AUTHORITHYES)
public enum Perfil {
ROLE_ADMIN,ROLE_DEFAULT
}
A AUTHORIZATION FILTER
public class JWTAuthorizationFilter extends BasicAuthenticationFilter {
private JWTUtil jwtUtil;
private UserDetailsService userDetailsService;
public JWTAuthorizationFilter(AuthenticationManager authenticationManager, JWTUtil jwtUtil,
UserDetailsService userDetailsService) {
super(authenticationManager);
this.jwtUtil = jwtUtil;
this.userDetailsService = userDetailsService;
}
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
String header = request.getHeader("Authorization");
if (header != null && header.startsWith("Bearer ")) {
UsernamePasswordAuthenticationToken auth = getAuthentication(header.substring(7));
if (auth != null) {
SecurityContextHolder.getContext().setAuthentication(auth);
}
}
chain.doFilter(request, response);
}
private UsernamePasswordAuthenticationToken getAuthentication(String token) {
if (jwtUtil.tokenValido(token)) {
String login = jwtUtil.getLogin(token);
UserDetails usuario = userDetailsService.loadUserByUsername(login);
return new UsernamePasswordAuthenticationToken(usuario, null, usuario.getAuthorities());
}
return null;
}
}
MY CONTROLLER
#RestController
#RequestMapping(value = "/parte")
public class ParteController {
#Autowired
private ParteService service;
#PreAuthorize("hasAnyRole('ROLE_ADMIN')")
#GetMapping("/partes_demandadas_por_processo")
public ResponseEntity<List<TpPartesProcessoDto>> getPartesPorNuprocesso(
#RequestParam(name = "processo",required = true)
#Length(max = 15,min = 15,message = "O campo processo deve possuir 15 caracteres.")
String processo
) throws SQLException{
List<TpPartesProcessoDto> partes = service.getPartesdoProcessoPorNuprocesso(processo);
return ResponseEntity.ok().body(partes);
}
}
I am new to spring boot and spring security and not able to understand the following error on my own.
my spring boot application simply contains two URLs one which is accessed by anyone i.e, only by whose name password is saved in database and another which can only ADMIN can access(to add user and there roll in MySql database).
But when i am passing username and password it saying:-
org.springframework.security.authentication.InternalAuthenticationServiceException: UserDetailsService returned null, which is an interface contract violation
I am posting all necessary class below:-
CustomUserDetailService:-
#Service
public class CustomUserDetailService implements UserDetailsService {
#Autowired
private UserRepository repository;
#Override
public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
User user= repository.findByname(name);
CustomUserDetail userDetail=null;
if(user!=null){
CustomUserDetail userDetails=new CustomUserDetail();
userDetails.setUser(user);
}else{
throw new UsernameNotFoundException("User not exist with name :" +name);
}
return null;
}
}
CustomUserDetail
public class CustomUserDetail implements UserDetails {
private User user;
/*Getter and Setter*/
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
/*Overriden methods from userDetail*/
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return user.getRoles().stream().map(role -> new SimpleGrantedAuthority("Role_"+role))
.collect(Collectors.toList());
}
#Override
public String getPassword() {
return user.getPassword();
}
#Override
public String getUsername() {
return user.getName();
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return true;
}
}
BasicConfig:-
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class BasicConfig extends WebSecurityConfigurerAdapter{
#Autowired
private UserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth.userDetailsService(userDetailsService).passwordEncoder(encodePWD());
}
#Override
protected void configure(HttpSecurity http) throws Exception
{
http.csrf().disable();
http
.authorizeRequests()
.antMatchers("/user/").permitAll()
.and()
.authorizeRequests()
.antMatchers("/MiniApi/**").hasAnyRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.permitAll();
}
#Bean
public BCryptPasswordEncoder encodePWD()
{
return new BCryptPasswordEncoder();
}
}
Controller Classes:-
I am not making two #Restcontroller classes and only single #RequestMapping() is acting as base URL
AdminController:-
#RestController
#RequestMapping("/MiniApi")
public class Admincontroller
{
#Autowired
private UserRepository userRepository;
#Autowired
private BCryptPasswordEncoder passwordEncoder;
#PreAuthorize("hasAnyRole('ADMIN')")
#PostMapping("/admin/add")
public String addUser(#RequestBody User user)
{
String pwd = user.getPassword();
String encryptPwd = passwordEncoder.encode(pwd);
user.setPassword(encryptPwd);
userRepository.save(user);
return "User added successfully...";
}
}
AnyOne:-
public class AnyOne {
#GetMapping("/anyone")
public String Anyone()
{
return "processing......";
}
}
Change what i made:-
If i am removing return statement from CustomUserDetailService i am getting return statement missing error and then i added return userDetails;
it gives me :-
First it askes me for username and password i provided it and then this
HTTP Status 403 – Forbidden
You are returning null instead of userDetails
#Service
public class CustomUserDetailService implements UserDetailsService {
#Autowired
private UserRepository repository;
#Override
public UserDetails loadUserByUsername(String name) throws
UsernameNotFoundException {
User user= repository.findByname(name);
CustomUserDetail userDetail=null;
if(user != null){
CustomUserDetail userDetails=new CustomUserDetail();
userDetails.setUser(user);
return userDetails;
}
throw new
UsernameNotFoundException("User not exist with name :" +name);
}
}
I'm implementing Spring Security in a project. we are using hibernate as ORM. The problem I'm getting is the page is redirecting to white level error page saying Access Is Denied though we are entering the right credentials.
The roles and users are stored in the db. I have craeted a CustomUserDetails class CustomUserDetails class too. But didn't getting any reason why it's not wrking.
CustomUserDetails
public class CustomUserDetals implements UserDetails {
#Autowired
private User user;
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return user.getRole().stream().map(role-> new SimpleGrantedAuthority("ROLE_"+role))
.collect(Collectors.toList());
}
#Override
public String getPassword() {
// TODO Auto-generated method stub
return user.getPassword();
}
#Override
public String getUsername() {
// TODO Auto-generated method stub
return user.getUserName();
}
#Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return true;
}
#Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return true;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
SeccrityConfig
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Autowired
private UserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(encodePwd());
}
#Bean
public BCryptPasswordEncoder encodePwd() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests().antMatchers("/user/admin/").authenticated().anyRequest().hasAnyRole("superadmin").and()
.authorizeRequests().antMatchers("/user/welcome/").authenticated().anyRequest().hasAnyRole("user").and()
.authorizeRequests().antMatchers("/").authenticated().anyRequest().permitAll().and().formLogin()
.permitAll();
}
}
CustomUserDetailsService
Service
#Transactional
public class CustomUserDetailsService implements UserDetailsService{
#Autowired
private UserRoleRepo repo;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user= repo.findUserWithUsername(username);
CustomUserDetals details= null;
if(user!= null) {
details= new CustomUserDetals();
details.setUser(user);
}else {
throw new UsernameNotFoundException("User Not Exist With Name"+ username);
}
return details;
}
}
RepositoryMethod
#Override
public User findUserWithUsername(String username) {
Query query= getSession().createQuery(loadUserName);
query.setString(0, username);
User u= null;
Iterator<User> iterator= query.iterate();
while(iterator.hasNext()) {
u= iterator.next();
System.out.println(u.getUserName()+" "+u.getMobileNo()+" "+u.getRole().toString());
}
return u;
}
Controller
#RestController
#RequestMapping("/user")
public class UserRoleController {
#Autowired
private BCryptPasswordEncoder encoder;
#Autowired
private UserRoleService service;
/*
* #PostMapping("/add") public ResponseEntity<String> saveUser(#RequestBody User
* user) { String pass = user.getPassword();
* user.setPassword(encoder.encode(pass)); String temp = service.saveUser(user);
* return new ResponseEntity<String>(temp, HttpStatus.OK); }
*/
#GetMapping("/welcome")
#PreAuthorize("hasAnyRole('user')")
public String iMUser() {
System.out.println("WORKED");
return "Worked";
}
#GetMapping("/admin")
#PreAuthorize("hasAnyRole('superadmin')")
public ResponseEntity<String> saveUser(){
User user= new User();
Set<Role> role= new HashSet<Role>();
Role role1= new Role();
role1.setRole("user");
user.setUserName("amalswain");
user.setPassword(encoder.encode("password"));
user.setMobileNo(7606844075L);
role.add(role1);
role.add(role1);
role1.setUser(user);
user.setRole(role);
String temp= service.saveUser(user);
return new ResponseEntity<String>(temp,HttpStatus.OK);
}
}
403- Forbidden
In configure method from SecurityConfig try this:
http.csrf().disable()
.authorizeRequests()
.antMatchers("/user/admin/").hasRole("superadmin")
.antMatchers("/user/welcome/").hasAnyRole("user")
.antMatchers("/").permitAll()
.and()
.formLogin().permitAll();
I am learning how to use Spring and how to implement Spring Security in my project, using Roles and MongoDB.
I have a User model with a role list, and I want to let only ADMIN user to use some endpints from Controller.
Here is the User class and Role enum:
#Document(collection = "Users")
public class User {
#Id
private String id;
private String firstName;
private String lastName;
private String email;
private String password;
private List<Role> roles;
//constructor + getters and setters
}
public enum Role {
ADMIN,
BASIC_USER
}
I use the this UserDetails implementation: I think here is the problem...
public class CustomUserDetails implements UserDetails {
private User user;
public CustomUserDetails() {
}
public CustomUserDetails(User user) {
this.user = user;
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.user.getRoles().stream().map(role -> new SimpleGrantedAuthority(String.format("ROLE_%s", role))).collect(Collectors.toList());
}
#Override
public String getPassword() {
return this.user.getPassword();
}
#Override
public String getUsername() {
return this.user.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;
}
public User getUser() {
return user;
}
}
The UserDetailsService looks like this:
public class CustomUserDetailsServiceImpl implements UserDetailsService {
#Autowired
private UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
final User user = userRepository.findByEmail(email);
if (Objects.isNull(user)) {
throw new UsernameNotFoundException("User not found");
}
return new CustomUserDetails(user);
}
}
I made this configuration:
#Configuration
#EnableWebSecurity(debug = true)
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(createUserDetailsService()).passwordEncoder(passwordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http
.authorizeRequests()
.antMatchers(HttpMethod.POST, "/users/**").permitAll()
.antMatchers( "/users/**").authenticated().anyRequest().hasAnyRole("ADMIN")
.antMatchers("/users/me").authenticated().anyRequest().hasAnyRole("ADMIN", "BASIC_USER")
.antMatchers( "/users/**").permitAll()
.and()
.formLogin().disable()
.httpBasic();
}
#Override
public void configure(WebSecurity web) throws Exception {
/* To allow Pre-flight [OPTIONS] request from browser */
web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
}
/**
* Create password encoder bean used for encrypting the password
*
* #return
*/
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* Create user service bean used for find the user by email
* #return
*/
#Bean
public UserDetailsService createUserDetailsService() {
return new CustomUserDetailsServiceImpl();
}
}
When I make any call with Postman at localhost:8080/users using Basic auth with the admin details from DB, all the time I get 401 Unauthorized Status
I think the problem is that I use an Enum for Roles and I don't know how to correctly build UserDetails implementation.
If helps, this is the UserController
#RestController
#RequestMapping("/users")
public class UserController {
#Autowired
private UserService userService;
#GetMapping(path = "")
public List<User> getUsers(){
return this.userService.getUsers();
}
}
When I used MySQL for this project (With the same classes for security) the apps worked perfectly. In that implementation I used Roles, Users and Users_Roles tables.