2014-09-19 16 views
11

हमारे ग्राहक कॉर्पोरेट आईओएस उपकरणों पर कुछ कॉर्पोरेट वेब सेवाओं तक पहुंच सीमित करने के लिए कॉर्पोरेट आईओएस उपकरणों पर क्लाइंट प्रमाणपत्र स्थापित करने के लिए एमडीएम (मोबाइल डिवाइस प्रबंधन) समाधान (मोबाइलइरॉन) का उपयोग करना चाहते हैं।आईओएस क्लाइंट सर्टिफिकेट्स और मोबाइल डिवाइस प्रबंधन

MobileIron सेटिंग में क्लाइंट प्रमाणपत्र स्थापित करता है> सामान्य>, जो आईओएस में प्रमाण पत्र के लिए डिफ़ॉल्ट स्थान है प्रोफाइल, और जब एक कंपनी की वेब सेवा एक के लिए यह चुनौती देता सफारी इस प्रमाण पत्र के साथ प्रतिक्रिया कर सकते हैं।

लेकिन मुझे एक कस्टम ऐप के भीतर से होने वाली एक ही चीज़ की आवश्यकता है। जब हमारे ऐप को प्रमाण पत्र के लिए चुनौती दी जाती है, तो मुझे सेटिंग्स> सामान्य> प्रोफाइल से प्रमाणपत्र के साथ जवाब देने में सक्षम होना चाहिए। मेरे पास हमारे ऐप के साथ बंडल किए गए प्रमाणपत्र के साथ प्रतिक्रिया देने के उदाहरण हैं, और एक प्रमाणपत्र के साथ जो हमारा ऐप अपने कुंजीपटल के भीतर स्टोर करता है, लेकिन सेटिंग्स में डिवाइस पर स्थापित प्रमाणपत्र के साथ प्रतिक्रिया का एक उदाहरण है> सामान्य> प्रोफाइल

क्या कोई मुझे NSURLAuthenticationChallengeSender प्रोटोकॉल विधि -performDefaultHandlingForAuthenticationChallenge: के बारे में और बता सकता है? डिफ़ॉल्ट हैंडलिंग का अर्थ है कि आईओएस ऐप की ओर से चुनौती का प्रभावी ढंग से जवाब देता है? क्या इस प्रतिक्रिया में सेटिंग्स> सामान्य> प्रोफाइल में संग्रहीत क्लाइंट प्रमाणपत्र शामिल हो सकता है?

अद्यतन

एमडीएम एप्लिकेशन कीचेन में क्लाइंट प्रमाणपत्र स्थापित कर सकता है, कि अधिक उचित होगा।

उत्तर

7

एप्पल तकनीकी सहायता जवाब में निम्नलिखित तकनीक टिप्पणी करने के लिए मुझसे कहा:

https://developer.apple.com/library/ios/qa/qa1745/_index.html

संक्षेप में, हम क्या करने समर्थित नहीं है चाहता हूँ।

1

मैं अभी मोबाइल पर एक ऑनसाइट से वापस आया जो मोबाइलइरॉन का उपयोग कर रहा था और बस ऐसा करने के लिए देख रहा था। मोबाइलइरॉन डेवलपमेंट सपोर्ट ने हमें कोड के इस स्निपेट के साथ प्रदान किया, जो ऐपकनेक्ट रैपर द्वारा मोबाइलआईरॉन कोर कॉन्फ टेक्नोलॉजी के माध्यम से प्रदान किया गया प्रमाणपत्र आयात करता है।

यह सुंदर नहीं है, लेकिन जैसा कि यह उनके द्वारा प्रदान किया गया था, मुझे इसे संशोधित करने की अनुमति नहीं थी। हालांकि यह काम करता है! अपने AppDelegate.m में

- (NSString *)appConnectConfigChangedTo:(NSDictionary *)newConfig; 

और यह, सही aforemention pragma चिह्न के बाद:: आप अपने AppDelegate.h में इस डालने

