From 32ac2990193f4bdda7fe3682ec04fe3261a32aa5 Mon Sep 17 00:00:00 2001 From: Brandon Werner Date: Tue, 19 Apr 2016 15:04:09 -0700 Subject: [PATCH 01/14] Update for US Government Authority Instance --- ADAL/src/ADInstanceDiscovery.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ADAL/src/ADInstanceDiscovery.m b/ADAL/src/ADInstanceDiscovery.m index 3c028a408..79e97d977 100644 --- a/ADAL/src/ADInstanceDiscovery.m +++ b/ADAL/src/ADInstanceDiscovery.m @@ -53,9 +53,9 @@ - (id)init //List of prevalidated authorities (Azure Active Directory cloud instances). //Only the sThrustedAuthority is used for validation of new authorities. [_validatedAuthorities addObject:sTrustedAuthority]; - [_validatedAuthorities addObject:@"https://login.chinacloudapi.cn"]; - [_validatedAuthorities addObject:@"https://login.cloudgovapi.us"]; - [_validatedAuthorities addObject:@"https://login.microsoftonline.com"]; + [_validatedAuthorities addObject:@"https://login.chinacloudapi.cn"]; // Microsoft Azure China + [_validatedAuthorities addObject:@"https://login.microsoftonline.com"]; // Microsoft Azure Worldwide + [_validatedAuthorities addObject:@"https://login-us.microsoftonline.com"]; // Microsoft Azure US Government return self; } From bcafc7476e6b428961684f3a6f2d56497aa26448 Mon Sep 17 00:00:00 2001 From: Brandon Werner Date: Tue, 19 Apr 2016 15:38:02 -0700 Subject: [PATCH 02/14] Update authority for Ireland. --- ADAL/src/ADInstanceDiscovery.m | 1 + 1 file changed, 1 insertion(+) diff --git a/ADAL/src/ADInstanceDiscovery.m b/ADAL/src/ADInstanceDiscovery.m index 79e97d977..e0efbb518 100644 --- a/ADAL/src/ADInstanceDiscovery.m +++ b/ADAL/src/ADInstanceDiscovery.m @@ -54,6 +54,7 @@ - (id)init //Only the sThrustedAuthority is used for validation of new authorities. [_validatedAuthorities addObject:sTrustedAuthority]; [_validatedAuthorities addObject:@"https://login.chinacloudapi.cn"]; // Microsoft Azure China + [_validatedAuthorities addObject:@"https://login.microsoftonline.de"]; // Microsoft Azure Ireland [_validatedAuthorities addObject:@"https://login.microsoftonline.com"]; // Microsoft Azure Worldwide [_validatedAuthorities addObject:@"https://login-us.microsoftonline.com"]; // Microsoft Azure US Government From d032f99fd084a4858eba1c4a2efdbd5c04217155 Mon Sep 17 00:00:00 2001 From: Brandon Werner Date: Tue, 19 Apr 2016 15:48:25 -0700 Subject: [PATCH 03/14] Update authority for Germany --- ADAL/src/ADInstanceDiscovery.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ADAL/src/ADInstanceDiscovery.m b/ADAL/src/ADInstanceDiscovery.m index e0efbb518..8417b600d 100644 --- a/ADAL/src/ADInstanceDiscovery.m +++ b/ADAL/src/ADInstanceDiscovery.m @@ -54,7 +54,7 @@ - (id)init //Only the sThrustedAuthority is used for validation of new authorities. [_validatedAuthorities addObject:sTrustedAuthority]; [_validatedAuthorities addObject:@"https://login.chinacloudapi.cn"]; // Microsoft Azure China - [_validatedAuthorities addObject:@"https://login.microsoftonline.de"]; // Microsoft Azure Ireland + [_validatedAuthorities addObject:@"https://login.microsoftonline.de"]; // Microsoft Azure Germany [_validatedAuthorities addObject:@"https://login.microsoftonline.com"]; // Microsoft Azure Worldwide [_validatedAuthorities addObject:@"https://login-us.microsoftonline.com"]; // Microsoft Azure US Government From 92a262fd38276090166c25ebe372aeb61385ce4f Mon Sep 17 00:00:00 2001 From: Claus Joergensen Date: Mon, 18 Apr 2016 13:14:23 -0700 Subject: [PATCH 04/14] Fixed a bug where a Error { WebKitErrorDomain, 102 } wasn't correctly ignored as it should be when implement a OAuth 2.0 flow. --- ADAL/src/ui/ADWebAuthController.m | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ADAL/src/ui/ADWebAuthController.m b/ADAL/src/ui/ADWebAuthController.m index 5f0178b2e..71ae18476 100755 --- a/ADAL/src/ui/ADWebAuthController.m +++ b/ADAL/src/ui/ADWebAuthController.m @@ -401,9 +401,16 @@ - (void)webAuthDidCompleteWithURL:(NSURL *)endURL // Authentication failed somewhere - (void)webAuthDidFailWithError:(NSError *)error { - AD_LOG_ERROR_F(@"-webAuthDidFailWithError:", error.code, _correlationId, @"error: %@", error); + // Ignore WebKitError 102 for OAuth 2.0 flow. + if ([error.domain isEqualToString:@"WebKitErrorDomain"] && error.code == 102) + { + return; + } + if (error) { + AD_LOG_ERROR_F(@"-webAuthDidFailWithError:", error.code, _correlationId, @"error: %@", error); + [[NSNotificationCenter defaultCenter] postNotificationName:ADWebAuthDidFailNotification object:self userInfo:@{ @"error" : error}]; From 764ec02c93f0994ff23a148627e498a6c912988b Mon Sep 17 00:00:00 2001 From: Claus Joergensen Date: Mon, 18 Apr 2016 13:15:30 -0700 Subject: [PATCH 05/14] Removed two DebugLog() statements that weren't respecting the NSLoggingEnabled setting. --- ADAL/src/ui/ADWebAuthController.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ADAL/src/ui/ADWebAuthController.m b/ADAL/src/ui/ADWebAuthController.m index 71ae18476..5d7c12bc8 100755 --- a/ADAL/src/ui/ADWebAuthController.m +++ b/ADAL/src/ui/ADWebAuthController.m @@ -380,7 +380,6 @@ - (BOOL)webAuthShouldStartLoadRequest:(NSURLRequest *)request // The user cancelled authentication - (void)webAuthDidCancel { - DebugLog(); AD_LOG_INFO(@"-webAuthDidCancel", _correlationId, nil); // Dispatch the completion block @@ -393,7 +392,7 @@ - (void)webAuthDidCancel - (void)webAuthDidCompleteWithURL:(NSURL *)endURL { AD_LOG_INFO_F(@"-webAuthDidCompleteWithURL:", _correlationId, @"%@", endURL); - DebugLog(); + [self endWebAuthenticationWithError:nil orURL:endURL]; [[NSNotificationCenter defaultCenter] postNotificationName:ADWebAuthDidCompleteNotification object:self userInfo:nil]; } From b0d78093f1011c6090a18f2a398649d7b83cd8e1 Mon Sep 17 00:00:00 2001 From: Claus Joergensen Date: Mon, 18 Apr 2016 13:16:41 -0700 Subject: [PATCH 06/14] Accessibility identifiers for the sign-in window and sign-in webview --- ADAL/src/ui/mac/ADAuthenticationViewController.m | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ADAL/src/ui/mac/ADAuthenticationViewController.m b/ADAL/src/ui/mac/ADAuthenticationViewController.m index 9242db268..fe6a848e2 100644 --- a/ADAL/src/ui/mac/ADAuthenticationViewController.m +++ b/ADAL/src/ui/mac/ADAuthenticationViewController.m @@ -91,7 +91,8 @@ - (BOOL)loadView:(ADAuthenticationError * __autoreleasing *)error backing:NSBackingStoreBuffered defer:YES]; [window setDelegate:self]; - + [window setAccessibilityIdentifier:@"ADAL_SIGN_IN_WINDOW"]; + NSView* contentView = window.contentView; @@ -102,7 +103,8 @@ - (BOOL)loadView:(ADAuthenticationError * __autoreleasing *)error [webView setResourceLoadDelegate:self]; [webView setPolicyDelegate:self]; [webView setAutoresizingMask:NSViewHeightSizable | NSViewWidthSizable]; - + [webView setAccessibilityIdentifier:@"ADAL_SIGN_IN_WEBVIEW"]; + [contentView addSubview:webView]; NSProgressIndicator* progressIndicator = [[NSProgressIndicator alloc] initWithFrame:NSMakeRect(DEFAULT_WINDOW_WIDTH / 2 - 16, DEFAULT_WINDOW_HEIGHT / 2 - 16, 32, 32)]; From 6ee0140a1833fbbe0ca7ca53f265bfa90b273ed4 Mon Sep 17 00:00:00 2001 From: Ryan Pangrle Date: Fri, 22 Apr 2016 12:12:41 -0700 Subject: [PATCH 07/14] Update ADAL_Internal.h Update version to 2.1.1. Add 'dev' to the version for as long as we're in the dev branch. --- ADAL/src/ADAL_Internal.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ADAL/src/ADAL_Internal.h b/ADAL/src/ADAL_Internal.h index 0756ce4a9..a82a0f304 100644 --- a/ADAL/src/ADAL_Internal.h +++ b/ADAL/src/ADAL_Internal.h @@ -25,22 +25,22 @@ //version in static define until we identify a better place: #define ADAL_VER_HIGH 2 #define ADAL_VER_LOW 1 -#define ADAL_VER_PATCH 0 +#define ADAL_VER_PATCH 1 #define STR_ADAL_VER_HIGH "2" #define STR_ADAL_VER_LOW "1" -#define STR_ADAL_VER_PATCH "0" +#define STR_ADAL_VER_PATCH "1" // Framework versions only support high and low for the double value, sadly. #define ADAL_VERSION_NUMBER 2.1 -#define ADAL_VERSION_STRING STR_ADAL_VER_HIGH "." STR_ADAL_VER_LOW "." STR_ADAL_VER_PATCH -#define ADAL_VERSION_NSSTRING @"" STR_ADAL_VER_HIGH "." STR_ADAL_VER_LOW "." STR_ADAL_VER_PATCH +#define ADAL_VERSION_STRING STR_ADAL_VER_HIGH "." STR_ADAL_VER_LOW "." STR_ADAL_VER_PATCH "-dev" +#define ADAL_VERSION_NSSTRING @"" STR_ADAL_VER_HIGH "." STR_ADAL_VER_LOW "." STR_ADAL_VER_PATCH "-dev" -#define ADAL_VERSION_(high, low, patch) adalVersion_ ## high ## _ ## low ## _ ## patch +#define ADAL_VERSION_(high, low, patch) adalVersion_ ## high ## _ ## low ## _ ## patch ## _dev // This is specially crafted so the name of the variable matches the full ADAL version -#define ADAL_VERSION_VAR ADAL_VERSION_(2, 1, 0) +#define ADAL_VERSION_VAR ADAL_VERSION_(2, 1, 1) #import "ADLogger+Internal.h" #import "ADErrorCodes.h" From 927940045c79b93fd13be1bac98420e05aef1a12 Mon Sep 17 00:00:00 2001 From: Yong Zeng Date: Mon, 25 Apr 2016 13:54:29 -0700 Subject: [PATCH 08/14] Packed underlying errors to the error object when interaction needed. --- .../src/request/ADAuthenticationRequest+AcquireToken.h | 3 ++- .../src/request/ADAuthenticationRequest+AcquireToken.m | 10 ++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ADAL/src/request/ADAuthenticationRequest+AcquireToken.h b/ADAL/src/request/ADAuthenticationRequest+AcquireToken.h index 4b887052a..aeaf5e026 100644 --- a/ADAL/src/request/ADAuthenticationRequest+AcquireToken.h +++ b/ADAL/src/request/ADAuthenticationRequest+AcquireToken.h @@ -32,7 +32,8 @@ // Bypasses the cache and attempts to request a token from the server, generally called after // attempts to use cached tokens failed -- (void)requestToken:(ADAuthenticationCallback)completionBlock; +- (void)requestToken:(ADAuthenticationError*)previousError + completionBlock:(ADAuthenticationCallback)completionBlock; // Generic OAuth2 Authorization Request, obtains a token from an authorization code. - (void)requestTokenByCode:(NSString*)code diff --git a/ADAL/src/request/ADAuthenticationRequest+AcquireToken.m b/ADAL/src/request/ADAuthenticationRequest+AcquireToken.m index 4159475a5..042e34027 100644 --- a/ADAL/src/request/ADAuthenticationRequest+AcquireToken.m +++ b/ADAL/src/request/ADAuthenticationRequest+AcquireToken.m @@ -130,7 +130,7 @@ - (void)validatedAcquireToken:(ADAuthenticationCallback)completionBlock } } - [self requestToken:completionBlock]; + [self requestToken:error completionBlock:completionBlock]; } /*Attemps to use the cache. Returns YES if an attempt was successful or if an @@ -214,11 +214,12 @@ - (void)attemptToUseCacheItem:(ADTokenCacheItem*)item //The refresh token attempt failed and no other suitable refresh token found //call acquireToken - [self requestToken:completionBlock]; + [self requestToken:[result error] completionBlock:completionBlock]; }];//End of the refreshing token completion block, executed asynchronously. } -- (void)requestToken:(ADAuthenticationCallback)completionBlock +- (void)requestToken:(ADAuthenticationError*)previousError + completionBlock:(ADAuthenticationCallback)completionBlock { [self ensureRequest]; @@ -231,6 +232,7 @@ - (void)requestToken:(ADAuthenticationCallback)completionBlock [ADAuthenticationError errorFromAuthenticationError:AD_ERROR_SERVER_USER_INPUT_NEEDED protocolCode:nil errorDetails:ADCredentialsNeeded + userInfo:@{NSUnderlyingErrorKey:(previousError?previousError:[NSNull null])} correlationId:_correlationId]; ADAuthenticationResult* result = [ADAuthenticationResult resultFromError:error correlationId:_correlationId]; completionBlock(result); @@ -269,7 +271,7 @@ - (void)requestToken:(ADAuthenticationCallback)completionBlock if (silentRequest) { _allowSilent = NO; - [self requestToken:completionBlock]; + [self requestToken:error completionBlock:completionBlock]; return; } From 1184910a5a48a55f00d2ef0a9873dbbde9b12e2a Mon Sep 17 00:00:00 2001 From: Yong Zeng Date: Mon, 25 Apr 2016 16:19:42 -0700 Subject: [PATCH 09/14] Used ivar to store underlying error for AD_ERROR_SERVER_USER_INPUT_NEEDED error. --- .../ADAuthenticationRequest+AcquireToken.h | 3 +-- .../ADAuthenticationRequest+AcquireToken.m | 21 ++++++++++++------- ADAL/src/request/ADAuthenticationRequest.h | 2 ++ ADAL/src/request/ADAuthenticationRequest.m | 1 + 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/ADAL/src/request/ADAuthenticationRequest+AcquireToken.h b/ADAL/src/request/ADAuthenticationRequest+AcquireToken.h index aeaf5e026..4b887052a 100644 --- a/ADAL/src/request/ADAuthenticationRequest+AcquireToken.h +++ b/ADAL/src/request/ADAuthenticationRequest+AcquireToken.h @@ -32,8 +32,7 @@ // Bypasses the cache and attempts to request a token from the server, generally called after // attempts to use cached tokens failed -- (void)requestToken:(ADAuthenticationError*)previousError - completionBlock:(ADAuthenticationCallback)completionBlock; +- (void)requestToken:(ADAuthenticationCallback)completionBlock; // Generic OAuth2 Authorization Request, obtains a token from an authorization code. - (void)requestTokenByCode:(NSString*)code diff --git a/ADAL/src/request/ADAuthenticationRequest+AcquireToken.m b/ADAL/src/request/ADAuthenticationRequest+AcquireToken.m index 042e34027..4611dd7cf 100644 --- a/ADAL/src/request/ADAuthenticationRequest+AcquireToken.m +++ b/ADAL/src/request/ADAuthenticationRequest+AcquireToken.m @@ -130,7 +130,7 @@ - (void)validatedAcquireToken:(ADAuthenticationCallback)completionBlock } } - [self requestToken:error completionBlock:completionBlock]; + [self requestToken:completionBlock]; } /*Attemps to use the cache. Returns YES if an attempt was successful or if an @@ -214,12 +214,13 @@ - (void)attemptToUseCacheItem:(ADTokenCacheItem*)item //The refresh token attempt failed and no other suitable refresh token found //call acquireToken - [self requestToken:[result error] completionBlock:completionBlock]; + _underlyingError = result.error; + SAFE_ARC_RETAIN(_underlyingError); + [self requestToken:completionBlock]; }];//End of the refreshing token completion block, executed asynchronously. } -- (void)requestToken:(ADAuthenticationError*)previousError - completionBlock:(ADAuthenticationCallback)completionBlock +- (void)requestToken:(ADAuthenticationCallback)completionBlock { [self ensureRequest]; @@ -228,12 +229,18 @@ - (void)requestToken:(ADAuthenticationError*)previousError //The cache lookup and refresh token attempt have been unsuccessful, //so credentials are needed to get an access token, but the developer, requested //no UI to be shown: - ADAuthenticationError* error = + ADAuthenticationError* error = _underlyingError ? + [ADAuthenticationError errorFromAuthenticationError:AD_ERROR_SERVER_USER_INPUT_NEEDED + protocolCode:nil + errorDetails:ADCredentialsNeeded + userInfo:@{NSUnderlyingErrorKey:_underlyingError} + correlationId:_correlationId] + : [ADAuthenticationError errorFromAuthenticationError:AD_ERROR_SERVER_USER_INPUT_NEEDED protocolCode:nil errorDetails:ADCredentialsNeeded - userInfo:@{NSUnderlyingErrorKey:(previousError?previousError:[NSNull null])} correlationId:_correlationId]; + ADAuthenticationResult* result = [ADAuthenticationResult resultFromError:error correlationId:_correlationId]; completionBlock(result); return; @@ -271,7 +278,7 @@ - (void)requestToken:(ADAuthenticationError*)previousError if (silentRequest) { _allowSilent = NO; - [self requestToken:error completionBlock:completionBlock]; + [self requestToken:completionBlock]; return; } diff --git a/ADAL/src/request/ADAuthenticationRequest.h b/ADAL/src/request/ADAuthenticationRequest.h index c8000ebaf..3f521e30b 100644 --- a/ADAL/src/request/ADAuthenticationRequest.h +++ b/ADAL/src/request/ADAuthenticationRequest.h @@ -68,6 +68,8 @@ NSString* _logComponent; BOOL _requestStarted; + + ADAuthenticationError* _underlyingError; } @property (retain) NSString* logComponent; diff --git a/ADAL/src/request/ADAuthenticationRequest.m b/ADAL/src/request/ADAuthenticationRequest.m index 5d9dac627..3340f71cf 100644 --- a/ADAL/src/request/ADAuthenticationRequest.m +++ b/ADAL/src/request/ADAuthenticationRequest.m @@ -133,6 +133,7 @@ - (void)dealloc SAFE_ARC_RELEASE(_queryParams); SAFE_ARC_RELEASE(_refreshTokenCredential); SAFE_ARC_RELEASE(_correlationId); + SAFE_ARC_RELEASE(_underlyingError); SAFE_ARC_SUPER_DEALLOC(); } From fd7370ac75ce1d200f09e6fb61d962cb587e2728 Mon Sep 17 00:00:00 2001 From: Yong Zeng Date: Tue, 26 Apr 2016 11:15:26 -0700 Subject: [PATCH 10/14] Simplified a part of code for returning AD_ERROR_SERVER_USER_INPUT_NEEDED error. --- .../request/ADAuthenticationRequest+AcquireToken.m | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/ADAL/src/request/ADAuthenticationRequest+AcquireToken.m b/ADAL/src/request/ADAuthenticationRequest+AcquireToken.m index 4611dd7cf..6b8aaee3b 100644 --- a/ADAL/src/request/ADAuthenticationRequest+AcquireToken.m +++ b/ADAL/src/request/ADAuthenticationRequest+AcquireToken.m @@ -229,16 +229,11 @@ - (void)requestToken:(ADAuthenticationCallback)completionBlock //The cache lookup and refresh token attempt have been unsuccessful, //so credentials are needed to get an access token, but the developer, requested //no UI to be shown: - ADAuthenticationError* error = _underlyingError ? - [ADAuthenticationError errorFromAuthenticationError:AD_ERROR_SERVER_USER_INPUT_NEEDED - protocolCode:nil - errorDetails:ADCredentialsNeeded - userInfo:@{NSUnderlyingErrorKey:_underlyingError} - correlationId:_correlationId] - : - [ADAuthenticationError errorFromAuthenticationError:AD_ERROR_SERVER_USER_INPUT_NEEDED + NSDictionary* underlyingError = _underlyingError ? @{NSUnderlyingErrorKey:_underlyingError} : nil; + ADAuthenticationError* error = [ADAuthenticationError errorFromAuthenticationError:AD_ERROR_SERVER_USER_INPUT_NEEDED protocolCode:nil errorDetails:ADCredentialsNeeded + userInfo:underlyingError correlationId:_correlationId]; ADAuthenticationResult* result = [ADAuthenticationResult resultFromError:error correlationId:_correlationId]; From fe817a7be1b6450be9189b26389cfeee120cf9db Mon Sep 17 00:00:00 2001 From: Yong Zeng Date: Tue, 26 Apr 2016 11:17:36 -0700 Subject: [PATCH 11/14] fixed indentation. --- ADAL/src/request/ADAuthenticationRequest+AcquireToken.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ADAL/src/request/ADAuthenticationRequest+AcquireToken.m b/ADAL/src/request/ADAuthenticationRequest+AcquireToken.m index 6b8aaee3b..283089236 100644 --- a/ADAL/src/request/ADAuthenticationRequest+AcquireToken.m +++ b/ADAL/src/request/ADAuthenticationRequest+AcquireToken.m @@ -230,7 +230,8 @@ - (void)requestToken:(ADAuthenticationCallback)completionBlock //so credentials are needed to get an access token, but the developer, requested //no UI to be shown: NSDictionary* underlyingError = _underlyingError ? @{NSUnderlyingErrorKey:_underlyingError} : nil; - ADAuthenticationError* error = [ADAuthenticationError errorFromAuthenticationError:AD_ERROR_SERVER_USER_INPUT_NEEDED + ADAuthenticationError* error = + [ADAuthenticationError errorFromAuthenticationError:AD_ERROR_SERVER_USER_INPUT_NEEDED protocolCode:nil errorDetails:ADCredentialsNeeded userInfo:underlyingError From d203e7105447fe81d508dd55a5efbd901f4c877f Mon Sep 17 00:00:00 2001 From: Ryan Pangrle Date: Tue, 26 Apr 2016 16:38:50 -0700 Subject: [PATCH 12/14] Only delete RTs when we get 'invalid_grant' from the server MRRTs might still be good for other resources, so we want to limit the cases where we delete them. We still are working with the service to reduce the cases where they send us invalid_grant when another error is more appropriate. --- .../ADAuthenticationRequest+TokenCaching.m | 26 ++++++------ ADAL/tests/ADAcquireTokenTests.m | 40 +++++++++++++++++++ ADAL/tests/XCTestCase+TestHelperMethods.h | 1 + ADAL/tests/XCTestCase+TestHelperMethods.m | 12 +++++- 4 files changed, 65 insertions(+), 14 deletions(-) diff --git a/ADAL/src/cache/ADAuthenticationRequest+TokenCaching.m b/ADAL/src/cache/ADAuthenticationRequest+TokenCaching.m index 6937ec963..0956c49de 100644 --- a/ADAL/src/cache/ADAuthenticationRequest+TokenCaching.m +++ b/ADAL/src/cache/ADAuthenticationRequest+TokenCaching.m @@ -148,14 +148,6 @@ - (void)updateCacheToResult:(ADAuthenticationResult *)result return; } - // If we succeeded, or weren't told it was a bad refresh token then just return right away as there are no changes - // to make to the cache. - if (!(result.status == AD_SUCCEEDED || result.error.code == AD_ERROR_SERVER_REFRESH_TOKEN_REJECTED)) - { - return; - } - - if (AD_SUCCEEDED == result.status) { ADTokenCacheItem* item = [result tokenCacheItem]; @@ -171,13 +163,23 @@ - (void)updateCacheToResult:(ADAuthenticationResult *)result [self updateCacheToItem:item MRRT:[result multiResourceRefreshToken]]; + return; } - else + + if (result.error.code != AD_ERROR_SERVER_REFRESH_TOKEN_REJECTED) { - [self removeItemFromCache:cacheItem - refreshToken:refreshToken - error:result.error]; + return; + } + + // Only remove tokens from the cache if we get an invalid_grant from the server + if (![result.error.protocolCode isEqualToString:@"invalid_grant"]) + { + return; } + + [self removeItemFromCache:cacheItem + refreshToken:refreshToken + error:result.error]; } - (void)updateCacheToItem:(ADTokenCacheItem *)cacheItem diff --git a/ADAL/tests/ADAcquireTokenTests.m b/ADAL/tests/ADAcquireTokenTests.m index cacee5318..094ecfde8 100644 --- a/ADAL/tests/ADAcquireTokenTests.m +++ b/ADAL/tests/ADAcquireTokenTests.m @@ -679,6 +679,46 @@ - (void)testMRRTNoNetworkConnection XCTAssertEqualObjects(allItems[0], mrrtItem); } +- (void)testMRRTUnauthorizedClient +{ + // Refresh tokens should only be deleted when the server returns a 'invalid_grant' error + ADAuthenticationError* error = nil; + ADAuthenticationContext* context = [self getTestAuthenticationContext]; + + // Add an MRRT to the cache as well + ADTokenCacheItem* mrrtItem = [self adCreateMRRTCacheItem]; + [[context tokenCacheStore] addOrUpdateItem:mrrtItem correlationId:nil error:&error]; + XCTAssertNil(error); + + // Set up the mock connection to simulate a no internet connection error + [ADTestURLConnection addResponse:[self adDefaultBadRefreshTokenResponseError:@"unauthorized_client"]]; + + // Web UI should not attempt to launch when we fail to refresh the RT because there is no internet + // connection + [context acquireTokenWithResource:TEST_RESOURCE + clientId:TEST_CLIENT_ID + redirectUri:TEST_REDIRECT_URL + userId:TEST_USER_ID + completionBlock:^(ADAuthenticationResult *result) + { + XCTAssertNotNil(result); + XCTAssertEqual(result.status, AD_FAILED); + XCTAssertNotNil(result.error); + + TEST_SIGNAL; + }]; + + TEST_WAIT; + + // The MRRT should still be in the cache + NSArray* allItems = [[context tokenCacheStore] allItems:&error]; + XCTAssertNotNil(allItems); + XCTAssertEqual(allItems.count, 1); + XCTAssertEqualObjects(allItems[0], mrrtItem); + + +} + - (void)testRequestRetryOnUnusualHttpResponse { //Create a normal authority (not a test one): diff --git a/ADAL/tests/XCTestCase+TestHelperMethods.h b/ADAL/tests/XCTestCase+TestHelperMethods.h index 906fee5d2..733594cb7 100644 --- a/ADAL/tests/XCTestCase+TestHelperMethods.h +++ b/ADAL/tests/XCTestCase+TestHelperMethods.h @@ -71,6 +71,7 @@ typedef enum resource:(NSString *)resource clientId:(NSString *)clientId correlationId:(NSUUID *)correlationId; +- (ADTestURLResponse *)adDefaultBadRefreshTokenResponseError:(NSString*)oauthError; - (ADTestURLResponse *)adDefaultBadRefreshTokenResponse; - (ADTestURLResponse *)adDefaultRefreshResponse:(NSString *)newRefreshToken diff --git a/ADAL/tests/XCTestCase+TestHelperMethods.m b/ADAL/tests/XCTestCase+TestHelperMethods.m index cf1fa2d6c..899d12d5c 100644 --- a/ADAL/tests/XCTestCase+TestHelperMethods.m +++ b/ADAL/tests/XCTestCase+TestHelperMethods.m @@ -294,6 +294,7 @@ - (ADTestURLResponse *)adResponseBadRefreshToken:(NSString *)refreshToken authority:(NSString *)authority resource:(NSString *)resource clientId:(NSString *)clientId + oauthError:(NSString *)oauthError correlationId:(NSUUID *)correlationId { NSString* requestUrlString = [NSString stringWithFormat:@"%@/oauth2/token?x-client-Ver=" ADAL_VERSION_STRING, authority]; @@ -314,19 +315,26 @@ - (ADTestURLResponse *)adResponseBadRefreshToken:(NSString *)refreshToken responseURLString:@"https://contoso.com" responseCode:400 httpHeaderFields:@{} - dictionaryAsJSON:@{ OAUTH2_ERROR : @"bad_refresh_token", + dictionaryAsJSON:@{ OAUTH2_ERROR : oauthError, OAUTH2_ERROR_DESCRIPTION : @"oauth error description"}]; return response; } -- (ADTestURLResponse *)adDefaultBadRefreshTokenResponse +- (ADTestURLResponse *)adDefaultBadRefreshTokenResponseError:(NSString*)oauthError { return [self adResponseBadRefreshToken:TEST_REFRESH_TOKEN authority:TEST_AUTHORITY resource:TEST_RESOURCE clientId:TEST_CLIENT_ID + oauthError:oauthError correlationId:TEST_CORRELATION_ID]; + +} + +- (ADTestURLResponse *)adDefaultBadRefreshTokenResponse +{ + return [self adDefaultBadRefreshTokenResponseError:@"invalid_grant"]; } - (ADTestURLResponse *)adDefaultRefreshResponse:(NSString *)newRefreshToken From cfde608fbb9550fafb8f24f4637445635d1ef282 Mon Sep 17 00:00:00 2001 From: Ryan Pangrle Date: Tue, 26 Apr 2016 18:08:43 -0700 Subject: [PATCH 13/14] Fix for the test to use the silent version --- ADAL/tests/ADAcquireTokenTests.m | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/ADAL/tests/ADAcquireTokenTests.m b/ADAL/tests/ADAcquireTokenTests.m index 094ecfde8..853f8da7f 100644 --- a/ADAL/tests/ADAcquireTokenTests.m +++ b/ADAL/tests/ADAcquireTokenTests.m @@ -693,20 +693,17 @@ - (void)testMRRTUnauthorizedClient // Set up the mock connection to simulate a no internet connection error [ADTestURLConnection addResponse:[self adDefaultBadRefreshTokenResponseError:@"unauthorized_client"]]; - // Web UI should not attempt to launch when we fail to refresh the RT because there is no internet - // connection - [context acquireTokenWithResource:TEST_RESOURCE - clientId:TEST_CLIENT_ID - redirectUri:TEST_REDIRECT_URL - userId:TEST_USER_ID - completionBlock:^(ADAuthenticationResult *result) - { - XCTAssertNotNil(result); - XCTAssertEqual(result.status, AD_FAILED); - XCTAssertNotNil(result.error); - - TEST_SIGNAL; - }]; + [context acquireTokenSilentWithResource:TEST_RESOURCE + clientId:TEST_CLIENT_ID + redirectUri:TEST_REDIRECT_URL + completionBlock:^(ADAuthenticationResult *result) + { + XCTAssertNotNil(result); + XCTAssertEqual(result.status, AD_FAILED); + XCTAssertNotNil(result.error); + + TEST_SIGNAL; + }]; TEST_WAIT; @@ -715,8 +712,6 @@ - (void)testMRRTUnauthorizedClient XCTAssertNotNil(allItems); XCTAssertEqual(allItems.count, 1); XCTAssertEqualObjects(allItems[0], mrrtItem); - - } - (void)testRequestRetryOnUnusualHttpResponse From 0e071ddee87e69aec21cf3b0c4c4c89967e6a968 Mon Sep 17 00:00:00 2001 From: Ryan Pangrle Date: Wed, 27 Apr 2016 12:42:54 -0700 Subject: [PATCH 14/14] Set version and update changelog for 2.1.1 release --- ADAL.podspec | 2 +- ADAL/src/ADAL_Internal.h | 6 +++--- changelog.txt | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/ADAL.podspec b/ADAL.podspec index 38b050f98..6774eb193 100644 --- a/ADAL.podspec +++ b/ADAL.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "ADAL" s.module_name = "ADAL" - s.version = "2.1.0" + s.version = "2.1.1" s.summary = "The ADAL SDK for iOS gives you the ability to add Azure Identity authentication to your application" s.description = <<-DESC diff --git a/ADAL/src/ADAL_Internal.h b/ADAL/src/ADAL_Internal.h index a82a0f304..cedf04e87 100644 --- a/ADAL/src/ADAL_Internal.h +++ b/ADAL/src/ADAL_Internal.h @@ -34,10 +34,10 @@ // Framework versions only support high and low for the double value, sadly. #define ADAL_VERSION_NUMBER 2.1 -#define ADAL_VERSION_STRING STR_ADAL_VER_HIGH "." STR_ADAL_VER_LOW "." STR_ADAL_VER_PATCH "-dev" -#define ADAL_VERSION_NSSTRING @"" STR_ADAL_VER_HIGH "." STR_ADAL_VER_LOW "." STR_ADAL_VER_PATCH "-dev" +#define ADAL_VERSION_STRING STR_ADAL_VER_HIGH "." STR_ADAL_VER_LOW "." STR_ADAL_VER_PATCH +#define ADAL_VERSION_NSSTRING @"" STR_ADAL_VER_HIGH "." STR_ADAL_VER_LOW "." STR_ADAL_VER_PATCH -#define ADAL_VERSION_(high, low, patch) adalVersion_ ## high ## _ ## low ## _ ## patch ## _dev +#define ADAL_VERSION_(high, low, patch) adalVersion_ ## high ## _ ## low ## _ ## patch // This is specially crafted so the name of the variable matches the full ADAL version #define ADAL_VERSION_VAR ADAL_VERSION_(2, 1, 1) diff --git a/changelog.txt b/changelog.txt index ecd5403eb..8643bc0df 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,6 +1,38 @@ +Version 2.1.1 +_____________ +* Added underlying errors to ADAuthenticationErrors when returning user interaction required +* Fixed a crash in ADKeychainTokenCache +* Add Azure Germany, and login-us to the list of known good Azure AD Authorities +* Refresh Tokens will only be removed on 'invalid_grant' OAuth errors now. + +Version 2.1.0 +_____________ +(See the GitHub release page for a more detailed list) +* Mac OS X Support +* Brokered Authentication support with Azure Authenticator +* Support for Conditional Access in 3rd Party apps via Azure Authenticator +* Support for User Cert Based Authentication via Azure Authenticator +* Changed ADLogger callback to allow more data to be passed through for telemetry purposes +* Logging improvements +* Token Cache API changes +* Renamed ADKeychainTokenCacheStore to ADKeychainTokenCache +* Renamed ADTokenCacheStoreItem to ADTokenCacheItem +* Renamed ADAuthenticationBroker to ADWebAuthController +* Changed APIs in ADAuthenticationSettings +* Added ADUserIdentifier API. + + +Version 1.2.6 +_____________ +* Whitelisted "about:blank" on the ADAL webview redirect filter. + + Version 1.2.5 _____________ * Fix for a crash in ADClientMetrics when using ADAL directly against ADFS +* Fix a correlation ID synchronization issue that could cause crashes +* Added token removal logging +* Redirects and forwards to unsecure endpoints (HTTP) will be blocked in the ADAL webview Version 1.2.4 -------------