String Boot REST security Error : type=Forbidden, status=403 - spring-boot

This project I have used Spring boot, security authentication, JPA and REST
This gives me 403 error, which is of role base error. I have tried for 2 days could not solve please help.
Here I am sharing code.
This is my Security config class have roles based /hello for all user and /admin/all and /admin/add for admin user.
#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(encodePsw());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests().antMatchers("/api/secure/admin/**").hasRole("ADMIN").antMatchers("/api/secure/**")
.hasAnyRole("USER", "ADMIN").anyRequest().authenticated().and().formLogin().permitAll();
}
#Bean
public BCryptPasswordEncoder encodePsw() {
return new BCryptPasswordEncoder();
}
}
This is my Controller class have 3 method which is or 3 role based /hello for all user and /admin/all and /admin/add for admin user.
#RestController
#RequestMapping("/api/secure")
public class AdminController {
#Autowired
private UserRepository userRepo;
#Autowired
private BCryptPasswordEncoder passEncp;
#RequestMapping(value = "/hello")
public String hello() {
return "Hello..";
}
//#PreAuthorize("hasAnyRole('ADMIN')")
#RequestMapping(value = "/admin/add", method = RequestMethod.POST)
public String addUserByAdmin(#RequestBody User user) {
user.setPassword(passEncp.encode(user.getPassword()));
userRepo.save(user);
return "Add User Successfully";
}
//#PreAuthorize("hasAnyRole('ADMIN')")
#GetMapping("/admin/all")
public String securedHello() {
return "Secured Hello";
}
}
This is Role bean
#Entity
#Data
public class Role {
#Id
#GeneratedValue
private int roleId;
private String role;
}
This User Bean
#Entity
#Setter
#Getter
public class User {
#Id
private int userId;
private String username;
private String password;
private String email;
#OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
#JoinTable(name="user_role", joinColumns = #JoinColumn(name="user_id"), inverseJoinColumns = #JoinColumn(name="role_id"))
private Set<Role> roles;
}
UserRepository interface
public interface UserRepository extends JpaRepository<User, Integer> {
User findByUsername(String username);
}
CustomUserDetails class
I think the problem in this part. I have save role like ROLE_USER, ROLE_ADMIN also tried without ROLE_
#Getter
#Setter
public class CustomUserDetails implements UserDetails {
private User user;
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return user.getRoles().stream().map(role -> new SimpleGrantedAuthority(""+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();
}
Service class CustomUserDetailsService
#Service
public class CustomUserDetailsService implements UserDetailsService {
#Autowired
private UserRepository userRepo;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepo.findByUsername(username);
CustomUserDetails userDetails = null;
if(user!=null) {
userDetails = new CustomUserDetails();
userDetails.setUser(user);
}else {
throw new UsernameNotFoundException("User not found with name "+username);
}
return userDetails;
}
}
I have another Controller class having different URL mapping which is running

WebSecurityConfigurerAdapter has a overloaded configure message that takes WebSecurity as argument which accepts ant matchers on requests to be ignored.
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/hello");
}
You can ignore /hello based url as its for all users.

Actual:
return user.getRoles().stream().map(role->new SimpleGrantedAuthority("ROLE_"+role)).collect(Collectors.toList());
Expected:
return user.getRoles().stream().map(role->new SimpleGrantedAuthority("ROLE_"+role.getRole_name())).collect(Collectors.toList());

Related

spring security - 403 forbidden and not call loadUserByUsername()

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

where do I get the "username" value from in spring security to pass to the loadUserByUsername(String username) method of UserDetailsService interface