#pragma mark UIApplicationDelegate implementation                                 
- (NSString *)appConnectConfigChangedTo:(NSDictionary *)newConfig{ 
        //NSLog(@"New config: %@", newConfig);                                          //unsecure 
        NSLog(@"New config retrieved");                                                 //confirm we got a new config 
        NSString *certStr       = [newConfig valueForKey:@"kUserCert"];                 //Store certificate as String 
        NSString *certPassword  = [newConfig valueForKey:@"kUserCert_MI_CERT_PW"];      //Store certificate password as string 
        NSData *cert = [[NSData alloc] initWithBase64EncodedString:certStr options:0];  //only for iOS7+, decodes base64 encoded certificate 
        CFDataRef pkcs12Data = (__bridge CFDataRef)cert;                                //Extract identity & certificate objects from 
        CFStringRef password = (__bridge CFStringRef)certPassword;                      //the cert data Identity 
        SecIdentityRef myIdentity = nil;                                                //Initialize variable for identity 
        SecCertificateRef myCertificate = nil;                                          //Initialize variable for certificate 
        OSStatus status = extractIdentityAndTrust(pkcs12Data, password, &myIdentity, nil); //Use Apple-provided method for extracting Identity and Trust 
        if (status != errSecSuccess || myIdentity == nil) { NSLog(@"Failed to extract identity and trust: %ld", status);} //Likely due to corruption 
        else { SecIdentityCopyCertificate(myIdentity, &myCertificate); }                //This method is supposed to store the Certificate, but Fiori doesn't see it here 
        const void *certs[] = { myCertificate };                                        //Initialize an array for one certificate 
        CFArrayRef certsArray = CFArrayCreate(NULL, certs, 1, NULL);                    //Make the array the way Apple wants it to be 
        NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificates:(__bridge NSArray*)certsArray persistence:NSURLCredentialPersistencePermanent];                                       //MobileIron's method of Credential storage 
        NSMutableDictionary *secIdentityParams = [[NSMutableDictionary alloc] init];    //Initialize Dictionary to store identity 
        [secIdentityParams setObject:(__bridge id)myIdentity forKey:(__bridge id)kSecValueRef]; //Build the secIdentityParams dictionary in the way the next method expects it to be 
        OSStatus certInstallStatus = SecItemAdd((__bridge CFDictionaryRef) secIdentityParams, NULL); //Add the identity to the keychain for Fiori consumption 
        if (myIdentity) CFRelease(myIdentity);                                          //Free 
        if (certsArray) CFRelease(certsArray);                                          //Up 
        if (myCertificate) CFRelease(myCertificate);                                    //Memory 
        return nil;                                                                     //Success 
}  
// Copied from Apple document on Certificates: 
// http://developer.apple.com/library/mac/documentation/security/conceptual/CertKeyTrustProgGuide/CertKeyTrustProgGuide.pdf 
OSStatus extractIdentityAndTrust(CFDataRef inP12data, CFStringRef password, SecIdentityRef *identity, SecTrustRef *trust){ 
        OSStatus securityError = errSecSuccess; 
        const void *keys[] = { kSecImportExportPassphrase }; 
        const void *values[] = { password }; 
        CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL); 
        CFArrayRef items = nil; 
        securityError = SecPKCS12Import(inP12data, options, &items); 
        if (securityError == errSecSuccess) { 
             CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex(items, 0); 
             if (identity && CFDictionaryGetValueIfPresent(myIdentityAndTrust, kSecImportItemIdentity, (const void **)identity)) { 
                  CFRetain(*identity); 
              } 
             if (trust && CFDictionaryGetValueIfPresent(myIdentityAndTrust, kSecImportItemTrust, (const void **)trust)) { 
                  CFRetain(*trust); 
              } 
         }   
        if (options) {CFRelease(options);} 
        if (items) {CFRelease(items);} 
        return securityError; 
} 

आपके द्वारा अपने ऐप का निर्माण किया है, MobileIron व्यवस्थापक से संपर्क ऐप को 'लपेटें' ताकि वह ऐपकनेक्ट का उपयोग कर सके। एक बार ऐसा करने के बाद और मोबाइल आईरॉन के माध्यम से उपयोगकर्ताओं को परीक्षण करने के लिए लपेटा गया ऐप तैनात किया जाता है, एक कोर कॉन्फ़िगर सेट करें जो प्रावधान किए गए उपयोगकर्ता के लिए उपयोगकर्ता प्रमाणपत्र विशिष्ट लेता है और इसे कोर कॉन्फ़िगर कुंजी "kUserCert" के अंतर्गत प्रावधान डिवाइस पर धक्का देता है।

