开发者

Send GET HTTPS request but get 403 forbidden response, why?

Below is the URL I send to the WS after the handshake is done

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

What it should do is redirecting the browser to BackUrl page given in the url. It display correct result in IE8 despite the开发者_运维技巧 certificate problem. In PC version of Chrome it display some code of the HTML. In Android, I get 403 Forbidden error.

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

I use this method to stream data

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();
        }

Is there something wrong with my code? I thought the problem was with the URL parameter, but it work in browser :(

I've been finding a way around the problem for the last three days now, no luck so far.

EDIT: This is FakeHostVerifier class that used to skip the certificate validation process. Isn't this correct?

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

}


As I was saying in a comment to another answer, this has nothing to do with trusting the server's certificate or not. If you get an HTTP response, even if it's a 403, that means that the HTTP connection was established, which also means that the underlying SSL/TLS connection was established. If your client doesn't trust the server certificate, the SSL/TLS connection will close before any HTTP traffic happens.

I'd try a few things:

  • Remove the Content-Length header. It's a GET request, so it doesn't have an entity. Implying a 0-length entity might confuse the server.
  • Try to set a User-Agent header to simulate the request as coming from a browser.
  • More generally, look at the headers a browser that work would send and try to reproduce them. (Try Accept header as well, that might be the cause of your problem with Chrome.)

EDIT: (other potential problem, more likely to be the cause)

If you urlstring variable really contains "https://ekp.truefriend.com/COVIWeb/gate/...", that's where the problem comes from.

When you send an HTTP GET the request should be like this:

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

Not:

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

(that's only for requests via a proxy, and doesn't apply to the HTTPS requests anyway.)

If you're using HTTP 1.0, you won't use the Host header, but it shouldn't really matter (unless that host serves multiple virtual hosts, which it can do, even over HTTPS). Consider using HTTP/1.1 if you can, although you may have to deal with closing the connection (content-length or chunked encoding perhaps).


Your question contains the answer. Upon trying to access the URL you specified in Chrome, you get a big red warning "The site's security certificate is not trusted!". While you can manually override in a browser and ignore the warning, your code treats this as a security problem and a dead end. It even recommends you contact the server administrator.

If you are the server's admin, change the SSL cert to a valid one. if not, ask the admin to do it. Failing that, try accessing the HTTP (non-SSL) version of the site.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