我开发了一个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标志。

09-05 11:58