Implemented NTLM auth support. Replaced deprecated auth challenge methods from `NSURLConnectionDelegate`. Replaces #711.

- added `username` and `password` properties on `SDWebImageDownloader`
- added `shouldUseCredentialStorage` and `credential` properties on `SDWebImageDownloaderOperation`
- `SDWebImageDownloaderOperation` conforms to `NSURLConnectionDataDelegate` (it used to implement the methods, but didn't stated the protocol in the declaration)
- removed deprecated methods: `- connection:canAuthenticateAgainstProtectionSpace:` and `- connection:didReceiveAuthenticationChallenge:` with `- connectionShouldUseCredentialStorage:` and `- connection:willSendRequestForAuthenticationChallenge:`
- updated demo project to download one image the requires HTTP auth
This commit is contained in:
Bogdan Poplauschi 2014-06-23 21:57:33 +03:00
parent c7330db3a6
commit 50c4d1d2eb
5 changed files with 65 additions and 10 deletions

View File

@ -29,7 +29,14 @@
style:UIBarButtonItemStylePlain
target:self
action:@selector(flushCache)];
// HTTP NTLM auth example
// Add your NTLM image url to the array below and replace the credentials
[SDWebImageManager sharedManager].imageDownloader.username = @"httpwatch";
[SDWebImageManager sharedManager].imageDownloader.password = @"httpwatch01";
_objects = [NSArray arrayWithObjects:
@"http://www.httpwatch.com/httpgallery/authentication/authenticatedimage/default.aspx?0.35786508303135633", // requires HTTP auth, used to demo the NTLM auth
@"http://assets.sbnation.com/assets/2512203/dogflops.gif",
@"http://www.ioncannon.net/wp-content/uploads/2011/06/test2.webp",
@"http://www.ioncannon.net/wp-content/uploads/2011/06/test9.webp",

View File

@ -97,8 +97,23 @@ typedef void(^SDWebImageDownloaderCompletedBlock)(UIImage *image, NSData *data,
*/
@property (assign, nonatomic) SDWebImageDownloaderExecutionOrder executionOrder;
/**
* Singleton method, returns the shared instance
*
* @return global shared instance of downloader class
*/
+ (SDWebImageDownloader *)sharedDownloader;
/**
* Set username
*/
@property (strong, nonatomic) NSString *username;
/**
* Set password
*/
@property (strong, nonatomic) NSString *password;
/**
* Set filter to pick headers for downloading image HTTP request.
*

View File

@ -153,6 +153,10 @@ static NSString *const kCompletedCallbackKey = @"completed";
[sself removeCallbacksForURL:url];
}];
if (wself.username && wself.password) {
operation.credential = [NSURLCredential credentialWithUser:wself.username password:wself.password persistence:NSURLCredentialPersistenceForSession];
}
if (options & SDWebImageDownloaderHighPriority) {
operation.queuePriority = NSOperationQueuePriorityHigh;
} else if (options & SDWebImageDownloaderLowPriority) {

View File

@ -12,7 +12,28 @@
@interface SDWebImageDownloaderOperation : NSOperation <SDWebImageOperation>
/**
* The request used by the operation's connection.
*/
@property (strong, nonatomic, readonly) NSURLRequest *request;
/**
* Whether the URL connection should consult the credential storage for authenticating the connection. `YES` by default.
*
* This is the value that is returned in the `NSURLConnectionDelegate` method `-connectionShouldUseCredentialStorage:`.
*/
@property (nonatomic, assign) BOOL shouldUseCredentialStorage;
/**
* The credential used for authentication challenges in `-connection:didReceiveAuthenticationChallenge:`.
*
* This will be overridden by any shared credentials that exist for the username or password of the request URL, if present.
*/
@property (nonatomic, strong) NSURLCredential *credential;
/**
* The SDWebImageDownloaderOptions for the receiver.
*/
@property (assign, nonatomic, readonly) SDWebImageDownloaderOptions options;
/**

View File

@ -12,7 +12,7 @@
#import <ImageIO/ImageIO.h>
#import "SDWebImageManager.h"
@interface SDWebImageDownloaderOperation () {
@interface SDWebImageDownloaderOperation () <NSURLConnectionDataDelegate> {
BOOL _executing;
BOOL _finished;
}
@ -46,6 +46,7 @@
- (id)initWithRequest:(NSURLRequest *)request options:(SDWebImageDownloaderOptions)options progress:(void (^)(NSInteger, NSInteger))progressBlock completed:(void (^)(UIImage *, NSData *, NSError *, BOOL))completedBlock cancelled:(void (^)())cancelBlock {
if ((self = [super init])) {
_request = request;
_shouldUseCredentialStorage = YES;
_options = options;
_progressBlock = [progressBlock copy];
_completedBlock = [completedBlock copy];
@ -404,18 +405,25 @@
return self.options & SDWebImageDownloaderContinueInBackground;
}
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection __unused *)connection {
return self.shouldUseCredentialStorage;
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
BOOL trustAllCertificates = (self.options & SDWebImageDownloaderAllowInvalidSSLCertificates);
if (trustAllCertificates && [challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
[challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]
forAuthenticationChallenge:challenge];
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
} else {
if ([challenge previousFailureCount] == 0) {
if (self.credential) {
[[challenge sender] useCredential:self.credential forAuthenticationChallenge:challenge];
} else {
[[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
}
} else {
[[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
}
}
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}
@end