代码之家  ›  专栏  ›  技术社区  ›  RobGThai

发送GET HTTPS请求但得到403禁止响应,为什么?

  •  1
  • RobGThai  · 技术社区  · 16 年前

    下面是握手完成后我发送给WS的URL

        "https://ekp.truefriend.com/COVIWeb/gate/AutoAuthentication.aspx?UserID=DP0001&BackUrl=http%3a%2f%2fgw.truefriendtest.com%2fCOVIWeb%2fApproval%2fForms%2fForm.aspx%3fmobileyn%3dY%26piid%3d96482621-6cc4-401c-a6f9-5ba6cb7ce26f%26wiid%3d425a9bc9-8607-4898-9158-ed9170da1d89%26fmpf%3dWF_A_DRAFT_PAPER01%26fmrv%3d0%26fiid%3d749526BE-B208-4987-B751-2DD0FC03F0F6%26fmid%3d24f6765d-69d1-429f-b0da-b540a064f0e2%26scid%3ddc4378f1-7edd-4d69-8fe4-5867ed32c8b9"
    

    HTTP/1.1 403 Forbidden ( The server denied the specified Uniform Resource Locator (URL). Contact the server administrator.  )
    

    我用这个方法来传输数据

    try{
                URL url = new URL(urlString);
                HttpsURLConnection.setDefaultHostnameVerifier(new FakeHostVerifier());
    
                TrustManager[] trustAllCerts = new TrustManager[]{
                         new X509TrustManager() {
                             public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                                 Log.d("SSLDemo", "getAcceptedIssuers");
                                 return null;
                             }
                             public void checkClientTrusted(
                                 java.security.cert.X509Certificate[] certs, String authType) {
                                 Log.d("SSLDemo", "Check Client Trusted");
                             }
                             public void checkServerTrusted(
                                 java.security.cert.X509Certificate[] certs, String authType) {
                                 Log.d("SSLDemo", "Check Server Trusted");
                             }
                         }
                     };
    
    
        SSLContext sc = SSLContext.getInstance("TLS"); //"TLS"
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
                int port = 443;
                SSLSocketFactory factory = HttpsURLConnection.getDefaultSSLSocketFactory();
                socket = (SSLSocket)factory.createSocket(url.getHost(), port);
                socket.startHandshake();
    
    
                /**
                 * Connection Method
                 */
                String method = "GET";
    
                String os = method + " "+urlString+" HTTP/1.0\r\n";
                os += "Content-Length: 0";
                os += "\r\n\r\n";
    
                ((SSLWeb)this.caller).updateRequest(urlString, method);
    
                Log.i("TESTWEB", os);
                BufferedWriter wout = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                wout.write(os);
                wout.flush();
                wout.close();
                rd = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    
                //*********     Not using thread
                StringBuffer buff = new StringBuffer();
    
                char[] buffer = new char[1024];
    
                while(rd.read(buffer) > -1) {
    
                    buff.append(buffer);
                    Log.i("TESTWEB", "read buffer :" + String.valueOf(buffer));
    
                }
                Log.i("TESTWEB", "read line :" + buff.toString());
    
                //**********
    
            }catch(Exception e){
                Log.e("TESTWEB", "Connecting error", e);
                e.printStackTrace();
            }
    

    我的代码有问题吗?我以为问题出在URL参数上,但它在浏览器中工作:(

    最近三天我一直在想办法解决这个问题,到目前为止运气不好。

     public class FakeHostVerifier implements HostnameVerifier {
        @Override
         public boolean verify(String hostname, SSLSession session) {
             return true;
         }
    
    }
    
    2 回复  |  直到 16 年前
        1
  •  5
  •   Bruno    16 年前

    正如我在对另一个答案的评论中所说的,这与是否信任服务器的证书无关。如果您得到一个HTTP响应,即使是403,也意味着HTTP连接已经建立,这也意味着底层SSL/TLS连接已经建立。如果您的客户端不信任服务器证书,SSL/TLS连接将在任何HTTP通信发生之前关闭。

    我会尝试一些方法:

    • 拆下 Content-Length 标题。它是一个 GET 请求,所以它没有实体。暗示长度为0的实体可能会混淆服务器。
    • 试着设置一个 User-Agent 头来模拟来自浏览器的请求。
    • 更一般地说,查看浏览器将发送的标题并尝试复制它们。(试试看) Accept 头,这可能是你的问题与铬的原因。)

    编辑:(其他潜在问题,更有可能是原因)

    如果你 urlstring 变量确实包含“ https://ekp.truefriend.com/COVIWeb/gate/... “,这就是问题的根源。

    GET /COVIWeb/gate/... HTTP/1.1
    Host: ekp.truefriend.com
    

    不是:

    GET https://ekp.truefriend.com/COVIWeb/gate/... HTTP/1.1
    

    (这仅适用于通过代理的请求,但不适用于HTTPS请求。)

    如果您使用的是HTTP1.0,则不会使用 Host 头,但这并不重要(除非该主机服务于多个虚拟主机,它可以这样做,甚至通过HTTPS)。如果可以的话,可以考虑使用HTTP/1.1,尽管可能需要关闭连接(可能是内容长度或分块编码)。

        2
  •  2
  •   Traveling Tech Guy    16 年前

    你的问题包含了答案。在尝试访问你在Chrome中指定的URL时,你会得到一个大大的红色警告:“网站的安全证书不可信!”。虽然可以在浏览器中手动重写并忽略警告,但代码将此视为安全问题和死胡同。它甚至建议您联系服务器管理员。

    如果您是服务器的管理员,请将SSL证书更改为有效证书。如果没有,请管理员来做。否则,请尝试访问该站点的HTTP(非SSL)版本。