Objective c NSURLSession和具有凭据的身份验证
我试图从需要使用NSURLSession进行身份验证的web服务器获取数据。我尝试过几种不同的方法,但都没有成功。这是我到目前为止所拥有的。它正在进入协议方法didReceiveChallenge,但似乎没有进行身份验证。我收到的数据是空的 我已检查用户名/密码是否正确。我再次检查了URL是否正确,在safari中转到该URL并手动输入凭据,我看到了JSONObjective c NSURLSession和具有凭据的身份验证,objective-c,ios9,nsurlsession,Objective C,Ios9,Nsurlsession,我试图从需要使用NSURLSession进行身份验证的web服务器获取数据。我尝试过几种不同的方法,但都没有成功。这是我到目前为止所拥有的。它正在进入协议方法didReceiveChallenge,但似乎没有进行身份验证。我收到的数据是空的 我已检查用户名/密码是否正确。我再次检查了URL是否正确,在safari中转到该URL并手动输入凭据,我看到了JSON @interface PlaylistData1b() <NSURLSessionDataDelegate, NSURLSessio
@interface PlaylistData1b() <NSURLSessionDataDelegate, NSURLSessionDelegate>
@property (nonatomic,strong) NSURLSession *session;
@property (nonatomic, strong) NSString *requestString;
@end
@implementation PlaylistData1b
- (instancetype)initWithURL:(NSString *)urlString
{
self = [super init];
if(self){
_requestString = urlString;
}
return self;
}
-(void)log
{
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
_session = [NSURLSession sessionWithConfiguration:config
delegate:self
delegateQueue:nil];
[self fetchData];
}
-(void)fetchData
{
NSString *requestString = _requestString;
NSURL *url = [NSURL URLWithString:requestString];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSURLSessionDataTask *dataTask =
[self.session dataTaskWithRequest:req completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(@"JSON: %@", jsonObject);
}];
[dataTask resume];
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler
{
NSURLCredential *cred = [NSURLCredential credentialWithUser:username
password:password
persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
completionHandler(NSURLSessionAuthChallengeUseCredential, cred);
NSLog(@"Finished Challenge");
}
感谢您的帮助。谢谢。我可能会尝试将
didReceiveChallenge
修改为如下内容
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler
{
NSString *authMethod = [[challenge protectionSpace] authenticationMethod];
if ([authMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
} else {
NSURLCredential *cred = [NSURLCredential credentialWithUser:username
password:password
persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
completionHandler(NSURLSessionAuthChallengeUseCredential, cred);
NSLog(@"Finished Challenge");
}
}
可以通过实现所有身份验证方法来改进委托方法。实际上,只需为
nsurAuthenticationMethodClientCertificate
添加一个特殊的处理程序,Digest和Basic都需要用户和密码,即相同的代码。不要这样做。你刚刚禁用了TLS。对于服务器信任,您应该始终执行默认处理,除非您有特定的原因要执行其他操作。。。这正是我所寻找的(它对我很有用,调用了一个需要Active Directory登录的内部web服务)
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler
{
NSString *authMethod = [[challenge protectionSpace] authenticationMethod];
if ([authMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
} else {
NSURLCredential *cred = [NSURLCredential credentialWithUser:username
password:password
persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];
completionHandler(NSURLSessionAuthChallengeUseCredential, cred);
NSLog(@"Finished Challenge");
}
}
- (void)digestAuthForTask:(NSURLSessionTask*)task{
NSURL *url = task.originalRequest.URL;
NSURLCredential *cred =
[NSURLCredential credentialWithUser:@"user-xxx"
password:@"user-password-xxx"
persistence:NSURLCredentialPersistenceForSession];
NSURLProtectionSpace *space =
[[NSURLProtectionSpace alloc] initWithHost:url.host
port:url.port.integerValue
protocol:url.scheme
realm:nil
authenticationMethod:NSURLAuthenticationMethodHTTPDigest];
[NSURLCredentialStorage.sharedCredentialStorage setCredential:cred
forProtectionSpace:space
task:task];
[task resume];
}
- (void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
NSString *authMtd = challenge.protectionSpace.authenticationMethod;
if ([authMtd isEqualToString: NSURLAuthenticationMethodHTTPDigest]) {
if (!challenge.proposedCredential){
[NSURLCredentialStorage.sharedCredentialStorage getDefaultCredentialForProtectionSpace:challenge.protectionSpace
task:task
completionHandler:^(NSURLCredential * _Nullable credential) {
if (credential){
[challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
}
else{
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
}
}];
}
else{
[challenge.sender useCredential:challenge.proposedCredential forAuthenticationChallenge:challenge];
completionHandler(NSURLSessionAuthChallengeUseCredential, challenge.proposedCredential);
}
} else {
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
}
}