I am Working on a spring boot project for an e-commerce website, As a beginner, I try to add spring security in it so the problem is when I try to test my rest login API using postman I have a status code 200 and the body is always the default login page of spring security. I will be thankful for any advice or any solution.
Here is my user class :
public class User implements Serializable {
private static final long serialVersionUID = -2800960695811489984L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String firstName;
private String lastName;
@Column(nullable = false, unique = true)
private String username;
@Column(nullable = false)
private String address;
@Column(nullable = false, unique = true)
private String email;
private String password;
private boolean isEnabled;
@Column(name = "role" , nullable = false)
@Enumerated(EnumType.STRING)
private Role role;
Here is my Role enum :
public enum Role {
USER ,ADMIN
}
MyUserDetails Class :
public class MyUserDetails implements UserDetails {
String ROLE_PREFIX ="ROLE_";
private String email;
private String password;
private boolean active;
private Role role;
public MyUserDetails(User user) {
super();
this.email = user.getEmail();
this.password = user.getPassword();
this.active = user.isEnabled();
this.role = role;
}
public MyUserDetails(String email, String password, boolean enabled, Role role) {
super();
}
public static MyUserDetails create(User user) {
return new MyUserDetails(user.getEmail(), user.getPassword() ,user.isEnabled(), user.getRole());
}
Here is MyUserDetailsService :
@Service
@ToString
public class MyUserDetailsService implements UserDetailsService {
UserRepository userRepository;
@Autowired
public MyUserDetailsService(UserRepository userRepository) {
super();
this.userRepository = userRepository;
}
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
if (email == null || email.isEmpty()) {
throw new UsernameNotFoundException("email is Empty");
}
User user = userRepository.findByEmail(email);
if (user != null) {
return user.toCurrentUserDetails();
}
throw new UsernameNotFoundException( email + "is not found !!!");
}
}
Here is my RestController :
@CrossOrigin(origins = "*")
@RestController
@RequestMapping("/home")
public class HomeController {
private AuthenticationManager authenticationManager;
private MyUserDetailsService userDetailsService;
private UserRepository userRepository;
private Jwt jwtUtil;
@Autowired
public HomeController(AuthenticationManager authenticationManager, MyUserDetailsService userDetailsService
, UserRepository userRepository, Jwt jwtUtil) {
this.authenticationManager = authenticationManager;
this.userDetailsService = userDetailsService;
this.userRepository = userRepository;
this.jwtUtil = jwtUtil;
}
@PostMapping("/signin")
public ResponseEntity<ServerResp> addUser(@RequestBody User user) {
ServerResp response = new ServerResp();
try {
if (Validator.isUserEmpty(user)) {
response.setStatus(ResponseCode.BAD_REQUEST_CODE);
response.setMessage(ResponseCode.BAD_REQUEST_MESSAGE);
} else if (!Validator.isValidEmail(user.getEmail())) {
response.setStatus(ResponseCode.BAD_REQUEST_CODE);
response.setMessage(ResponseCode.INVALID_EMAIL_FAIL_MSG);
} else {
user.setRole(Role.USER);
user.setEnabled(true);
User reg = userRepository.save(user);
response.setStatus(ResponseCode.SUCCESS_CODE);
response.setMessage(ResponseCode.CUST_REG);
}
} catch (Exception e) {
response.setStatus(ResponseCode.FAILURE_CODE);
response.setMessage(e.getMessage());
}
return new ResponseEntity<ServerResp>(response, HttpStatus.ACCEPTED);
}
@PostMapping("/login")
public ResponseEntity<ServerResp> authentification(@RequestBody HashMap<String, String> credential) {
final String email = credential.get(WebConstants.USER_EMAIL);
final String password = credential.get(WebConstants.USER_PASSWORD);
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(email, password));
} catch (BadCredentialsException e) {
throw new UserNotFoundException(email);
}
final UserDetails userDetails = userDetailsService.loadUserByUsername(email);
final String jwt = jwtUtil.generateToken(userDetails);
ServerResp resp = new ServerResp();
resp.setStatus(ResponseCode.SUCCESS_CODE);
resp.setMessage(ResponseCode.SUCCESS_MESSAGE);
resp.setAUTH_TOKEN(jwt);
return new ResponseEntity<ServerResp>(resp, HttpStatus.OK);
}
}
Here is my Security Configuration Class :
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private MyUserDetailsService userDetailsService;
private JwtFilter jwtFilter;
@Autowired
DataSource datasource;
@Autowired
public SecurityConfiguration(MyUserDetailsService userDetailsService, JwtFilter jwtFilter) {
this.userDetailsService = userDetailsService;
this.jwtFilter = jwtFilter;
}
public SecurityConfiguration(boolean disableDefaults, MyUserDetailsService userDetailsService, JwtFilter jwtFilter) {
super(disableDefaults);
this.userDetailsService = userDetailsService;
this.jwtFilter = jwtFilter;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests().antMatchers("/resources/**", "/static/**", "/public/**").permitAll()
.antMatchers("/home/**").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**")
.hasRole("USER")
.anyRequest().authenticated().and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http
.formLogin()
//.loginPage("/home/login")
.usernameParameter("email")
.passwordParameter("password")
.permitAll()
.and()
.logout()
.permitAll();
http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
// TODO Auto-generated method stub
return super.authenticationManagerBean();
}
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
Here is my user in the database ( MySQL):
And finally, this is the result of the test in postman :
Try sending your credentials using Authorization tab in postman, select authorization type to basic Auth
.