2010-09-16 236 views
1

下面是我送的WS握手完成发送GET HTTPS请求但获得403禁止响应,为什么?

"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" 

它应该做的是将浏览器重定向到URL中的给定BackUrl页之后的URL。它在IE8中显示正确的结果,即使证书有问题。在PC版Chrome中,它显示了HTML的一些代码。在Android中,我得到了403 Forbidden错误。

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参数,但它在浏览器:(

我一直在寻找一种方法解决此问题的最后三天了,至今没有运气工作

编辑:这是用于跳过证书验证过程FakeHostVerifier类。是不是正确呢?

public class FakeHostVerifier implements HostnameVerifier { 
    @Override 
    public boolean verify(String hostname, SSLSession session) { 
     return true; 
    } 

} 
+0

原因是什么? (你标记的答案,但它实际上包含几个建议。) – 2016-01-13 22:46:03

+1

@JaroslavZáruba这是我的不好。我不知道该修复是什么。道歉不正确地记录解决方案。 – RobGThai 2016-01-14 12:03:40

回答

5

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

我想尝试的几件事情:

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

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

如果你urlstring变量真的包含“https://ekp.truefriend.com/COVIWeb/gate/...”,这就是问题来自何处。

当你发送一个HTTP GET请求应该是这样的:

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

不:

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

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

如果您使用的是HTTP 1.0,您将不会使用Host标头,但它不应该很重要(除非该主机为多个虚拟主机提供服务,甚至可以通过HTTPS执行)。如果可以,请考虑使用HTTP/1.1,尽管您可能不得不处理关闭连接(也许是内容长度或分块编码)。

+2

非常感谢。这个惊人的细节真的帮助。 – RobGThai 2010-09-17 12:27:11

2

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

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

+0

但我的FakeHostVerifier已覆盖验证方法。为什么它仍拒绝证书? \t public boolean verify(String hostname,SSLSession session){ \t \t return true; \t} – RobGThai 2010-09-16 10:09:26

+0

如果客户端不信任证书(并且不允许用户临时选择信任证书,如此处所示),则SSL/TLS会话将不会建立。因此,根本不会在HTTP之上交换HTTP消息(HTTP连接将不会建立)。特别是,不会返回HTTP状态码(403,200,...)。客户端是否信任服务器的证书不是403 HTTP状态码的原因。 – Bruno 2010-09-16 13:07:37