我开发了一个REST API。除了安全性(登录,获取登录用户等)之外,其他所有东西都运行良好
当我登录用户并尝试通过/ getWhoAmI端点获取它时,我无法获取它(由于没有身份验证,它返回HttpStatus.NOT_FOUND)。在邮递员中,它的工作很棒!
我执行以下情形:登录用户,然后通过/ getWhoAmI获得它。在邮递员中,它可以工作并返回登录的用户,但是在我的JavaScript应用程序中,它返回HttpStatus.NOT_FOUND。
另外,我尝试调试它,并且在getWhoAmI中,身份验证为null(仅当我在JavaScript中调用它时,在邮递员中它包含经过身份验证的用户)
这是/ getWhoAmI端点
@GetMapping(path = "/getWhoAmI")
public ResponseEntity<UserModel> getWhoAmI(Authentication authentication) {
// if there is no authenticated user
if(authentication == null) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
String loggedUsername = SecurityContextHolder.getContext().getAuthentication().getName();
UserModel loggedUser = userRepo.findByUsername(loggedUsername);
return new ResponseEntity<>(loggedUser, HttpStatus.OK);
}
这是我的SecurityConfig:
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter{
private ApplicationUserDetailsService userDetailsService;
public SecurityConfig(ApplicationUserDetailsService userDetailService) {
this.userDetailsService = userDetailService;
}
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/**").permitAll()
.requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()
.and().logout().logoutSuccessHandler((new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK))) // return HttpStatus.OK after successfull logout
.and().csrf().disable();
http.headers().frameOptions().disable();
}
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
super.configure(auth);
auth.userDetailsService(userDetailsService);
}
}
登录端点:
@PostMapping(path = "/login")
public ResponseEntity<UserModel> login(
@RequestParam(value = "username") String username,
@RequestParam(value = "password") String password) {
UserModel user = userRepo.findUserByUsernameAndPassword(username, password);
if(user != null) {
UserDetails userDetails = userDetailsService.loadUserByUsername(user.getUsername());
if(userDetails != null) {
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
System.out.println(authentication);
}
return new ResponseEntity<>(user, HttpStatus.OK);
}
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
我的前端JavaScript:
$.ajax({
method: "GET",
url: SERVER_URL + "/getWhoAmI",
complete: function(data) {
console.log(data.responseJSON);
}
});
最佳答案
根据交换的意见:
因为来自前端的调用是跨域请求(CORS),所以ajax
调用没有发送会话标识符cookie(JSESSIONID)。
对于跨站点请求,必须将XMLHttpRequest.withCredentials标志设置为true
,以包括凭据(例如cookie和授权标头)。
对于可以用ajax
完成的JQuery的xhrFields: { withCredentials: true }
函数。 axios具有类似的withCredentials
标志。