2017-10-04 20 views
8

फेंकता है IOS के लिए Xamarin फॉर्म ऐप में प्रमाणीकरण के लिए क्लाइंट प्रमाणपत्र का उपयोग करने का प्रयास कर रहा हूं, लेकिन कुछ भी काम नहीं करता है। अगर मैं अनुरोध शुरू करता हूं तो ऐप 100 सेकंड के डिफ़ॉल्ट टाइमआउट पर प्रतीक्षा करता है (मैंने इसे HttpWebRequest.Timeout के साथ कम करने की कोशिश की, लेकिन इसे सेट करना अनदेखा प्रतीत होता है), उसके बाद, मुझे निम्न अपवाद मिलता है: प्रतिक्रिया स्ट्रीम प्राप्त करने में त्रुटि (ReadDone1): प्राप्त करें विफलताक्लाइंट सर्टिफिकेट्स के साथ एक्समरिन फॉर्म https वेबएक्सप्शन

विंडोज कंसोल एप्लिकेशन के समान कोड ठीक काम करता है। यहाँ कुछ (पठनीयता के लिए सरलीकृत) के टुकड़े पुन: पेश करने:

ग्राहक:

var clientCertificate = new X509Certificate2(data, pwd); 
var result = await ExecuteRequest("https://server/user.aspx", clientCertificate); 

public static async Task<string> ExecuteRequest(Uri uri, X509Certificate2 clientCertificate) 
{ 
    var hwr = (HttpWebRequest)HttpWebRequest.Create(uri); 
    if (clientCertificate != null) 
    { 
     hwr.ClientCertificates.Add(clientCertificate); 
    } 
    hwr.Method = "GET"; 
    try 
    { 
     var resWebResonse = await hwr.GetResponseAsync(); 
     var stream = resWebResonse.GetResponseStream(); 
     var sr = new StreamReader (stream); 
     return sr.ReadToEnd(); 
    } 
    catch (Exception ex) 
    { 
     Debug.WriteLine($"Error executing Webrequest to {uri}: {ex}"); 
    } 
    return null; 
} 

सर्वर: user.aspx

<%@ Page Language="C#" %> 
<%@ Import Namespace="System.Security.Cryptography.X509Certificates" %> 
<%@ Import Namespace="System.Security.Principal" %> 
<script runat="server"> 

     public void Page_Load(object sender, EventArgs e) 
     { 
      try 
      { 
       Regex userRegEx = new Regex("CN=(.*)@", RegexOptions.IgnoreCase | RegexOptions.Compiled); 
       if (Request.ClientCertificate.IsPresent) 
       { 
        var cert = new X509Certificate2(Request.ClientCertificate.Certificate); 
        var identity = new GenericIdentity(cert.Subject, "ClientCertificate"); 
        var principal = new GenericPrincipal(identity, null); 
        var m = userRegEx.Match (principal.Identity.Name); 
        Response.Write (m.Groups[1].Value); 
       } 
       else 
        Response.Write("No Client-Certificate"); 
       Response.End(); 
      } 
      catch (Exception ex) 
      { 
       if (!(ex is System.Threading.ThreadAbortException)) 
        Response.Write(ex.ToString()); 
      } 
     }  
</script> 

यह अपवाद मैं बार आ रही है है:

System.Net.WebException: Error getting response stream (ReadDone1): ReceiveFailure 
---> System.IO.IOException: Unable to read data from the transport connection: Connection reset by peer. 
---> System.Net.Sockets.SocketException: Connection reset by peer 
    at System.Net.Sockets.Socket.Receive (System.Byte[] buffer, System.Int32 offset, System.Int32 size, System.Net.Sockets.SocketFlags socketFlags) [0x00017] 
in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.0.0.0/src/mono/mcs/class/referencesource/System/net/System/Net/Sockets/Socket.cs:1773 
at System.Net.Sockets.NetworkStream.Read (System.Byte[] buffer, System.Int32 offset, System.Int32 size) [0x0009b] 
in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.0.0.0/src/mono/mcs/class/referencesource/System/net/System/Net/Sockets/NetworkStream.cs:513 
--- End of inner exception stack trace 
--- 
    at Mono.Net.Security.MobileAuthenticatedStream.EndReadOrWrite (System.IAsyncResult asyncResult, Mono.Net.Security.AsyncProtocolRequest& nestedRequest) [0x00056] 
in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.0.0.0/src/mono/mcs/class/System/Mono.Net.Security/MobileAuthenticatedStream.cs:335 
at Mono.Net.Security.MobileAuthenticatedStream.EndRead (System.IAsyncResult asyncResult) [0x00000] 
in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.0.0.0/src/mono/mcs/class/System/Mono.Net.Security/MobileAuthenticatedStream.cs:278 
at System.Net.WebConnection.ReadDone (System.IAsyncResult result) [0x00027] 
in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.0.0.0/src/mono/mcs/class/System/System.Net/WebConnection.cs:475 
--- End of inner exception stack trace 
--- 
    at System.Net.HttpWebRequest.EndGetResponse (System.IAsyncResult asyncResult) [0x00059] 
