我开发了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);
}
});
答案 0 :(得分:2)
基于交换的评论:
由于来自前端的调用是跨域请求(CORS),因此ajax
调用未发送会话标识符cookie(JSESSIONID)。
对于跨站点请求,必须将XMLHttpRequest.withCredentials标志设置为true
,以包括cookie和授权标头之类的凭据。
对于JQuery的ajax
函数,可以用xhrFields: { withCredentials: true }
完成。 axios具有类似的withCredentials
标志。