+0

बहुत रोचक। इसे आज़माने के लिए मोबाइलइरॉन की एक प्रति पर अपना हाथ लेने की कोशिश करनी होगी। –

+0

क्या आपको मोबाइलइरॉन एसडीके के साथ एकीकृत करने की आवश्यकता है? – windfly2006

+0

इस कार्यक्षमता के लिए कोई पारंपरिक लाइब्रेरी या एसडीके नहीं था: मोबाइलइरॉन ने हमें नमूना कोड प्रदान किया, और ऐप को कनेक्ट करने के लिए ऐप को लपेटने के लिए हमें अपने रैपर एप्लिकेशन का उपयोग करना पड़ा। –

1

मोबाइलइरॉन AppConnect 2.1 अद्यतन इस समस्या को हल करता है, कोई विशेष कोड आवश्यक नहीं है। एक्स.50 9 प्रमाणपत्रों को ऐपकनेक्ट कॉन्फ़िगरेशन के साथ धक्का दिया जा सकता है, और ऐपकनेक्ट फ्रेमवर्क किसी भी authentication challenges को एक योग्य प्रमाणपत्र के साथ प्रतिक्रिया दे सकता है।पहली लॉन्च पर कर्ट्स ऑन-द-फ्लाई बनाया जा सकता है, बाद में रद्द किया गया, प्रति उपयोगकर्ता या प्रति डिवाइस अनुकूलित किया जा सकता है, और विभिन्न यूआरएल विभिन्न कर्ट का उपयोग कर सकते हैं।

यदि कोई इस पृष्ठ पर कोड स्निपेट का उपयोग कर रहा है, तो रोकें, इसकी आवश्यकता नहीं है। अपने अनमोडिफाइड ऐप को लपेटने के बाद, या ऐपकनेक्ट फ्रेमवर्क में लिंक करने के बाद, एक प्रमाणपत्र नामांकन कॉन्फ़िगरेशन (यानी एससीईपी, प्रवेश, सिमेंटेक पीकेआई, पीआईवी-डी इत्यादि) को इंगित करते हुए, अपने एपकनेक्ट कॉन्फ़िगरेशन में एक MI_AC_CLIENT_CERT_1 कुंजी जोड़ें। एक यूआरएल (वैकल्पिक वाइल्डकार्ड के साथ) के साथ एक MI_AC_CLIENT_1_RULE कुंजी जोड़ें। कोई चरण 3 नहीं है। आपका ऐप अब प्रमाणीकरण के लिए स्वचालित रूप से कर्ट का उपयोग करेगा।

पूर्ण विवरण के तहत "AppConnect से प्रमाणपत्र प्रमाणीकरण उद्यम सेवाओं किए जाने वाले एप्लिकेशन", MobileIron के AppConnect और AppTunnel गाइड डॉक्स में कर रहे हैं।

+0

से आना होगा, इसलिए प्रोजेक्ट से आगे बढ़ने से मुझे इस सवाल से पूछने के लिए प्रेरित किया गया, मैं इसे आजमा नहीं सकता। ऐसा लगता है जैसे यह ग्राहकों की जरूरतों को संबोधित करता, और यह हमारे ऐप को सरल बना देता। "प्रमाणीकरण चुनौतियों का अवरोध" भाग मुझे थोड़ी परेशान करता है, हालांकि। क्या इसका मतलब यह है कि ऐप के बजाय ऐपकनेक्ट एचटीटीपीएस एंडपॉइंट बन जाता है? तो ऐप कनेक्ट कनेक्ट यातायात प्रॉक्सी? –

+0

ब्रेट, मैं यहां हमारे "गुप्त सॉस" को प्रकट नहीं कर रहा हूं, लेकिन https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/URLLoadingSystem/Articles/AuthenticationChallenges.html और NSURLAuthenticationMethodClientCertificate देखें। –

+0

मैं इसे "हां" के रूप में ले जाऊंगा। –

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