2009-12-20 3 views
8

Shibboleth Identity Provider에 iPhone 응용 프로그램을 통합 한 사람이 있습니까? 인터넷 검색은 아무 것도 나오지 않아서 내가 전문가에게 직접 묻습니다.iPhone 응용 프로그램을 Shibboleth와 통합

이전에 해결되지 않은 경우 그렇게 할 수 있습니까?

+0

웹 응용 프로그램 또는 기본 응용 프로그램에 대해 이야기하고 있습니까? –

+0

네이티브 응용 프로그램; 또는 iPhone 웹 페이지가 네이티브 응용 프로그램을 인증 할 수 있습니까? – user353829

답변

15

둘 모두에 대한 대답은 "예"입니다.

  • 다운로드 표어와 프로그램 인증 네이티브 아이폰 앱
  • 쓰기

    • 학습 목표 - C
    • :

      는 그래서 2 주 전에 요청을 받고, 자바 사람이야 디스플레이 Shibboleth 보호 된 데이터 파일

    ... 조금 위압적이었다. 도움이되는 포럼 게시물이 없으면 저의 경험을 공유 할 수있게되었습니다.

    다음은 개요와 그 다음에 유용한 샘플 코드가 나와 있습니다. 이것이 도움이된다면 제 대답을 투표하십시오! 가치가 Shibbolized 자원을 다운로드 할 수있는 아이폰 응용 프로그램에 대한 내 시간 :

    의 몇 주, 다음과 같은 요구 사항이 발생합니다 :

    1. 사용하여 URL이 API의의를 코코아에 대한 HTTP 요청을 제출 문제의 리소스 사용자 자격 증명에
    2. 에 응답은
    3. 도전은 SP 다시 직접 IdP가에 (코코아의 자동 제공) 서버 인증서 신뢰에
    4. 에 응답이 도전에
    5. 에 응답 :
    6. 은에 요청 대리자 클래스를 구현 오류
    7. 가 인증 된 사용자, HTML 양식에 대한 IdP가의 "바인딩 템플릿을"수신 (필요한 경우) 두 개의 매개 변수
    8. 프로그래밍 HTTP POST 두 개의 매개 변수를 다시 SP로 사용자를 다시 지시에
    9. 에 응답 IdP에서 SP로 돌아갑니다.
    10. 쿠키가 자동으로 저장되어 Cocoa로부터 다시 전달됩니다.
    11. 두 번째 URL 요청 대리인을 구현하여 원래 요청 데이터를받습니다.

      을 그리고 다행스럽게도 필자는 빠른 데모에 대한 모든 소스를 포함 할 수 있습니다 :

    여기에 애플과 표어에서 유용한 참조입니다.

    ApplicationDelegate.h 
    ---------- 
    #import <UIKit/UIKit.h> 
    #import "ConsoleViewController.h" 
    
    /* 
    The application delegate will hold references to the application's UIWindow and a ConsoleViewController. 
    The console does all of the interesting Shibboleth activities. 
    */ 
    @interface ApplicationDelegate : NSObject <UIApplicationDelegate> { 
    
    UIWindow *window; 
    ConsoleViewController *consoleViewController; 
    } 
    
    
    @end 
    
    ApplicationDelegate.m 
    ---------- 
    #import "ApplicationDelegate.h" 
    #import "ConsoleViewController.h" 
    
    /* 
    The implementation for the ApplicationDelegate initializes the console view controller and assembles everything. 
    The console does all of the interesting Shibboleth activities. 
    */ 
    @implementation ApplicationDelegate 
    
    
    - (void)applicationDidFinishLaunching:(UIApplication *)application {  
    
    // Initialize the console. 
    consoleViewController = [[ConsoleViewController alloc] init]; 
    
    window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    [window setBackgroundColor:[UIColor lightGrayColor]]; 
    [window addSubview:[consoleViewController view]]; 
    
    [window makeKeyAndVisible]; 
    } 
    
    
    - (void)dealloc { 
        [window release]; 
    [ConsoleViewController release]; 
        [super dealloc]; 
    } 
    
    
    @end 
    
    ConsoleController.h 
    ---------- 
    #import <Foundation/Foundation.h> 
    #import <UIKit/UIKit.h> 
    
    /* 
    The ConsoleViewController's interface declares references to the network data used in negotiating with Shibboleth 
    and a UITextView used to display the final result or errors. 
    */ 
    @interface ConsoleViewController : UIViewController { 
    
    NSMutableData *responseData; 
    NSString *responseString; 
    UITextView *console; 
    } 
    
    @end 
    
    ConsoleController.m 
    ---------- 
    #import "ApplicationDelegate.h" 
    #import "ConsoleViewController.h" 
    
    
    /* 
    This delegate is used when making the second HTTP request with Shibboleth. If you're just getting here, start 
    by reading the comments for ConsoleViewController below. 
    
    All we need to do now is receive the response from the SP and display it. 
    If all goes well, this should be the secured page originally requested. 
    */ 
    @interface AuthenticationRedirectDelegate : NSObject { 
    
    NSMutableData *authResponseData; 
    NSString *authResponseString; 
    UITextView *console; 
    } 
    
    @property (nonatomic retain) UITextView *console; 
    
    @end 
    
    
    /* 
    Refer to the comments for the interface above. 
    */ 
    @implementation AuthenticationRedirectDelegate 
    
    @synthesize console; 
    
    -(id)init { 
    authResponseData = [[NSMutableData alloc] retain]; 
    return self; 
    } 
    
    
    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
    [authResponseData setLength:0]; 
    } 
    
    
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    [authResponseData appendData:data]; 
    } 
    
    
    - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 
    [console setText:[error localizedDescription]]; 
    } 
    
    
    /* 
    Once the data is received from Shibboleth's SP, display it. 
    */ 
    - (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    
    authResponseString = [[NSString alloc] initWithData:authResponseData encoding:NSUTF8StringEncoding]; 
    [console setText:authResponseString]; 
    [connection release]; 
    } 
    
    
    @end 
    
    
    /* 
    The implementation of the ConsoleViewController, and AuthenticationRedirectDelegate above, contain the real logic of 
    this Shibboleth exercise. The ConsoleViewController performs the following: 
    1. Prepare the initial HTTP request to a Shibboleth protected resource. 
    2. Act as the delegate whilst Cocoa's URL Loading API receives the HTTP Response. 
    NOTE: We instruct Cocoa in advance to take care of the SP redirecting to the IdP, accepting the server certificate, 
    and submitting the user credentials 
    3. Once the HTTP Response is finished loading, parse the <form action, RelayState and SAMLResponse from the IdP's 
    response 
    4. Call a utility method to prepare a second HTTP POST Request to the <form action/SP with the IdP's parameters 
    NOTE: We do not need to transfer over any of Shibboleth's cookies, since Cocoa is doing this automatically 
    5. Use a new instance of AuthenticationRedirectDelegate to receive the POST's response, which should be the secured 
    page originally requested. 
    6. Display the final content in the UITextView known as console. 
    */ 
    @implementation ConsoleViewController 
    
    
    /* 
    A handy utility method for extracting a substring marked by two provided token strings. 
    Used in parsing the HTML form returned by the IdP after the first HTTP Request. 
    */ 
    +(id)substringFromString:(NSString *)source BetweenOpenToken:(NSString *)openToken AndCloseToken:(NSString *)closeToken { 
    
    NSUInteger l = [source length]; 
    NSUInteger openTokenLen = [openToken length]; 
    
    NSUInteger openTokenLoc = ([source rangeOfString:openToken]).location; 
    NSUInteger valueLoc = openTokenLoc + openTokenLen; 
    NSRange searchRange = NSMakeRange(valueLoc, l - valueLoc); 
    NSUInteger closeTokenLoc = ([source rangeOfString:closeToken options:NSCaseInsensitiveSearch range:searchRange]).location; 
    searchRange = NSMakeRange(valueLoc, closeTokenLoc - valueLoc); 
    NSString *result = [source substringWithRange:searchRange]; 
    
    return result; 
    } 
    
    
    /* 
    This function takes the three properties returned by the IdP after the first HTTP request and 
    HTTP POSTs them to the SP as specified by the IdP in the "url" parameter. 
    */ 
    -(void)authReturnTo:(NSURL *)url WithRelay:(NSString *)relayState AndSAML:(NSString *)samlResponse { 
    
    // Here we assemble the HTTP POST body as usual. 
    NSString *preBody = [[NSString alloc] initWithString:@"RelayState="]; 
    preBody = [preBody stringByAppendingString:relayState]; 
    preBody = [preBody stringByAppendingString:@"&"]; 
    preBody = [preBody stringByAppendingString:@"SAMLResponse="]; 
    preBody = [preBody stringByAppendingString:samlResponse]; 
    
    /* The SAMLResponse parameter contains characters (+) that the SP expects to be URL encoded. 
        Here we simply manually URL encode those characters. You may wish to harden this with proper 
        URL encoding for production use. 
        */ 
    NSString *httpBody = [preBody stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"]; 
    NSData *httpBodyData = [httpBody dataUsingEncoding:NSUTF8StringEncoding]; 
    
    NSString *httpContentLength = [NSString stringWithFormat:@"%d", [httpBodyData length]]; 
    
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url 
           cachePolicy:NSURLRequestReloadIgnoringCacheData 
           timeoutInterval:12.0]; 
    [request setHTTPMethod:@"POST"]; 
    [request setValue:httpContentLength forHTTPHeaderField:@"Content-Length"]; 
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; 
    
    [request setHTTPBody:httpBodyData]; 
    
    // Submit the HTTP POST using the second delegate class to receive the response 
    AuthenticationRedirectDelegate *delegate = [[AuthenticationRedirectDelegate alloc] init]; 
    delegate.console=console; 
    [[NSURLConnection alloc] initWithRequest:request delegate:delegate]; 
    } 
    
    
    /* 
    When this UIViewController finishes loading, automatically prepare and send a request to the Shibboleth SP Web Server 
    for a secured resource. 
    */ 
    - (void)viewDidLoad { 
    [super viewDidLoad]; 
    
    console = [[UITextView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    [[self view] addSubview:console]; 
    
    responseData = [[NSMutableData data] retain]; 
    
    // TODO: Enter your own URL for a Shibboleth secured resource. 
    NSURL *url = [NSURL URLWithString:@"<URL>"]; 
    
    NSURLRequest *request = [NSURLRequest requestWithURL:url 
         cachePolicy:NSURLRequestUseProtocolCachePolicy 
         timeoutInterval:12.0]; 
    
    [[NSURLConnection alloc] initWithRequest:request delegate:self]; 
    
    /* Control flows to the delegate methods below */ 
    } 
    
    
    /* 
    Refer to Apple's docs on the URL Loading System for details. 
    http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html 
    */ 
    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
        [responseData setLength:0]; 
    } 
    
    
    /* 
    Refer to Apple's docs on the URL Loading System for details. 
    http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html 
    */ 
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    [responseData appendData:data]; 
    } 
    
    /* 
    This implementation in the delegate let's Cocoa trust my SP Web Server's self-signed certificate. 
    TODO: You will want to harden this for production use. 
    
    Refer to Apple's docs on the URL Loading System for details. 
    http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html 
    */ 
    - (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { 
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust] || [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic]; 
    } 
    
    
    /* 
    This implementation for the delegate does two things: 
    1. Respond to challenges for my server's self-signed certificate 
    2. Respond to the IdP's challenge for the username and password. 
    TODO: Enter your own username and password here. 
    Refer to Apple's docs on the URL Loading System for details. 
    http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html 
    */ 
    - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { 
    // TODO: Enter the correct username and password below. 
    /* 
        WARNING: Using an incorrect user name and password will result in your application being re-challenged 
        by the IdP. Cocoa will return to this function in a never-ending loop. This can result in the message 
        "NSPosixErrorDomain Too many open files". You'll need to perform additional coding to handle this. 
        */ 
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) 
        [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge]; 
    else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic]) 
        [challenge.sender useCredential:[NSURLCredential credentialWithUser:@"<USERNAME>" password:@"<PASSWORD>" persistence:NSURLCredentialPersistenceNone] forAuthenticationChallenge:challenge]; 
    else 
        [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge]; 
    } 
    
    
    /* 
    You may wish to add more code here to log errors. 
    
    Refer to Apple's docs on the URL Loading System for details. 
    http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html 
    */ 
    - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 
    [console setText:[error localizedDescription]]; 
    } 
    
    
    /* 
    Once Cocoa has received a (hopefully) authenticated response from the IdP, we parse out the relevant pieces and prepare to 
    HTTP POST them back to the SP as specified by the IdP in the <form action attribute. 
    
    Refer to Apple's docs on the URL Loading System for details. 
    http://developer.apple.com/mac/library/DOCUMENTATION/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html 
    */ 
    - (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    [connection release]; 
    responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; 
    
    if([responseString rangeOfString:@"SAMLResponse"].length < 1) 
    { 
        [console setText:[@"Unexpected response:\n]n" stringByAppendingString:responseString]]; 
        return; 
    } 
    
    NSString *relayState = [ConsoleViewController substringFromString:responseString BetweenOpenToken:@"RelayState\" value=\"" AndCloseToken:@"\"/>"]; 
    NSString *SAMLResponse = [ConsoleViewController substringFromString:responseString BetweenOpenToken:@"SAMLResponse\" value=\"" AndCloseToken:@"\"/>"]; 
    NSString *formAction = [ConsoleViewController substringFromString:responseString BetweenOpenToken:@"<form action=\"" AndCloseToken:@"\""]; 
    NSURL *formActionURL = [[NSURL alloc] initWithString:formAction]; 
    [self authReturnTo:formActionURL WithRelay:relayState AndSAML:SAMLResponse]; 
    } 
    
    
    @end 
    
  • +0

    Nice이지만 양식 기반 인증에서는 작동하지 않습니다. 여기서 html을 구문 분석하거나 상호 작용을 위해 사용자에게 제공해야합니다. 필자의 경우 사용자는 여러 인증 요소를 반복해야하므로이를 극복 할 수 없습니다. 어쨌든 샘플을 C#으로 번역 할 수 있습니다.이 언어는 iPhone 개발을위한 제 언어로 기본 언어로 사용할 수 있습니다. 감사 – Monoman

    0

    EC의 솔루션을 사용하여 성공적으로 구현되었습니다.내가 추가 할 수있는 유일한 다른 점은 한 번에 하나의 요청 만 진행하는 것에주의를 기울여야한다는 것입니다. 우리의 구현에서 동시에 실행되는 여러 비동기 요청간에 인증 프로세스가 혼란 스러울 수 있습니다. 대기열을 조절하기 위해 NSOperation을 사용하면 큰 도움이되었습니다.

    0

    나는 그럭저럭 할 수 있었다. 그러나 나는 과정의 모든 단계를 이해하고 그것을 완벽하게 재현하는 데 어느 정도 시간이 걸렸다. 시간이 있다면 많은 문제에 대한 도움을 얻지 못했기 때문에 상세한 자습서를 쓸 수 있습니다. 문제는 연결하려는 웹 사이트에 따라 다르므로 내 경로와 동일한 경로를 따르지 않을 수도 있습니다 (프로세스는 here과 동일 함).

    내 브라우저 (Chrome)에서 연결 요청을 확인하기 위해 개발자 도구 네트워크 패널에서 '로그 유지'를 선택했습니다.

    몇 가지 힌트 :

    • 1 °) 당신은 "_idp_authn_lc_key ..."쿠키를 얻을 필요가있다. 당신을 위해 그것을 설정 한 요청이 있습니다.

    • 2 °) 로그인 티켓 (LT -...)이 필요합니다. 당신은 당신의 신임장을 요구하는 페이지 본문에서 찾을 수있을 것입니다.

    • 3 °) 서비스 티켓 (ST -...)이 필요합니다. 다시 이전 요청이 반환 한 페이지에서 찾을 수 있습니다.

    • 4 °) SAMLResponse가 필요합니다. 다시 이전 요청이 반환 한 페이지에서 찾을 수 있습니다.

    • 5 °) 마지막으로 서비스 제공 업체에 SAMLResponse를 보내서 로그인 할 수 있습니다. 여기서 인코딩을 처리해야합니다. 나는 '% 2B'와 '% 3D'로 바꿀 필요가있는 몇 가지 '+'또는 '='가있었습니다. "_idp_session"쿠키가 주어지며,이 모든 혼란없이 다시 연결할 수 있습니다.

    누군가가 동일한 시도를하면 기꺼이 도와 드리겠습니다. 그냥 내게 메시지를 보내.

    관련 문제