I am trying to get a user from the database by authenticating the user based on username and password. I am using basic authentication to do this.
I am sending username and password in the authorization header of the rest api
In my controller the getUser() method calls the getuser() method of the UserService class
#GetMapping("/user/self")
public ResponseEntity<UserDto> getUser() {
UserDto UserDto = userService.getUser();
return new ResponseEntity<>(UserDto, HttpStatus.OK);
}
#PutMapping("/user/self")
public ResponseEntity<User> updateUser(#Valid #RequestBody Map<String, String> userMap, Principal principal) {
String username = principal.getName();
String firstname = userMap.get("firstName");
String lastName = userMap.get("lastName");
String password = BCrypt.hashpw(userMap.get("password"), BCrypt.gensalt(10));
User user = userService.getUserByUserName(username);
user.setFirstName(firstname);
user.setLastName(lastName);
user.setPassword(password);
userService.save(user);
return new ResponseEntity<>(user, HttpStatus.NO_CONTENT);
}
UserService class implements UserDetailsService and overrides the loadUserByUsername method that requires a username to be passed as an argument. my question is: how do I pass username to loadUserByUsername() method from my UserService class that I am calling from my controller. where does username value reside?
my understanding is - the Authentication Object contains user credentials that are passed to authentication object when a user types their credentials and send their request, how do I retrieve this username value
#Service
public class UserService implements UserDetailsService {
#Autowired
UserRepository userRepository;
public UserDto save(User user) {
String hashedPassword = BCrypt.hashpw(user.getPassword(), BCrypt.gensalt(10));
user.setPassword(hashedPassword);
userRepository.save(user);
UserDto userDto = new UserDto();
userDto.setId(user.getId());
userDto.setFirstName(user.getFirstName());
userDto.setLastName(user.getLastName());
userDto.setUserName(user.getUserName());
userDto.setAccountUpdatedAt(user.getAccountUpdatedAt());
userDto.setAccountCreatedAt(user.getAccountCreatedAt());
return userDto;
}
#Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
User user = userRepository.findByUserName(userName);
if (user == null) {
throw new UsernameNotFoundException(userName + "was not found");
}
return new UserPrincipal(user);
}
here is my repository code:
#Repository
public interface UserRepository extends CrudRepository<User, Long> {
User findByUserName(String userName);
}
here is my authentication code:
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
DataSource dataSource;
#Autowired
private AuthenticationEntryPoint authenticationEntryPoint;
#Autowired
UserService userService;
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(passwordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable();
http.authorizeRequests().antMatchers("/v1/user").permitAll()
.antMatchers("/v1/user/self").authenticated().and().httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
}
}
if you dealing with JPA then in your case you have to use userDetailsService instead of jdbcauthentication, therefor your security class would look like this :
#EnableWebSecurity
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private UserService userService;
public SecurityConfig(UserService userService){
this.userService = userService;
}
#Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder(10); // Number of rounds
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(this.userService).passwordEncoder(passwordEncoder());
}
}
then you can customize the authentication in the UserService class to satisfy the business need as the below sample :
#Service
public class UserService implements UserDetailsService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository){
this.userRepository = userRepository;
}
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Optional<User> user = userRepository.findByUsername(username);
if(user.isPresent()){
log.info("cretaed under User service : " + user.get());
return user.get();
}
throw new UsernameNotFoundException("empty or invalud user");
}
}
in addition, do not forget to create the findByUsername method in your repository also do not forget to implement org.springframework.security.core.userdetails.UserDetails in your module class:
#Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String name);
}

Spring Security login issue when trying to access a url after authentication

