'Getting 404 error in spring boot even though method is logging statements
My app uses Angular on the frontend and Spring Boot (w basic authentication & Spring security) on the backend. I'm using a proxy for api requests to my backend as follows:
{
"/api": {
"target": "http://localhost:8080",
"secure": false,
"loglevel": "debug"
}
}
I have a method in Angular to query my backend with user credentials set in the header:
login(credentials: User) {
console.log("test");
const headers = new HttpHeaders(credentials ? {
authorization: 'Basic ' + btoa(credentials.username + ':' + credentials.password)
} : {});
this.http.get('api/users/user', {headers: headers}).subscribe(
response => {
console.log(response);
// @ts-ignore
if (response['name']) {
this.authenticated = true;
// @ts-ignore
this.authenticatedUserName = response['username'];
} else {
console.log("test3");
this.authenticated = false;
}
});
console.log("test4");
}
Where the backend request mapping looks like this:
@RestController
@RequestMapping("api/users/")
public class UserProfileController {
private final static Logger LOGGER =
Logger.getLogger(UserProfileController.class.getName());
@Autowired
private PlayerService playerService;
@RequestMapping("user")
@ResponseBody
public ResponseEntity<Principal> user(Principal user) {
LOGGER.info("User is " + user);
return new ResponseEntity<Principal>(user, HttpStatus.OK);
}
When I enter incorrect user credentials on my Angular login form, Spring Security intercepts and I get a 403 error as expected. However, when I enter the correct credentials, I see the logger message on the backend ("User is ...") alongside a 404 error-- GET http://localhost:4200/api/users/user 404 (Not Found). The backend returns the correct user, but the frontend doesn't ever enter the subscribe method block. The request is clearly hitting my backend, so I'm not sure what's going on, and would appreciate any insight on the matter.
For reference, here are my security configurations:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final static Logger LOGGER = Logger.getLogger(UserDetailsServiceImpl.class.getName());
private UserDetailsServiceImpl userDetailsService;
private final CustomAuthenticationEntryPoint authenticationEntryPoint;
@Autowired
public SecurityConfig(CustomAuthenticationEntryPoint authenticationEntryPoint, UserDetailsServiceImpl userDetailsService) {
this.authenticationEntryPoint = authenticationEntryPoint;
this.userDetailsService = userDetailsService;
}
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public DaoAuthenticationProvider daoAuthenticationProvider(){
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setPasswordEncoder(passwordEncoder());
provider.setUserDetailsService(userDetailsService);
return provider;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/api/**").permitAll()
.anyRequest().authenticated().and().
httpBasic().authenticationEntryPoint(authenticationEntryPoint);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(daoAuthenticationProvider());
}
}
Solution 1:[1]
You have not defined the request mapping correctly. best practice is to have controller level annotation like:
@RequestMapping("/users/*")
public class UsersController {
@RequestMapping("user")
@ResponseBody
public ResponseEntity<Principal> user(Principal user) {
LOGGER.info("User is " + user);
return new ResponseEntity<Principal>(user, HttpStatus.OK);
}
}
Solution 2:[2]
By default, spring doesn't allow any url to access data for security, your angular app runs on localhost4200 and sprint boot on 8080, so to allow angular to connect the sprint boot API, add @CrossOrigin in your controller/Resource class
@CrossOrigin(origins="http://localhost:4200")
@RestController
public class TodoController {
}
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 | Juliyanage Silva |
Solution 2 | sarthak sethi |