401 Produit non autorisé lors de la tentative de connexion alors que l'enregistrement fonctionne parfaitement.
Pendant le débogage, j'ai repéré que la réponse est donnée sur la ligne où la méthode authenticationManager.authenticate()
sur UserController
est appelée. Une autre chose que j'ai remarquée est que, pour une raison quelconque, je n'ai pas eu ce problème en travaillant avec les référentiels JPA plutôt que DAO . J'utilise PostgreSQL
Voici le code de la méthode correspondante si UserController
:
@Override public User getUserByUsername(String username) { return jdbcTemplate.queryForObject("SELECT * FROM user_table WHERE username = ?", new Object[]{username}, User.class); }
JwtFilter.doFilterInternal ():
@Service public class UserService implements IUserService, UserDetailsService { @Override public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException { User userByName = userDao.getUserByUsername(s); return new org.springframework.security.core.userdetails.User(userByName.getUsername(), userByName.getPassword(), userByName.getAuthorities()); } }
SecurityConfig.configure ():
@Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable().cors().disable() .authorizeRequests() .anyRequest().permitAll() .and().addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class) .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and().httpBasic(); }
UserService.loadUserByUsername ():
@Override protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException { String authorizationHeader = httpServletRequest.getHeader("Authorization"); String jwtToken = null; String username = null; if (authorizationHeader != null && authorizationHeader.startsWith("Bearer")) { jwtToken = authorizationHeader.substring(7); username = jwtService.extractUsername(jwtToken); } if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { UserDetails userDetails = userDetailsService.loadUserByUsername(username); if (jwtService.validateToken(jwtToken, userDetails.getUsername())) { UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken( userDetails, null, userDetails.getAuthorities() ); usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest)); SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); } } filterChain.doFilter(httpServletRequest, httpServletResponse); }
Requête DAO:
@RequestMapping(path = "/auth", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) public AuthResponse authenticate(@RequestBody AuthRequest req){ authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(req.getUsername(), req.getPassword())); String token = jwtService.generateToken(req.getUsername()); return new AuthResponse(token); }
3 Réponses :
Il s'agit probablement d'un problème JWT. Dans la ligne: .and().addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
Utilisez le débogage pour voir ce que vous avez dedans comme paramètres.
Si vous regardez la documentation :
An AuthenticationManager must honour the following contract concerning exceptions: A DisabledException must be thrown if an account is disabled and the AuthenticationManager can test for this state. A LockedException must be thrown if an account is locked and the AuthenticationManager can test for account locking. A BadCredentialsException must be thrown if incorrect credentials are presented. Whilst the above exceptions are optional, an AuthenticationManager must always test credentials. Exceptions should be tested for and if applicable thrown in the order expressed above (i.e. if an account is disabled or locked, the authentication request is immediately rejected and the credentials testing process is not performed). This prevents credentials being tested against disabled or locked accounts.
Je suppose que votre authentification lève l'une de ces trois exceptions (ou peut-être une autre exception). Vous devez consulter vos journaux pour déterminer lequel, ou intercepter l'exception et la déboguer.
Le problème était que la requête ne renvoyait pas de valeur attendue. J'ai changé:
@Override public User getUserByUsername(String username) { List<User> userList = jdbcTemplate.query("SELECT * FROM user_table WHERE username = ?", new Object[]{username}, (resultSet,i) -> { System.out.println(1); return new User(resultSet.getInt("id"), resultSet.getString("username"), resultSet.getString("password"), resultSet.getString("role")); }); return userList.get(0); }