I am learning spring security and has followed few tutorials on Youtube, I have completed the task as taught by the author/teacher but unfortunately i could not login when i try to access my urls for /user and /admin after login, though i receive granted authorities object from database with USER_USER and USER_ADMIN roles but still when i request those urls i throws exception for forbidden access, anyone can guide why this is happening?
#EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
#Autowired
private MyUserDetailsService userDetailsService;
/*Authentication method*/
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//auth.inMemoryAuthentication().withUser("admin").password("admin").roles("Admin").and().withUser("user").password("user").roles("User");
auth.userDetailsService(userDetailsService);
}
// Authorization - Should be from most secure to least one
#Override
protected void configure(HttpSecurity http) throws Exception {
// To allow access to any url without permission is by using permitAll() method
System.out.println("Accessign URL : ");
http.authorizeRequests().
antMatchers("/admin").hasRole("USER_ADMIN").
antMatchers("/user").hasAnyRole("USER_USER", "USER_ADMIN").
antMatchers("/", "static/css", "static/js").
permitAll().
and().
formLogin();
}
#Bean
public PasswordEncoder getPasswordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
}
MyUserDetails Class :
package com.springsecurity.demo.models;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
public class MyUserDetails implements UserDetails {
private static final long serialVersionUID = -3042145577630945747L;
private String userName;
private String password;
private List<GrantedAuthority> authorityList;
public MyUserDetails() {
}
public MyUserDetails(User user) {
this.userName = user.getUserName();
this.password = user.getPassword();
this.authorityList = Arrays.stream(user.getUserRole().trim().split(",")).map(SimpleGrantedAuthority::new).collect(Collectors.toList());
System.out.println((this.authorityList.size() > 0 ? this.authorityList.get(0) : "Empty"));
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorityList;
}
#Override
public String getPassword() {
return password;
}
#Override
public String getUsername() {
return userName;
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return true;
}
}
MyUserDetailsService class :
#Service
public class MyUserDetailsService implements UserDetailsService {
private UserRepository userRepository;
public MyUserDetailsService(UserRepository userRepository) {
this.userRepository = userRepository;
}
#Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
Optional<User> user = userRepository.findByUserName(userName);
user.orElseThrow(() -> new UsernameNotFoundException("User not found with name : " + userName));
return user.map(MyUserDetails::new).get();
}
}
UserRepository Class :
#Repository
public interface UserRepository extends JpaRepository<User, Integer> {
Optional<User> findByUserName(String userName);
}
Controller Class :
#RestController
public class GreetingController {
#RequestMapping(value = "/")
public String greet() {
return "Hello World!";
}
#RequestMapping(value = "/user")
public String greetUser() {
return ("<h1>Hello User!</h2");
}
#RequestMapping(value = "/admin")
public String greetAdmin() {
return ("<h1>Hello Admin!</h2");
}
}
Thanks
I found the answer with just updating my database user_roles column values from USER_USER & USER_ADMIN to ROLE_USER & ROLE_ADMIN it worked for me, I don't know exactly the reason but it was specified that SimpleGrantedAuthority class expects to have role names like Role_Admin & Role_User format and it worked perfectly for me.
Along with database change i updated my WebSecurity configure method to following,
protected void configure(HttpSecurity http) throws Exception {
// To allow access to any url without permission is by using permitAll() method
System.out.println("Accessign URL : ");
http.authorizeRequests().
antMatchers("/admin", "/api/v1/users").hasRole("ADMIN").
antMatchers("/api/v1/students", "/api/v1/courses").hasAnyRole("USER", "ADMIN").
antMatchers("/", "static/css", "static/js").
permitAll().
and().
formLogin();
}

How to get a username from post method in spring security?

