BASIC認証、SSL認証も合わせて NTLM認証も対応しようとすると、
かなり長いコードが必要なる。
準備として、NSURLAuthenticationChallenge を一時保存できるようにしておくことで
OSによる呼ばれるメソッドの差を吸収させる。
@property (nonatomic, retain) NSURLAuthenticationChallenge* myChallenge;
@synthesize myChallenge;
そして、各々のメソッド。。。
#pragma -
#pragma mark ---- for iOS ~4.x ----
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
return YES;
}
#pragma mark ---- for iOS ~4.x ----
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
[self authProcess:challenge];
}
#pragma mark ---- iOS 5.x~ ----
-( void ) connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
[self authProcess:challenge];
}
static BOOL isRequire_USER_PASS;
#pragma mark ---- OS共通 -------
-(void)authProcess:(NSURLAuthenticationChallenge *)challenge
{
self.myChallenge = challenge;
isRequire_USER_PASS = NO;
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPBasic]
|| [challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodHTTPDigest]
|| [challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodDefault]) {
// BASIC or DIGEST認証
isRequire_USER_PASS = YES;
[self performSelectorOnMainThread:@selector(challengeBasicOrNTLM) withObject:nil waitUntilDone:YES];
return;
}else if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodNTLM]){
// NTLM認証
isRequire_USER_PASS = YES;
[self performSelectorOnMainThread:@selector(challengeBasicOrNTLM) withObject:nil waitUntilDone:YES];
}else if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]){
// SSL認証
NSURLResponse *checkresponse;
NSError *error = nil;
[NSURLConnection sendSynchronousRequest:self.request
returningResponse:&checkresponse
error:&error ];
if (error==nil) {
// 事前チェックでエラーなし
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]
forAuthenticationChallenge:challenge];
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}else{
[self performSelectorOnMainThread:@selector(conectAlert:)
withObject:[error localizedDescription]
waitUntilDone:YES];
}
}else{
// 対応しない認証の場合、リジェクト
[[challenge sender] rejectProtectionSpaceAndContinueWithChallenge:challenge];
}
}
#pragma mark ----Basic Or NTLM ----
-(void)challengeBasicOrNTLM
{
NSString* strVersion = [[UIDevice currentDevice] systemVersion];
double version = [strVersion doubleValue];
if (version >= 5.0) {
// iOS 5.0 ~
UIAlertView *dialog = [[UIAlertView alloc] initWithTitle:localString(@"item_authentication_required")
message:@""
delegate:self
cancelButtonTitle:localString(@"cancel")
otherButtonTitles:@"OK", nil ];
((UILabel *)[[dialog subviews] objectAtIndex:1]).textAlignment = UITextAlignmentLeft;
[dialog setAlertViewStyle: UIAlertViewStyleLoginAndPasswordInput];
[dialog show];
[dialog autorelease];
}else{
LoginPanel* login = [ LoginPanel shared ];
[ login showWithDelegate: self title: localString( @"item_authentication_required" ) ];
}
}
#pragma mark ---- for iOS ~4.x ----
-(void)loginPanelResponse:(LoginPanelResponse)response userid:(NSString*)user password:(NSString*)pw
{
if( response == LoginPanelResponseOK ) {
NSURLCredential* credential = [NSURLCredential credentialWithUser:user
password:pw
persistence:NSURLCredentialPersistenceForSession ];
[[self.myChallenge sender] useCredential:credential
forAuthenticationChallenge:self.myChallenge ];
}else if( response == LoginPanelResponseCancel ) {
[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:BROWSER_STOP_LOAD
object:self] ];
}
}
-(void)conectAlert:(NSString *)message
{
UIAlertView* alert = [ [[UIAlertView alloc] initWithTitle: nil
message: message
delegate: self
cancelButtonTitle: nil
otherButtonTitles: @"OK", nil] autorelease ];
((UILabel *)[[alert subviews] objectAtIndex:0]).textAlignment = UITextAlignmentLeft;
[alert show];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (isRequire_USER_PASS){
switch (buttonIndex) {
case 0: // キャンセル
[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:BROWSER_STOP_LOAD
object:self] ];
break;
case 1: // GO
; // ←なぜか、空の実行が必要
UITextField *username = [alertView textFieldAtIndex:0];
UITextField *password = [alertView textFieldAtIndex:1];
NSURLCredential* credential = [NSURLCredential credentialWithUser:username.text
password:password.text
persistence:NSURLCredentialPersistenceForSession ];
[[self.myChallenge sender] useCredential:credential forAuthenticationChallenge:self.myChallenge];
[delegate startIndicator];
break;
}
}else{
switch (buttonIndex) {
case 0: // キャンセル
[[self.myChallenge sender] cancelAuthenticationChallenge:self.myChallenge];
if (version >= 5.0) {
[ self.protocolConnection cancel ];
}
break;
case 1: // GO
[self.myChallenge.sender useCredential:[NSURLCredential credentialForTrust:self.myChallenge.protectionSpace.serverTrust]
forAuthenticationChallenge:self.myChallenge ];
[[self.myChallenge sender] continueWithoutCredentialForAuthenticationChallenge:self.myChallenge ];
break;
}
}
}