Permalink
Browse files

Merge pull request #4 from dlvenable/master

Providing more client control over authentication in CouchCocoa

Add ability for app to allow cert-based authentication by providing
an NSURLProtectionSpace.
  • Loading branch information...
2 parents 12d5e46 + f8301e3 commit 8552e8e3a8c8c2c0d0cfb07f7a074af449e6d0ce @snej snej committed Nov 10, 2011
Showing with 30 additions and 0 deletions.
  1. +1 −0 REST/RESTInternal.h
  2. +15 −0 REST/RESTOperation.m
  3. +4 −0 REST/RESTResource.h
  4. +10 −0 REST/RESTResource.m
View
@@ -44,6 +44,7 @@ static inline BOOL $equal(id a, id b) {return a==b || [a isEqual: b];}
- (void) setURL: (NSURL*)url;
@property (readwrite, retain) RESTCache* owningCache;
- (NSURLCredential*) credentialForOperation: (RESTOperation*)op;
+- (NSURLProtectionSpace*) protectionSpaceForOperation: (RESTOperation*)op;
@end
View
@@ -466,13 +466,28 @@ - (NSCachedURLResponse *)connection:(NSURLConnection *)connection
return nil;
}
+- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
+{
+ NSURLProtectionSpace* acceptableProtectionSpace = [_resource protectionSpaceForOperation:self];
+ if(acceptableProtectionSpace) {
+ return [protectionSpace isEqual:acceptableProtectionSpace];
+ }
+ // Default Cocoa behavior when connection:canAuthenticateAgainstProtectionSpace: is not implemented
+ return protectionSpace.serverTrust == nil && protectionSpace.distinguishedNames == nil;
+}
- (void)connection:(NSURLConnection *)connection
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if (challenge.previousFailureCount == 0) {
NSURLCredential* credential = [_resource credentialForOperation: self];
NSLog(@"REST: Authentication challenge! credential=%@", credential);
+ if(!credential) {
+ NSURLProtectionSpace* acceptableProtectionSpace = [_resource protectionSpaceForOperation:self];
+ if(acceptableProtectionSpace) {
+ credential = [[NSURLCredential alloc] initWithTrust:acceptableProtectionSpace.serverTrust];
+ }
+ }
if (credential) {
[challenge.sender useCredential: credential forAuthenticationChallenge: challenge];
return;
View
@@ -34,6 +34,7 @@
NSURL* _cachedURL;
NSURLCredential* _credential;
+ NSURLProtectionSpace* _protectionSpace;
}
/** Creates an instance with an absolute URL and no parent. */
@@ -57,6 +58,9 @@
/** Sets the login credential (e.g. username/password) to be used for authentication by this resource and its children. */
- (void) setCredential: (NSURLCredential*)credential;
+/** Sets a protection space for operations on this resource. */
+- (void) setProtectionSpace: (NSURLProtectionSpace*)protectionSpace;
+
#pragma mark HTTP METHODS:
/** Starts an asynchronous HTTP GET operation, with no parameters.
View
@@ -58,6 +58,7 @@ - (void) dealloc
[_owningCache resourceBeingDealloced: self];
[_activeOperations release];
[_credential release];
+ [_protectionSpace release];
[_eTag release];
[_lastModified release];
[_url release];
@@ -333,5 +334,14 @@ - (NSURLCredential*) credentialForOperation: (RESTOperation*)op {
return _credential ? _credential : [_parent credentialForOperation: op];
}
+- (void) setProtectionSpace: (NSURLProtectionSpace*)protectionSpace {
+ [_protectionSpace autorelease];
+ _protectionSpace = [protectionSpace retain];
+}
+
+- (NSURLProtectionSpace*) protectionSpaceForOperation: (RESTOperation*)op {
+ return _protectionSpace ? _protectionSpace : [_parent protectionSpaceForOperation: op];
+}
+
@end

0 comments on commit 8552e8e

Please sign in to comment.