I am using spring-boot and spring-security in app. My goal is to get the user name of the currently registered user from post method. Get method is working nicely but the post method isn't working. Why? How can I solve this problem?
Test Controller
#GetMapping("/test")
public String test(Authentication authentication) {
System.out.println(authentication.getName()); // <--------- It's working
return "testfile";
}
#PostMapping("/test")
public String testPost(Authentication authentication) {
System.out.println(authentication.getName()); // <--------- NOLL ERROR!
return "testfile";
}
Error
java.lang.NullPointerException: null
User
#Entity
#Table(name="user")
public class User {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
#Column(name="id")
private long id;
#Column(name="mail")
private String mail;
#Column(name="password")
private String password;
}
UserDAO
#Repository
public class UserDAO {
#Autowired
private EntityManager entityManager;
public List<User> findAll() {
return entityManager.unwrap(Session.class).createQuery("from User", User.class).getResultList();
}
public User findByMail(String mail){
Session currentSession = entityManager.unwrap(Session.class);
Query theQuery = currentSession.createQuery("from User where mail=:mail", User.class);
theQuery.setParameter("mail", mail);
List<User> users = theQuery.getResultList();
if(users.isEmpty()){
return new User();
}
return users.get(0);
}
public void saveOrUpdate(User user) {
Session currentSession = entityManager.unwrap(Session.class);
currentSession.saveOrUpdate(user);
}
}
UserService
public interface UserService extends UserDetailsService{
public List<User> findAll();
public User findByMail(String mail);
public void saveOrUpdate(User user);
}
UserServiceImpl
#Service
public class UserServiceImpl implements UserService{
#Autowired
private UserDAO userDAO;
#Autowired
private UserRoleDAO userRoleDAO;
#Autowired
private BCryptPasswordEncoder passwordEncoder;
#Override
#Transactional
public List<User> findAll() {
return userDAO.findAll();
}
#Override
#Transactional
public User findByMail(String mail){
return userDAO.findByMail(mail);
}
#Override
#Transactional
public void saveOrUpdate(User user) {
user.setPassword(passwordEncoder.encode(user.getPassword()));
userDAO.saveOrUpdate(user);
}
#Override
#Transactional
public UserDetails loadUserByUsername(String mail) throws UsernameNotFoundException {
User user = userDAO.findByMail(mail);
List<UserRole> userRole = userRoleDAO.findByUserId(user.getId());
if (user == null) {
throw new UsernameNotFoundException("Invalid username or password.");
}
return new org.springframework.security.core.userdetails.User(user.getName(), user.getPassword(), mapRolesToAuthorities(userRole));
}
private Collection<? extends GrantedAuthority> mapRolesToAuthorities(Collection<UserRole> roles) {
return roles.stream().map(role -> new SimpleGrantedAuthority(role.getRole())).collect(Collectors.toList());
}
}
SecurityConfig
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private Environment env;
#Autowired
private DataSource dataSource;
#Autowired
private UserService userService;
RedirectAuthenticationSuccessHandler redirectAuthenticationSuccessHandler = new RedirectAuthenticationSuccessHandler();
RedirectAuthenticationFailureHandler redirectAuthenticationFailureHandler = new RedirectAuthenticationFailureHandler();
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery(env.getProperty("my.usersbyusernamequery"))
.authoritiesByUsernameQuery(env.getProperty("my.authoritiesbyusernamequery"));
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests()
.antMatchers("/anypage1/**").hasRole("MANAGER")
.antMatchers("/anypage2/**").hasRole("ADMIN")
.antMatchers("/test").hasRole("ADMIN")
.authenticated()
.antMatchers("/**").permitAll()
.and()
.formLogin().loginPage("/login").failureHandler(redirectAuthenticationFailureHandler)
.loginProcessingUrl("/login-control").successHandler(redirectAuthenticationSuccessHandler).permitAll()
.and()
.logout().logoutUrl("/logout").permitAll().and().exceptionHandling().accessDeniedPage("/access-denied");
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(HttpMethod.POST, "/anypage3").antMatchers(HttpMethod.POST, "/anypage4")
.antMatchers(HttpMethod.POST, "/test");
}
#Bean
public BCryptPasswordEncoder passwordEncoder()
{
return new BCryptPasswordEncoder();
}
#Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
auth.setUserDetailsService(userService);
auth.setPasswordEncoder(passwordEncoder());
return auth;
}
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(HttpMethod.POST, "/anypage3").antMatchers(HttpMethod.POST, "/anypage4")
.antMatchers(HttpMethod.POST, "/test");
}
You ignore /test in post method, so it will not be filtered by spring security filter, try to remove this.
You can get username from SecurityContextHolder
User user =
(User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String name = user.getUsername(); //get current logged in username
In loadUserByUsername method you can manually set the Authentication token on SecurityContextHolder and same you can use in controller
UsernamePasswordWithAttributesAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( loadUserByUsername(username), password, authorities );
SecurityContextHolder.getContext().setAuthentication(authenticationToken);

Spring Security + MongoDB, request get 401 all the time

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.

Resources