in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.0.0.0/src/mono/mcs/class/System/System.Net/HttpWebRequest.cs:1031 
at System.Threading.Tasks.TaskFactory`1[TResult].FromAsyncCoreLogic (System.IAsyncResult iar, System.Func`2[T,TResult] endFunction, System.Action`1[T] endAction, System.Threading.Tasks.Task`1[TResult] promise, System.Boolean requiresSynchronization) [0x0000f] 
in <6314851f133e4e74a2e96356deaa0c6c>:0 
--- End of stack trace from previous location where exception was thrown 
--- 
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() [0x0000c] 
in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.0.0.0/src/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:151 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x00037] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.0.0.0/src/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:187 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.0.0.0/src/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:156 
at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.0.0.0/src/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/TaskAwaiter.cs:128 
at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult() [0x00000] 
in <6314851f133e4e74a2e96356deaa0c6c>:0 
at EWOIS.iOS.WebHelper+<ExecuteRequest>d__4.MoveNext() [0x0012e] in C:\xxxx\WebHelper.cs:70 
  • विजुअल स्टूडियो 2017 v15.3.5
  • Xamarin 4.7.9.45
  • Xamarin iOS और Xamarin मैक एसडीके 11.0.0.0
  • तैनाती लक्ष्य आईओएस 9.3 (10.3 नहीं करता है काम के साथ-साथ)
  • Windows Server 2008 R2 एंटरप्राइज़ SP1
  • IIS 7

मैं AppDelegate.cs में सर्वर प्रमाणपत्र का एक चेक (जो हमारे डोमेन-सीए द्वारा हस्ताक्षरित किया गया है) कहा, यह SslPolicyErrors.None रिपोर्ट

System.Net.ServicePointManager.ServerCertificateValidationCallback += 
(sender, cert, chain, sslPolicyErrors) => 
{ 
    if (cert != null) 
     System.Diagnostics.Debug.WriteLine($"Servercertificate: {cert.Subject}, SSL-Policy-Errors: {sslPolicyErrors}"); 
    return sslPolicyErrors == SslPolicyErrors.None; // return true does not work either (and is not recommended for security reasons) 
} 

अनुरोध करता है अगर मैं वेब सर्वर पर प्रमाणपत्र आवश्यकता को अक्षम करता हूं, तो कनेक्शन काम कर रहा है।

