切换到SSL时,WebRequest返回404

时间:2016-05-11 14:56:58

标签: xamarin https xamarin.ios httpwebresponse

在Xamarin中使用PCL方法构建应用程序并使用标准HTTP 100%工作我现在更改了远程测试服务器以使用带有自签名证书的SSL。

该应用程序会联系自定义API以登录服务器并查询特定数据。

我已经更改了应用程序以立即查看SSL,并且最初收到有关身份验证无法正常工作的错误或其他内容但关闭了SSL相关错误以进行测试:

ServicePointManager.ServerCertificateValidationCallback += (o, certificate, chain, errors) => true;

在我的AppDelegate文件FinishedLaunching方法中克服了该错误。

我在尝试将登录POST发送到给定的URL时,现在收到404 /协议错误。

我正在使用HttpWebRequest来进行我的RESTful调用,如果我改回原来的http,这个工作正常。

不知道为什么,但有些文章建议使用ModernHttpClient,我做了。我导入了组件(也使用NuGet添加了包)无济于事。

在联系SSL服务器时,我是否遗漏了我应该在与httpwebresponse相关的代码中配置的其他内容,或者该组件是否无法与SSL服务器通话?

我的登录功能如下(删除/混淆了无关代码):

public JsonUser postLogin(string csrfToken, string partnerId, string username, string password){
        string userEndPoint = SingletonAppSettngs.Instance ().apiEndPoint;
        userEndPoint = userEndPoint.Replace ("druid/", "");

        var request = WebRequest.CreateHttp(string.Format(this.apiBaseUrl + userEndPoint + @"user/login.json"));

        // Request header collection set up
        request.ContentType = "application/json";
        request.Headers.Add ("X-CSRF-Token", csrfToken);

        // Add other configs
        request.Method = "POST";

        using (var streamWriter = new StreamWriter(request.GetRequestStream()))
        {
            string json_body_content = "{\"username\":\"" + username + "\",\"password\":\"" + password + "\"}";

            streamWriter.Write(json_body_content);
            streamWriter.Flush();
            streamWriter.Close();
        }

        try{
            HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse();

            using (StreamReader reader = new StreamReader (httpResponse.GetResponseStream ())) {
                var content = reader.ReadToEnd ();
                content = content.Replace ("[],", "null,");
                content = content.Replace ("[]", "null");

                if (content == null) {
                    throw new Exception ("request_post_login - content is NULL");

                } else {
                    JsonSerializerSettings jss = new JsonSerializerSettings();
                    jss.NullValueHandling = NullValueHandling.Ignore;

                    JsonUser deserializedUser = JsonConvert.DeserializeObject<JsonUser>(content, jss);
                    if(content.Contains ("Hire company admin user")){
                        deserializedUser.user.roles.__invalid_name__5 = "Hire company admin user";
                        deserializedUser.user.roles.__invalid_name__2 = "authenticated user";
                    }

                    return deserializedUser;
                }
            }
        }catch(Exception httpEx){
            Console.WriteLine ("httpEx Exception: " + httpEx.Message);
            Console.WriteLine ("httpEx Inner Exception: " + httpEx.InnerException.Message);
            JsonUser JsonUserError = new JsonUser ();
            JsonUserError.ErrorMessage = "Error occured: " + httpEx.Message;
            return JsonUserError;
        }

    }

2 个答案:

答案 0 :(得分:0)

使用ModernHttpClient制作Web请求时,我通常会遵循以下模式。 Paul Betts创建的另一个很棒的图书馆是refit,可以用来简化休息通话。

    using (var client = new HttpClient(new NativeMessageHandler(false, false)))
    {
        client.BaseAddress = new Uri(BaseUrl, UriKind.Absolute);

        var result = await Refit.RestService.For<IRestApi>(client).GetData();

    }

如果使用customSSLVerification,则应将NativeMessageHandler的第二个参数设置为true。

在这里看看IRestApi

    public interface IRestApi
    {
        [Get("/foo/bar")]
        Task<Result> GetMovies();
    }

答案 1 :(得分:0)

为了让它发挥作用我必须做的事情。

  1. 自签名证书必须允许TLS 1.2
  2. 由于API是基于Drupal的,因此必须在服务器上启用HTTPS,并安装一个模块来管理HTTP特定页面。