': "ERROR" dispatch for GET "/login", parameters={} ]

I have a problem with spring security the register work and add admin and client with an encrypted password but when I try to login with "\login" it shows me error 404 with not found resource

2020-07-07 13:43:19.912 DEBUG 12156 --- [nio-9000-exec-9] o.s.web.servlet.DispatcherServlet        : GET "/login", parameters={}
2020-07-07 13:43:20.490 DEBUG 12156 --- [nio-9000-exec-9] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped to ResourceHttpRequestHandler ["classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/"]
2020-07-07 13:43:21.178 DEBUG 12156 --- [nio-9000-exec-9] o.s.w.s.r.ResourceHttpRequestHandler     : Resource not found
2020-07-07 13:43:21.178 DEBUG 12156 --- [nio-9000-exec-9] o.s.web.servlet.DispatcherServlet        : Completed 404 NOT_FOUND
2020-07-07 13:43:21.227 DEBUG 12156 --- [nio-9000-exec-9] o.s.web.servlet.DispatcherServlet        : "ERROR" dispatch for GET "/error", parameters={}
2020-07-07 13:43:21.253 DEBUG 12156 --- [nio-9000-exec-9] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)
2020-07-07 13:43:21.471 DEBUG 12156 --- [nio-9000-exec-9] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Using 'application/hal+json', given [*/*] and 
supported [application/hal+json]
2020-07-07 13:43:21.477 DEBUG 12156 --- [nio-9000-exec-9] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Writing [{timestamp=Tue Jul 07 13:43:21 CEST 2020, status=404, error=Not Found, message=No message available, (truncated)...]
2020-07-07 13:43:21.679 DEBUG 12156 --- [nio-9000-exec-9] o.s.web.servlet.DispatcherServlet        : Exiting from "ERROR" dispatch, status 404  

securityconfig.java

 @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Autowired
        private UserDetailsServiceImpl userDetailsService;
        @Autowired
        private BCryptPasswordEncoder bCryptPasswordEncoder;


       

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
        }
    

       
        
         

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable();
            http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
           http.authorizeRequests().antMatchers("/login").permitAll();
           
         
            http.authorizeRequests().anyRequest().permitAll();
           // http.authorizeRequests().anyRequest().authenticated();
            http.addFilter(new JWTAuthenticationFilter(authenticationManager()));
            http.addFilterBefore(new JWTAuthorizationFiler(), UsernamePasswordAuthenticationFilter.class);
        }

JWTAuthorizationFiler


public class JWTAuthorizationFiler extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {

        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
        response.addHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers,authorization");
        response.addHeader("Access-Control-Expose-Headers", "Access-Control-Allow-Origin, Access-Control-Allow-Credentials, authorization");
        if(request.getMethod().equals("OPTIONS")){
            response.setStatus(HttpServletResponse.SC_OK);
        }
        else if(request.getRequestURI().equals("/login")) {
            filterChain.doFilter(request, response);
            return;
        }
        else {
            String jwtToken = request.getHeader(SecurityParams.JWT_HEADER_NAME);
            System.out.println("Token="+jwtToken);
            if (jwtToken == null || !jwtToken.startsWith(SecurityParams.HEADER_PREFIX)) {
                filterChain.doFilter(request, response);
                return;
            }
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SecurityParams.SECRET)).build();
            String jwt = jwtToken.substring(SecurityParams.HEADER_PREFIX.length());
            DecodedJWT decodedJWT = verifier.verify(jwt);
            System.out.println("JWT="+jwt);
            String username = decodedJWT.getSubject();
            List<String> roles = decodedJWT.getClaims().get("roles").asList(String.class);
            System.out.println("username="+username);
            System.out.println("roles="+roles);
            Collection<GrantedAuthority> authorities = new ArrayList<>();
            roles.forEach(rn -> {
                authorities.add(new SimpleGrantedAuthority(rn));
            });
            UsernamePasswordAuthenticationToken Admin =
                    new UsernamePasswordAuthenticationToken(username, null,authorities);
            SecurityContextHolder.getContext().setAuthentication(Admin);
            filterChain.doFilter(request, response);
        }

    }

JWTAuthenticationFilter.java

 public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
    private AuthenticationManager authenticationManager;

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
        this.authenticationManager = authenticationManager;
    }


    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        try {
            Admin appUser= new ObjectMapper().readValue(request.getInputStream(),Admin.class);
            return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(appUser.getUsername(),appUser.getPassword()));
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    public Authentication attemptAuthentication1(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        try {
            Admin appUser= new ObjectMapper().readValue(request.getInputStream(),Admin.class);
            return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(appUser.getUsername(),appUser.getPassword()));
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
                                            FilterChain chain, Authentication authResult) throws IOException, ServletException {
        User user=(User)authResult.getPrincipal();
        List<String> roles=new ArrayList<>();
        authResult.getAuthorities().forEach(a->{
            roles.add(a.getAuthority());
        });
        String jwt= JWT.create()
                .withIssuer(request.getRequestURI())
                .withSubject(user.getUsername())
                .withArrayClaim("roles",roles.toArray(new String[roles.size()]))
                .withExpiresAt(new Date(System.currentTimeMillis()+SecurityParams.EXPIRATION))
                .sign(Algorithm.HMAC256(SecurityParams.SECRET));
        response.addHeader(SecurityParams.JWT_HEADER_NAME,jwt);
    }

Accountserviceimp.java

public class AccountServiceImpl  implements AccountService{
    private AppUserRepository appUserRepository;
 private AppRoleRepository appRoleRepository;
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    public AccountServiceImpl(AppUserRepository appUserRepository, AppRoleRepository appRoleRepository, BCryptPasswordEncoder bCryptPasswordEncoder) {
        this.appUserRepository = appUserRepository;
        this.appRoleRepository = appRoleRepository;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }
//othercode
@Override
    public Utilisateur loadUserByUsername(String username) {
        return appUserRepository.findByUsername(username);
    }

    @Override
    public void addRoleToUser(String username, String rolename) {
        Utilisateur appUser=appUserRepository.findByUsername(username);
        AppRole appRole=appRoleRepository.findByRoleName(rolename);
        appUser.getRoles().add(appRole);
    }

admincontroller.java

@GetMapping("/users")
    public Utilisateur getuser(Principal principal){

        return  appUserRepository.findByUsername(principal.getName());
    }


Solution 1:[1]

Since evrything is done in your multiple filters, you just need a "/login" end point to return just OK

   @PostMapping("/login")
    public ResponseEntity<String> authenticate(HttpServletResponse response) {
        String jwt = response.getHeader(SecurityParams.JWT_HEADER_NAME);
        return new ResponseEntity<>(jwt, HttpStatus.OK);
    }

Solution 2:[2]

Check the path of your endpoint "\login" , generally it is "/login", verify the endpoint url you are using to login for example:"http://localhost:8080/your_endpoint_path". since you made a custom version of UsernamePasswordAuthenticationFilter you need to specify the path you are using to login , try to add this to your SecurityConfig.java class

@Override
protected void configure(HttpSecurity http) throws Exception {

    JWTAuthenticationFilter.setFilterProcessesUrl("/your_endpoint_path");

    // the rest of your configuration code

}

` therefore you can authenticate by specifying "/your_endpoint_path" , i hope this would help .

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 gaetan224
Solution 2 Andronicus