【问题标题】:Angular 2/4 and Jersey REST CORS issueAngular 2/4 和 Jersey REST CORS 问题
【发布时间】:2017-06-26 21:06:07
【问题描述】:

我一直在尝试在后端使用 angular 和 jersey REST 构建相对简单的应用程序。我已经设法在两者之间进行了一些沟通,但是当我尝试按照这个答案Best practice for REST token-based authentication with JAX-RS and Jersey 来实施安全性时,我得到了一些奇怪的行为。

当我尝试从 Angular 应用程序 (localhost:4200) 发出 POST 请求时,我得到 403 Forbidden(对预检请求的响应未通过访问控制检查),甚至没有执行 ContainerRequestFilter 或 ContainerResponseFilter。

当我使用 POSTMAN 发送完全相同的请求时,一切正常。每个过滤器都会被调用,并且身份验证工作正常。

这是我的课程:

@Provider
public class CorsFilter implements ContainerResponseFilter {

@Override
public void filter(ContainerRequestContext request,
        ContainerResponseContext response) throws IOException {

    System.out.println("cors");
    response.getHeaders().add("Access-Control-Allow-Origin", "*");
    response.getHeaders().add("Access-Control-Allow-Headers",
            "origin, content-type, accept, authorization");
    response.getHeaders().add("Access-Control-Allow-Credentials", "true");
    response.getHeaders().add("Access-Control-Allow-Methods",
            "GET, POST, PUT, DELETE, OPTIONS, HEAD");
    System.out.println(response.getHeaders());
}

休息

@Path("/like")
@POST
@Secured({User.RoleEnum.ADMIN,User.RoleEnum.MODERATOR,User.RoleEnum.SUBSCRIBER})
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response like(Comment toUpdate){
    System.out.println("like");
    Comment updated = null;
    try {
        updated = commentService.like(toUpdate);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        return Response
                .serverError()
                .build();
    }
    if(updated !=null){
        return Response
                .ok(updated)
                .build();
    }
    return Response
            .noContent()
            .build();
}

@Secure 接口,AuthorizationFilter 和 AuthenticationFilter 和我上面贴的链接基本一样。

角度请求

const headersAuth = new Headers({'Content-Type': 'application/json', 'Authorization': 'Bearer ' + this.userService.loggedUserToken});
return this.http.post(this.url + this.likeURL, comment, {headers: headersAuth})
  .map(
    (res: Response) => {
      const body: CommentModel = res.json();
      return body || {};
    }
  )
  .catch(this.handleError);

}

请记住,通过邮递员应用程序发送到资源的完全相同的标题和内容工作正常,但是当我尝试通过 Angular POST 发送它时,我得到 403 禁止,甚至没有触发过滤器。当我从 Angular 中删除 @Secure 和 Authorization 标头时,它也可以工作

【问题讨论】:

  • 我在使用 Angular 2 和 Spring Boot 时遇到了同样的问题。您的浏览器将在发送您的POST 之前发送一个预检OPTIONS 请求。 OPTIONS 请求未通过身份验证,因为令牌未添加到 OPTIONS 预检 rqeust 标头中,这导致身份验证失败和 403。您可以编写一个过滤器以允许所有 OPTIONS 请求通过而无需身份验证,或者过滤以检查 OPTIONS 请求并返回状态 200。这是有关预检选项请求的链接 https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
  • Postman 工作的原因是 Postman 没有发送 CORS 请求,而 Angular 客户端是。
  • 合乎逻辑,但我在 CorsFilter 类中的过滤器怎么没有被执行?它甚至没有到达身份验证点
  • 我解决了我的问题,将我的 url 变量设为私有,并将 http:localhost:.. 放在我的 url 中,它就像魔术一样工作

标签: java angular rest jersey-2.0


【解决方案1】:

经过繁琐的谷歌搜索后,我找到了解决方案。它正在使用 tomcat 的 cors 过滤器。

将此添加到 web.xml

    <filter-name>CorsFilter</filter-name>
    <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>

    <!-- With or without this, it doesn't work -->
    <init-param>
        <param-name>cors.allowed.headers</param-name>
        <param-value>x-rest-version,Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization</param-value>
    </init-param>

    <init-param>
        <param-name>cors.allowed.origins</param-name>
        <param-value>http://localhost:4200</param-value>
    </init-param>

    <init-param>
        <param-name>cors.allowed.methods</param-name>
        <param-value>GET,POST,HEAD,OPTIONS,PUT,DELETE</param-value>
    </init-param>

    <init-param>
        <param-name>cors.exposed.headers</param-name>
        <param-value>Location</param-value>
    </init-param>

</filter>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-20
    • 2021-09-19
    • 1970-01-01
    • 2018-10-30
    • 2018-03-01
    • 2019-02-02
    • 1970-01-01
    • 2020-09-11
    相关资源
    最近更新 更多