Rest API返回401时出现CORS错误

Rest API返回401时出现CORS错误,rest,angular,rest-client,Rest,Angular,Rest Client,我在Spring中使用RESTAPI作为后端,Angular 2作为前端 我调用登录URL。当响应为201时,一切正常,但当我发送401/403时,我有一个错误 XMLHttpRequest cannot load http://localhost:8888/emot/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200'

我在Spring中使用RESTAPI作为后端,Angular 2作为前端

我调用登录URL。当响应为201时,一切正常,但当我发送401/403时,我有一个错误

XMLHttpRequest cannot load http://localhost:8888/emot/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 401.
在所有请求中出现此错误之前,我更改了客户端中的调用方法:

 authenticate(login: string, password: string) {

    let headers = this.createBasicHeaders();
    this.createAuthorizationHeader(headers, login, password);
    const options = new RequestOptions({headers: headers});

    console.log(this.http.post(this.restApi + "/emot/login", '{}', options)
      .map(this.extractData)
      .toPromise()
      .catch(this.handleError));

  }


  createAuthorizationHeader(headers: Headers, login: string, password: string) {
    headers.append('Authorization', 'Basic ' +
      btoa(login + ':' + password));
  }

  createBasicHeaders(): Headers {
    let headers = new Headers();

    headers.append('Content-Type', 'application/json');
    // Website you wish to allow to connect
    headers.append('Access-Control-Allow-Origin', this.restApi);

    // Request methods you wish to allow
    headers.append('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    headers.append('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    headers.append('Access-Control-Allow-Credentials', 'true');

    return headers;
  }

  private extractData(res: Response) {
    const body = res.json();
    console.log("GOOD");
    return body.data || {};
  }

  private handleError(error: Response | any) {
    let errMsg: string;
    if (error instanceof Response) {
      const body = error.json() || '';
      const err = body.error || JSON.stringify(body);
      errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
    }
    else {
      errMsg = error.message ? error.message : error.toString();
    }
    return Observable.throw(errMsg);
  }
我的服务器控制器:

@RestController
@ComponentScan("xxxx")
@RequestMapping("/xxx")
@CrossOrigin(origins = "*")
public class RootRequestDispatcher {

    @Autowired
    OperatorFacade operatorFacade;

    @RequestMapping(value = "login", method = RequestMethod.POST)
    public ResponseEntity<OperatorDTO> logon(Authentication auth) {

        System.out.println(auth);
        OperatorDTO operator = operatorFacade.findOperatorByLogin(auth.getName());

        return new ResponseEntity<OperatorDTO>(operator, HttpStatus.OK);
    }
}

我找到了自己的解决办法

对于这个问题,需要重写
AccessDeniedHandler
bean。不像我在前一篇文章中那样

public class CustomAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest,
                       HttpServletResponse httpServletResponse,
                       AccessDeniedException e) throws IOException, 
    ServletException {
        httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
        httpServletResponse.addHeader(SecurityPathProperties.HEADER_NAME_REALM,
                SecurityPathProperties.HEADER_VALUE_REALM + SecurityPathProperties.REALM);
        ObjectMapper mapper = new ObjectMapper();
        PrintWriter writer = httpServletResponse.getWriter();
        writer.println(mapper.writeValueAsString(new ExceptionBean(ExceptionCauses.NOT_FOUND_USER)));
    }
}
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest,
                       HttpServletResponse httpServletResponse,
                       AccessDeniedException e) throws IOException, 
    ServletException {
        httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
        httpServletResponse.addHeader(SecurityPathProperties.HEADER_NAME_REALM,
                SecurityPathProperties.HEADER_VALUE_REALM + SecurityPathProperties.REALM);
        ObjectMapper mapper = new ObjectMapper();
        PrintWriter writer = httpServletResponse.getWriter();
        writer.println(mapper.writeValueAsString(new ExceptionBean(ExceptionCauses.NOT_FOUND_USER)));
    }
}