मैं भी System.Net.HttpClientकोशिश की, लेकिन जब ClientCertificate संपत्ति :(

अब तक पहुँचने यह एक NotImplementedException फेंकता मैं पूरी तरह से अनजान आगे क्या अन्य सभी प्रश्नों के प्रयास करने के लिए ... हूँ मैं कुछ साल के थे और किसी भी काम कर समाधान

उत्तर

2

अपने अपवाद संचालक में की पेशकश नहीं है पाया, ऐसा लगता है आप Response.End() कॉल नहीं कर रहे हैं की तरह:

 catch (Exception ex) 
     { 
      if (!(ex is System.Threading.ThreadAbortException)) 
       Response.Write(ex.ToString()); 
     } 

तो यदि सर्वर पक्ष पर एक अपवाद फेंक दिया जा रहा है, तो यह संभव है कि प्रतिक्रिया क्लाइंट को कभी नहीं भेजी जाए। मैं अपवाद के कुछ सर्वर-साइड लॉगिंग जोड़ने की सलाह दूंगा और देख सकता हूं कि कुछ भी उपयोगी है या नहीं।

यह भी लगता है कि आप क्लाइंट प्रमाण पत्र के कुछ फ़ील्ड को सत्यापित करते हैं, लेकिन जहां तक ​​मैं आपको बता सकता हूं कि क्लाइंट प्रमाणपत्र किसी विश्वसनीय रूट द्वारा हस्ताक्षरित नहीं है। आपको यह सुनिश्चित करना चाहिए कि यह मामला है, या कोई भी स्वयं-हस्ताक्षरित प्रमाण पत्र उत्पन्न कर सकता है जिसमें उपयोगकर्ता नाम का प्रतिरूपण करना है और उसका उपयोग करने के लिए इसका उपयोग करें, जो एक गंभीर सुरक्षा भेद्यता होगी।

+0

प्रतिक्रिया। अंत में प्रतिक्रिया के लिए वास्तव में आवश्यक नहीं है, मैं बस चाहता था कि सर्वर प्रतिक्रिया में कोई HTML नहीं जोड़ता है। सर्वर समस्या नहीं होनी चाहिए, क्योंकि क्लाइंटकोड कंसोल-एप्लिकेशन के रूप में काम करता है, लेकिन Xamarin आईओएस में नहीं। मैं अभी भी सोमवार को इसका परीक्षण करूंगा, मैं घर से अपने काम तक नहीं पहुंच सकता। प्रमाण-जांच गुम है, – Brandtware

+0

सलाह के लिए धन्यवाद मैंने एक और प्रतिक्रिया जोड़ा। कैच-ब्लॉक में, कुछ भी नहीं बदला। मैंने आईआईएस-लॉग की जांच की, ऐसा लगता है कि अनुरोध सर्वर को भी हिट नहीं करता है, क्लाइंट साइड समस्या की तरह दिखता है ... – Brandtware

1

मुझे कई quesitons मिले जो मोनो HTTP स्टैक के साथ समस्या को इंगित करते हैं।यह आपकी समस्या का समाधान करने में मदद कर सकता है: How to validate SSL certificates when using HttpWebRequest, Urgent help needed: "error getting response stream (ReadDone1): ReceiveFailure"। संभावित तरीकों में से एक ModernHttpClient का उपयोग करना है जो प्लेटफ़ॉर्म-मूल HTTP क्लाइंट का उपयोग करता है।

इसके अलावा आपको ServicePointManager.ServerCertificateValidationCallback property में कॉलबैक में कोई गलती है। RemoteCertificateValidationCallback delegate एक बुलियन मान देता है जो निर्धारित करता है कि निर्दिष्ट प्रमाण पत्र प्रमाणीकरण के लिए स्वीकार किया गया है या नहीं। एमएसडीएन उदाहरणों में अधिक जानकारी देखें। How to validate SSL certificates when using HttpWebRequest प्रश्न को पढ़ने का भी प्रयास करें।

+0

मुझे ModernHttpClient के बारे में कई थ्रेड मिले हैं, समस्या यह है कि यह मूल सामग्री को सेट और उपयोग कर रहा है नीचे सामान्य एचटीपी क्लाइंट। जैसा कि सवाल में बताया गया है, HttpClient.ClientCertificate एक NotImplementedException फेंकता है। मैंने पोस्टिंग के लिए कोड-क्लीनअप में कॉलबैक-रिटर्न वैल्यू को गोपनीय रूप से हटा दिया है, यह बिना किसी संकलित नहीं होगा। मैंने दोनों को वापस लौटने की कोशिश की (सुरक्षा कारणों से अनुशंसित नहीं) और sslPolicyErrors == SslPolicyError.None वापस लौटें, उनमें से कोई भी काम नहीं करता है। मैं – Brandtware

+0

के अनुसार प्रश्न संपादित करूँगा इस मामले में सर्वर और क्लाइंट साइड पर अपने प्रमाण पत्र की शुद्धता की जांच करने का प्रयास करें। सुनिश्चित करें कि आपके पास निजी कुंजी सहित पूर्ण प्रमाणपत्र तक पहुंच है। सर्टिफिकेट वेब सर्वर के लिए विश्वसनीय रूट प्रमाणन प्राधिकरण प्रमाणपत्र स्टोर में स्थित होना चाहिए। मुझे लगता है [यह सवाल] (https://stackoverflow.com/questions/35582396/how-to-use-a-client-certificate-to- प्रमाणीकरण- और- प्राधिकरण-in-a-web-api) आपकी मदद कर सकता है । – Didgeridoo

+0

क्लाइंट प्रमाणपत्र। आईस्वालिद और हैसप्रेटकी दोनों सच हैं। रूट सीए डिवाइस पर मौजूद है (सेटिंग्स -> सामान्य -> ​​प्रोफाइल -> (हमारे एमडीएम नाम) -> अधिक जानकारी -> हमारे रूट प्रमाण) और वेबसर्वर पर विश्वसनीय जड़ों में। कंसोल एप्लिकेशन में एक ही प्रमाणपत्र फ़ाइल का उपयोग किया जा सकता है, इसलिए इसे काम करना चाहिए। – Brandtware

1

यदि आप विशेष रूप से प्रमाणपत्र जोड़ने के बिना HTTPS पर सर्वर से कनेक्ट होते हैं तो क्या होता है?

क्या अनुरोध सर्वर से ठीक है? यदि ऐसा है, तो समस्या शायद एन्क्रिप्टेड प्रतिक्रिया के डीकोडिंग में है। क्या ग्राहक और सर्वर पर प्रमाण पत्र समान हैं?

+0

दिलचस्प, अगर मैं https: // servername/प्रमाण पत्र के बिना कॉल करता हूं, तो यह काम करता है, अगर मैं https: //servername/test/test.aspx पर कॉल करता हूं तो यह नहीं करता है (एसएसएल-सेटिंग्स में "क्लाइंट प्रमाणपत्र की आवश्यकता है" को निष्क्रिय करने के बाद भी)। .. मैं थोड़ा और पैटर्न की तलाश करूँगा – Brandtware

संबंधित मुद्दे