【问题标题】:Tomcat7 REST Service with Basic Authentification XMLHttpRequest具有基本身份验证 XMLHttpRequest 的 Tomcat7 REST 服务
【发布时间】:2019-01-11 03:57:58
【问题描述】:

我只是在设置一个小的 TestScenario。我正在使用 Jersey 公开 Tomcat 7 上的 REST 服务。该服务由另一个 Javascript/HTML5 应用程序通过 XMLHttpRequest 调用。 为了测试,我只是在我的 Eclipse 安装中使用 Tomcat 运行 REST 服务。

从 JavaScript 调用 REST 服务可以正常工作,无需任何身份验证设置。

现在我正在尝试将基本身份验证机制添加到我的 REST 服务中。在我的 Web 项目的 web.xml 中,我添加了

 <?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
      <display-name>ImageLinksServices</display-name>
      <servlet>
            <servlet-name>Jersey REST Service</servlet-name>
            <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
            <init-param>
                <param-name>com.sun.jersey.config.property.packages</param-name>
                <param-value>com.xxx.xxx.services</param-value>
            </init-param>
            <init-param>
                <param-name>readonly</param-name>
                <param-value>false</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>Jersey REST Service</servlet-name>
            <url-pattern>/rest/*</url-pattern>
        </servlet-mapping>



        <filter>
            <filter-name>CorsFilter</filter-name>
            <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
            <init-param>
                <param-name>cors.allowed.origins</param-name>
                <param-value>*</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.allowed.headers</param-name>
                <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
            </init-param>
            <init-param>
                <param-name>cors.exposed.headers</param-name>
                <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
            </init-param>
            <init-param>
                <param-name>cors.support.credentials</param-name>
                <param-value>true</param-value>
            </init-param>
            <init-param>
                <param-name>cors.preflight.maxage</param-name>
                <param-value>10</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>CorsFilter</filter-name>
            <url-pattern>/*</url-pattern>

        </filter-mapping>

        <security-constraint>
            <web-resource-collection>
                <web-resource-name>Wildcard means whole app requires authentication</web-resource-name>
                <url-pattern>/*</url-pattern>
                <http-method>GET</http-method>
                <http-method>POST</http-method>
            </web-resource-collection>
            <auth-constraint>
                <role-name>tomcat1</role-name>
            </auth-constraint>

            <user-data-constraint>
                <!-- transport-guarantee can be CONFIDENTIAL, INTEGRAL, or NONE -->
                <transport-guarantee>NONE</transport-guarantee>
            </user-data-constraint>
        </security-constraint>

        <login-config>
            <auth-method>BASIC</auth-method>
        </login-config>
    </web-app>

从浏览器调用 REST URL 可以正常工作。他要求输入用户名和密码,然后显示 REST 服务的响应。

但是当我尝试使用以下 snipplet 从 Javascript 调用它时,我总是收到 403 错误和警告

OPTIONS http://localhost:10080/xxxx/rest/fileupload No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access

我目前正在使用的代码片段:

xhr.open('POST', url, true);
//xhr.open("POST", url, true, "user1", "tomcat1");
xhr.setRequestHeader("Authorization","Basic "+ btoa("user1:tomcat1"));
xhr.withCredentials = "true";
xhr.onreadystatechange = function(){
    if(xhr.readyState == 4){
        if(xhr.status == 200){
            var jsonResponse = JSON.parse(xhr.responseText);

我做错了什么?我很困惑为什么现在添加身份验证后浏览器抱怨没有访问控制标头存在。在向服务添加身份验证之前,该调用也适用于 CORS。

我可以从 HTTP 请求中看到基本身份验证标头似乎设置正确。

    Request URL:http://localhost:10080/xxx/rest/fileupload
Request Method:OPTIONS
Status Code:403 Forbidden
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Access-Control-Request-Headers:authorization, content-type
Access-Control-Request-Method:POST
Authorization:Basic dXNlcjE6dG9tY2F0MQ==
Connection:keep-alive
Host:localhost:10080
Origin:http://localhost:63342
Referer:http://localhost:63342/xxx/html/index.html
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36
Response Headersview source
Content-Length:0
Content-Type:text/plain
Date:Thu, 05 Dec 2013 12:58:46 GMT
Server:Apache-Coyote/1.1

谁能帮我理解我做错了什么。如果 Tmocat 配置错误或我的 Javascript 错误,我感到困惑。

【问题讨论】:

    标签: rest tomcat basic-authentication


    【解决方案1】:

    我不知道您是否设法解决了您的问题,但我遇到了同样的问题并通过org.apache.catalina.filters.CorsFilter 进行了调试以找出请求被禁止的原因。

    根据W3 CORS Spec Section 6.2 Preflight Requests,如果提交的任何标头与允许的标头不匹配,预检必须拒绝请求。

    default configuration for the CorsFilter cors.allowed.headers(和你的一样)不包括随请求提交的 Authorization 标头。

    我更新了cors.allowed.headers 过滤器设置以接受authorization 标头,并且预检请求现在成功。

    <filter>
      <filter-name>CorsFilter</filter-name>
      <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
        <init-param>
            <param-name>cors.allowed.headers</param-name>
            <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization</param-value>
        </init-param>     
    </filter>
    

    【讨论】:

    • 感谢您的回复。有用 !我将 Authorization 标头添加到允许的标头中,现在它可以工作了。太好了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-27
    • 1970-01-01
    • 2010-11-24
    相关资源
    最近更新 更多