【问题标题】:Client side Ajax call on CORS server doesn't include credentialsCORS 服务器上的客户端 Ajax 调用不包括凭据
【发布时间】:2019-03-29 22:37:21
【问题描述】:

我在我的网络应用程序中使用 Shiro 来确保 REST API 的安全性。当客户端在同一台服务器上运行时它工作正常,但我无法让它与 CORS 请求一起工作。经过一番研究,该应用程序如下所示:

web.xml

<filter>
    <filter-name>CORS</filter-name>
    <filter-class>com.company.project.cors.CORSFilter</filter-class>
    <!--<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>-->
</filter>
<filter-mapping>
    <filter-name>CORS</filter-name>
    <url-pattern>/v2/*</url-pattern>
</filter-mapping>

我尝试使用 tomcat 的 CorsFilter 实现,但由于无法正常工作,我实现了自己的自定义过滤器:

public class CORSFilter implements Filter {

    public CORSFilter() {}

    public void destroy() {}

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        System.out.println("CORSFilter HTTP Request: " + request.getMethod());

        HttpServletResponse resp = (HttpServletResponse) servletResponse;

        String origin = request.getHeader("Origin");
        resp.setHeader("Access-Control-Allow-Origin", origin);
        resp.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        resp.setHeader("Vary", "Origin");
        resp.setHeader("Access-Control-Allow-Credentials", "true");
        resp.setHeader("Access-Control-Max-Age", "6000");
        resp.setHeader("Access-Control-Expose-Headers","Access-Control-Allow-Origin, Access-Control-Allow-Headers, Access-Control-Allow-Credentials, Access-Control-Allow-Methods");

    if (request.getMethod().equals("OPTIONS")) {
        resp.setStatus(HttpServletResponse.SC_ACCEPTED);
        resp.setHeader("Access-Control-Allow-Methods", "PUT, GET, OPTIONS, POST, DELETE");
        return;
    }

        // pass the request along the filter chain
        chain.doFilter(request, servletResponse);
    }

    public void init(FilterConfig fConfig) throws ServletException {}
}

我修改了一项服务以检查服务器在 CORS 请求中接收到的内容:

    @POST
    @Compress
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response getElementsSearch(SearchRequestObject sro, @Context HttpServletRequest hsr) {
        Subject currentUser = SecurityUtils.getSubject();
        System.out.println("Current User: " + currentUser);
        System.out.println("Session: " + currentUser.getSession(false));
        System.out.println("Current User: " + currentUser.getPrincipal());
        System.out.println("Origin: " + hsr.getHeader("Origin"));
        System.out.println("Headers: ");
        Enumeration<String> e1 = hsr.getHeaderNames();
        while(e1.hasMoreElements()) {
            String param = e1.nextElement();
            System.out.print(param + "; ");
        }
        System.out.println("Cookie: " + hsr.getHeader("cookie"));   

        if(!currentUser.isAuthenticated())  
            return Response.status(Response.Status.UNAUTHORIZED).build();
         .
         .
         .
}

使用 jQuery 的 ajax 调用如下所示:

$.ajax({
    url:  ServerUrl+'search',
    type: 'POST',
    data: JSON.stringify(objSearch),
    headers: {'Content-Type':'application/json'},
    xhrFields: {
        withCredentials: true
    },
    success: function (result) {
        //Format result

    }, //success
    error: ajaxErrorCallback
});

此调用返回unauthorized,因为尽管已将xhrFields.withCredentials 设置为true,但带有JSESSIONID 的cookie 并未包含在请求的标头中,因此服务器将其视为新的未经身份验证的会话。我不知道问题出在服务器端还是客户端。有谁知道我是否错过了什么?

【问题讨论】:

    标签: java ajax tomcat cors shiro


    【解决方案1】:

    登录请求也必须包含withCredentials=true 标志。如果没有,浏览器似乎关闭了 JSESSIONID cookie。现在它工作正常。

    【讨论】:

      猜你喜欢
      • 2011-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-08
      相关资源
      最近更新 更多