': "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 |
