Клиентский вызов Ajax на сервере CORS не включает учетные данные - PullRequest
0 голосов
/ 25 октября 2018

Я использую 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();
         .
         .
         .
}

Вызов ajax с использованием jQuery выглядит следующим образом:

$.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, поскольку файл cookie с JSESSIONID не включается в заголовки запроса, несмотря на то, что для xhrFields.withCredentials установлено значение true, поэтому сервер рассматривает его как новый, не прошедший проверку подлинности.сессия.Я не знаю, является ли проблема на стороне сервера или клиента.Кто-нибудь знает, если я что-то пропустил?

1 Ответ

0 голосов
/ 31 октября 2018

Запрос на вход в систему также должен включать флаг withCredentials=true.Если нет, кажется, что файл cookie JSESSIONID отклонен браузером.Теперь работает нормально.

...