Appcelerator Titanium iOS模块崩溃

时间:2016-07-11 16:09:26

标签: ios appcelerator appcelerator-titanium

我们正在为Titanium编写一个可以进行SAML身份验证的本机iOS模块。我将SSO url传递给模块,它向url发起HTTP请求,url发送HTTP 302重定向2次并转到IDP,在那里它应该进行身份验证并返回SAML令牌。

这是我从我的Titanium app javascript代码调用的SAML模块中的函数:

var saml = require('com.xxx.SAML');
    Ti.API.info("module is => " + saml);
    saml.ssoUrl ="https://xxxx";
    saml.startSSO();

模块已正确安装并被调用。以下是函数startSSO:

-(id)startSSO:(id)args {
    self.samlUtility  = [[SAMLUtility alloc] init];
    [self.samlUtility setSsoUrl:self.ssoUrl];
    [self.samlUtility performSAMLAuth];
    NSLog(@"setSsoUrl ");    }

SAML Utility类如下:

@implementation SAMLUtility

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
 completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler{
    NSLog(@"did receive auth challenge");

    if(challenge.protectionSpace.authenticationMethod  == NSURLAuthenticationMethodServerTrust){
        NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
        completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
    }else if(challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodNTLM || challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodNegotiate){

        NSURLCredential *credential = [NSURLCredential credentialWithUser:@"xxxx" password:@"xxxx" persistence:NSURLCredentialPersistenceNone];

        completionHandler(NSURLSessionAuthChallengeUseCredential, credential);

    }else {

        // Cancel request
        NSURLCredential *credential = [[NSURLCredential alloc] init];
        completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, credential);

    }

}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
willPerformHTTPRedirection:(NSHTTPURLResponse *)response
        newRequest:(NSURLRequest *)request
 completionHandler:(void (^)(NSURLRequest * __nullable))completionHandler{
    NSLog(@"in redirection");
    NSURLRequest *newRequest = request;
    completionHandler(newRequest);

}

-(void)httpRequest:(NSMutableURLRequest*)request callback:(void(^)(NSData *data, NSString *str))callback{
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

    //Manage the time out configuration
    configuration.timeoutIntervalForRequest=120;
    configuration.timeoutIntervalForResource=120;

    //Now initiate the reuqest
    self.session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]];

    NSData *data = [[NSData alloc] init];

    if((request) != nil) {
        NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

            if(response){
                NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
                NSLog(@"---- Response Code : %ld",(long)httpResponse.statusCode);
                NSLog(@"---- Header fields Code : %@", httpResponse.allHeaderFields);

                if(error){
                    callback(data, error.localizedDescription);
                } else {

                    callback(data, nil);
                }
            }
            else{
                NSLog(@"---- Response is not NSHTTPURLResponse it is %@ -data: %@ - error: %@",response, data, error);
            }


        }];

        [task resume];
    }

    callback(data, nil);
}

