I added Username and password field to an existing Customer entity. I have added a Custom JWT filter and authentication provider with a WebSecurityConfig annotated @Order(2). But when I send a post request with the Username and password payload , I get an Unauthorized Error 401 response But no error message in Server Log I have checked the WebConfig file appropriately .What am I not getting right ? I've been on this all day and I seem to be frustrated already.
This is UserDetails class
public class MyCustomerDetails implements UserDetails{
/**
*
*/
private static final long serialVersionUID = -5087929420394311276L;
private Long id;
private String username;
private String password;
public MyCustomerDetails() {
}
public MyCustomerDetails(Long id, String username, String password) {
super();
this.id = id;
this.username = username;
this.password = password;
}
public static MyCustomerDetails build(Customer customer) {
return new MyCustomerDetails(customer.getId(),
customer.getUserName(), customer.getPassword());
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getPassword() {
// TODO Auto-generated method stub
return password;
}
@Override
public String getUsername() {
// TODO Auto-generated method stub
return username;
}
............
This is the Controller class
@CrossOrigin(origins = {"http://localhost:3000"})
@RestController
public class CustomerController {
@Autowired
CustomerAccountService customerRepo;
@Autowired
private CustomerJwtTokenUtil customerJwtTokenUtil;
@Autowired
private AuthenticationManager authenticationManager;
@PostMapping(value="/validateCustomer")
public ResponseEntity <?> createAuthenticationToken( @RequestBody MyCustomerDetails
authenticationRequest) throws Exception
{
authenticate(authenticationRequest.getUsername(),
authenticationRequest.getPassword());
// Long userId = authenticationRequest.getId();
final MyCustomerDetails userDetails =
(MyCustomerDetails) customerRepo.loadUserByUsername(authenticationRequest.getUsername());
final String token =
customerJwtTokenUtil.generateToken(userDetails);
return new ResponseEntity<>(new JwtResponse(token), HttpStatus.OK) ;
}
private void authenticate(String username, String password) throws Exception {
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
} catch (DisabledException e) {
throw new Exception("USER_DISABLED", e);
} catch (BadCredentialsException e) {
throw new Exception("INVALID_CREDENTIALS", e);
}
}
This is the WebSecurityconfig class
@Configuration
@Order(2)
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class CustomerSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private CustomerJwtAuthenticationEntryPoint customerJwtAuthenticationEntryPoint;
@Autowired
private UserDetailsService myCustomerDetailsService;
@Autowired
private CustomerJwtRequestFilter customerJwtRequestFilter;
@Bean
public CustomerAccountService myCustomerAccountService() {
return new CustomerAccountService();
}
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/*
* @Bean public UserDetailsService myCustomerDetailsService() { return
* myCustomerDetailsService(); }
*/
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider(PasswordEncoder passwordEncoder,
UserDetailsService userDetailsService){
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
return daoAuthenticationProvider;
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
protected void configure(AuthenticationManagerBuilder auth ) throws Exception {
auth.userDetailsService(myCustomerDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.authorizeRequests()
.antMatchers("/***").permitAll()
// .antMatchers("/customer/**").hasAuthority("CUSTOMER")
.anyRequest().authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(customerJwtAuthenticationEntryPoint)
.and()
.formLogin().permitAll()
// .loginPage("/login")
.and()
.logout().logoutUrl("/logout").logoutSuccessUrl("/login")
.and()
.sessionManagement()
.maximumSessions(1)
.and()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(customerJwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}
}
The Service class
@Primary
public class CustomerAccountService implements UserDetailsService {
@Autowired
private CustomerAccountRepo custRepo;
@Qualifier("passwordEncoder")
@Autowired
private PasswordEncoder bCryptPasswordEncoder;
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Customer customer = custRepo.findByUserName(username);
if(customer == null) {
throw new UsernameNotFoundException("Customer not found");
}
return MyCustomerDetails.build(customer);
}
This is the Base class
@Configuration
@EnableWebMvc
//@ComponentScan(basePackages = "com.bethsaida.org.security")
@EnableJpaRepositories
@SpringBootApplication(exclude = { SecurityAutoConfiguration.class })
public class BethsaidaApplication {
public static void main(String[] args)
{SpringApplication.run(BethsaidaApplication.class, args);}
public class WebConfig implements WebMvcConfigurer
{
private static final long MAX_AGE_SECS = 3600;
@Override
public void addCorsMappings(CorsRegistry registry)
{ registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("HEAD", "OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE")
.maxAge(MAX_AGE_SECS);}
}
}