-(void)performSAMLAuth{

    NSString *escapedspEndPoint = [self.ssoUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

    NSLog(@"Calling iDP endpoint added encoded %@",escapedspEndPoint);

    //call SP login end point
    NSURL *urlObject = [NSURL URLWithString:escapedspEndPoint];
    NSMutableURLRequest *spLoginReq = [NSMutableURLRequest requestWithURL:urlObject];

    //Create a session and connect to the specfied url.
    NSLog(@"Going to request  now...");

    //TODO: This will result in 302 and go to IdP location do authentication with kerberos
    //other other options and come back...

    [self httpRequest:spLoginReq callback:^(NSData *data, NSString *error){
        if(error) {
            NSLog(@"Error: %@",error);
            NSLog(@"Task execution completed with failure");
        } else {
            NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(@"Success: %@", s);

            //Parse the IdP response and send back to
            //SP SSO End point
            NSMutableURLRequest *spSsoReq = [self buildSsoRequestFrom:data];

            [self httpRequest:spSsoReq callback:^(NSData *data, NSString *error){
                if(error) {
                    NSLog(@"Error: %@",error);
                    NSLog(@"Task execution completed with failure");
                } else {
                    NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                    NSLog(@"Success: %@", s);

                    NSLog(@"spSsoReq completed");
                    NSLog(@"------------------------");
                }
                NSLog(@"Task execution completed");
                NSMutableURLRequest *spSsoReq1 = [self buildSsoRequestFrom:data];
                if([spSsoReq1.URL.absoluteString isEqualToString:@"https://xxxxx/saml2/sp/acs"]){
                    [[NSNotificationCenter defaultCenter] postNotificationName:@"SSOCompleted" object: nil];
                }

                NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
                if(cookies.count > 0){
                    for(NSHTTPCookie *cookie in cookies){
                        NSLog(@"cookie : %@", cookie.name);
                    }
                }

            }];
        }
    }];

}

-(NSMutableURLRequest*)buildSsoRequestFrom:(NSData*)samlHtmlResponse{
    TFHpple *doc = [[TFHpple alloc] initWithHTMLData:samlHtmlResponse];

            if(doc == nil || (doc.data) == nil) {
                NSLog(@"Bad SAML expected response: %@", doc);
                return nil;
            }

    NSArray *elements = [doc searchWithXPathQuery:@"//form"];

    if (elements != nil && elements.count > 0) {

        for(TFHppleElement *element in elements){

            //This is form
            TFHppleElement *formElement = (TFHppleElement*)element;
            NSString *spSsoUrlString = [formElement objectForKey:@"action"];
            NSLog(@"--- Now sending back to SP SSO End point : %@", spSsoUrlString);

            //Now iterate through all the child elements of type input
            NSURL *spSsoUrl = [NSURL URLWithString:spSsoUrlString];
            NSMutableURLRequest *spSsoRequest = [NSMutableURLRequest requestWithURL:spSsoUrl];

            //set method to HTTP POST
            spSsoRequest.HTTPMethod = @"POST";

            //set content type for url encoded
            //spSsoRequest.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")

            //iterate through all the input parameters
            //and extract key = name & value = value of the input

            NSArray *inputElements = [formElement childrenWithTagName:@"input"];
            NSMutableString *postBody = [[NSMutableString alloc] init];
            for(TFHppleElement *ie in inputElements) {
                TFHppleElement *tfie = (TFHppleElement*)ie;
                NSString *key = [tfie objectForKey:@"name"];
                NSString *value= [tfie objectForKey:@"value"];
                value = [value stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
                value = [value stringByReplacingOccurrencesOfString:@"+" withString:@"%2B" options:NSLiteralSearch range:NSMakeRange(0, value.length)];
                [postBody stringByAppendingFormat:@"%@=%@",key,value];
            }
            NSLog(@"3. POST Body : %@", postBody);
            NSData *postBodyData = [postBody dataUsingEncoding:NSUTF8StringEncoding];
            spSsoRequest.HTTPBody = postBodyData;

            return spSsoRequest;
        }
    }
    return nil;

}

当我运行应用程序时,我看到日志停在下面,应用程序崩溃提到分段错误:

[INFO] :   [object ComXXXSamlModule] loaded
[INFO] :   module is => [object ComXXXSamlModule]
[INFO] :   2016-07-06 18:01:57.837 myxxx[16912:209092] Calling iDP endpoint added encoded https://xxx
[INFO] :   2016-07-06 18:01:57.838 myxxx[16912:209092] Going to request  now...
[INFO] :   2016-07-06 18:01:57.840 myxxx[16912:209092] Success: 
[INFO] :   2016-07-06 18:01:57.882 myxxx[16912:209092] Document length: 0 (902 in Kerberos-POC)
[INFO] :   2016-07-06 18:01:57.882 myxxx[16912:209092] Unable to parse:
[INFO] :   2016-07-06 18:01:57.882 myxxx[16912:209092] Success: 
[INFO] :   2016-07-06 18:01:57.883 myxxx[16912:209092] spSsoReq completed
[INFO] :   2016-07-06 18:01:57.883 myxxx[16912:209092] ------------------------
[INFO] :   2016-07-06 18:01:57.883 myxxx[16912:209092] Task execution completed
[INFO] :   2016-07-06 18:01:57.883 myxxx[16912:209092] Document length: 0  (5728 in Kerberos-POC)
[INFO] :   2016-07-06 18:01:57.883 myxxx[16912:209092] Unable to parse:

但是,如果我将相同的代码放入我的原生iOS应用程序并调用与startSSO相同的代码,则代码将执行超出这些日志(我在日志中看到SAML令牌和更多内容)并完成SAML身份验证。

崩溃日志:

Crashed Thread:        5  KrollContext<kroll$1>

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000018
Exception Note:        EXC_CORPSE_NOTIFY

VM Regions Near 0x18:
--> 
    __TEXT                 0000000104e67000-0000000105198000 [ 3268K] r-x/rwx SM=COW  /Users/USER/Library/Developer/CoreSimulator/Devices/FBA2AFBE-14CE-4439-B28A-1AC45FE45639/data/Containers/Bundle/Application/74AA8443-77DE-42FF-BA3F-CE6216FB08D5/myxxx.app/myxxx

Application Specific Information:
objc_msgSend() selector name: isKindOfClass:
CoreSimulator 209.19 - Device: iPad Air - Runtime: iOS 9.3 (13E230) - DeviceType: iPad Air

...

Thread 5 Crashed:: KrollContext<kroll$1>
0   libobjc.A.dylib                 0x000000010aadb80b objc_msgSend + 11
1   com.xxx.myxxx       0x0000000104e910c7 ConvertIdTiValue + 55 (KrollObject.m:95)
2   com.xxx.myxxx       0x0000000104e92c95 +[KrollObject toValue:value:] + 37 (KrollObject.m:538)
3   com.xxx.myxxx       0x0000000104e8ccfc KrollCallAsFunction + 684 (KrollMethod.m:66)
4   com.apple.JavaScriptCore        0x0000000105a90bba JSC::JSCallbackObject<JSC::JSDestructibleObject>::call(JSC::ExecState*) + 506
5   com.apple.JavaScriptCore        0x0000000105b71340 JSC::LLInt::setUpCall(JSC::ExecState*, JSC::Instruction*, JSC::CodeSpecializationKind, JSC::JSValue, JSC::LLIntCallLinkInfo*) + 528
6   com.apple.JavaScriptCore        0x0000000105b7835d llint_entry + 22900
7   com.apple.JavaScriptCore        0x0000000105b78368 llint_entry + 22911
8   com.apple.JavaScriptCore        0x0000000105b78468 llint_entry + 23167
9   ???                             0x0000061b4034dafa 0 + 6714111089402
10  com.apple.JavaScriptCore        0x0000000105b727d9 vmEntryToJavaScript + 326
11  com.apple.JavaScriptCore        0x0000000105a44959 JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 169
12  com.apple.JavaScriptCore        0x0000000105a2b264 JSC::Interpreter::execute(JSC::ProgramExecutable*, JSC::ExecState*, JSC::JSObject*) + 10404
13  com.apple.JavaScriptCore        0x000000010583b786 JSC::evaluate(JSC::ExecState*, JSC::SourceCode const&, JSC::JSValue, WTF::NakedPtr<JSC::Exception>&) + 470
14  com.apple.JavaScriptCore        0x0000000105a89fb8 JSEvaluateScript + 424
15  com.xxx.myxxx       0x0000000104e819f1 -[KrollBridge evalFileOnThread:context:] + 1281 (KrollBridge.m:460)
16  com.xxx.myxxx       0x0000000104e8625c -[KrollInvocation invoke:] + 124 (KrollContext.m:108)
17  com.xxx.myxxx       0x0000000104e881d2 -[KrollContext invokeOnThread:method:withObject:callback:selector:] + 194 (KrollContext.m:1147)
18  com.xxx.myxxx       0x0000000104e81b63 -[KrollBridge evalFile:callback:selector:] + 115 (KrollBridge.m:480)
19  com.xxx.myxxx       0x0000000104e82952 -[KrollBridge didStartNewContext:] + 2498 (KrollBridge.m:614)
20  com.xxx.myxxx       0x0000000104e88de8 -[KrollContext main] + 2392 (KrollContext.m:1349)
21  com.apple.Foundation            0x0000000106f1e12b __NSThread__start__ + 1198
22  libsystem_pthread.dylib         0x000000010b9fe99d _pthread_body + 131
23  libsystem_pthread.dylib         0x000000010b9fe91a _pthread_start + 168
24  libsystem_pthread.dylib         0x000000010b9fc351 thread_start + 13

任何帮助都会受到赞赏,因为基于此我无法理解崩溃的原因。

0 个答案:

没有答案