Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for scenarios where access_token is not returned #952

Merged
merged 5 commits into from
Mar 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -783,8 +783,7 @@ - (BOOL)saveAccessTokenWithConfiguration:(MSIDConfiguration *)configuration
MSIDAccessToken *accessToken = [factory accessTokenFromResponse:response configuration:configuration];
if (!accessToken)
{
MSIDFillAndLogError(error, MSIDErrorInternal, @"Response does not contain an access token", context.correlationId);
return NO;
return YES;
}

if (![self checkAccountIdentifier:accessToken.accountIdentifier.homeAccountId context:context error:error])
Expand Down
8 changes: 4 additions & 4 deletions IdentityCore/src/oauth2/MSIDOauth2Factory.m
Original file line number Diff line number Diff line change
Expand Up @@ -97,21 +97,21 @@ - (BOOL)verifyResponse:(MSIDTokenResponse *)response
return NO;
}

if (![self verifyAccessToken:response.accessToken])
if (![self verifyToken:response.accessToken] && ![self verifyToken:response.idToken])
{
if (error)
{
*error = MSIDCreateError(MSIDErrorDomain, MSIDErrorInternal, @"Authentication response received without expected accessToken", nil, nil, nil, context.correlationId, nil, YES);
*error = MSIDCreateError(MSIDErrorDomain, MSIDErrorInternal, @"Authentication response received without expected accessToken and idToken", nil, nil, nil, context.correlationId, nil, YES);
}
return NO;
}

return YES;
}

- (BOOL)verifyAccessToken:(NSString *)accessToken
- (BOOL)verifyToken:(NSString *)token
{
return ![NSString msidIsStringNilOrBlank:accessToken];
return ![NSString msidIsStringNilOrBlank:token];
}

#pragma mark - Tokens
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ - (BOOL)validateTokenResult:(MSIDTokenResult *)tokenResult
we'd like to throw an error and specify which scopes were granted and which ones not
*/

if (tokenResult.accessToken == nil)
{
return YES;
}

NSOrderedSet *grantedScopes = tokenResult.accessToken.scopes;
NSOrderedSet *normalizedGrantedScopes = grantedScopes.normalizedScopeSet;

Expand Down
23 changes: 20 additions & 3 deletions IdentityCore/tests/MSIDOauth2FactoryTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ - (void)testVerifyResponse_whenOAuthError_shouldReturnError
XCTAssertEqualObjects(error.userInfo[MSIDOAuthErrorKey], @"invalid_grant");
}

- (void)testVerifyResponse_whenNoAccessToken_shouldReturnError
- (void)testVerifyResponse_whenNoAccessTokenAndNoIdToken_shouldReturnError
{
MSIDOauth2Factory *factory = [MSIDOauth2Factory new];

Expand All @@ -129,10 +129,10 @@ - (void)testVerifyResponse_whenNoAccessToken_shouldReturnError

XCTAssertFalse(result);
XCTAssertEqual(error.domain, MSIDErrorDomain);
XCTAssertEqualObjects(error.userInfo[MSIDErrorDescriptionKey], @"Authentication response received without expected accessToken");
XCTAssertEqualObjects(error.userInfo[MSIDErrorDescriptionKey], @"Authentication response received without expected accessToken and idToken");
}

- (void)testVerifyResponse_whenValidResponseWithTokens_shouldReturnNoError
- (void)testVerifyResponse_whenValidResponseWithAccessTokens_shouldReturnNoError
{
MSIDOauth2Factory *factory = [MSIDOauth2Factory new];

Expand All @@ -149,6 +149,23 @@ - (void)testVerifyResponse_whenValidResponseWithTokens_shouldReturnNoError
XCTAssertNil(error);
}

- (void)testVerifyResponse_whenValidResponseWithIdTokens_shouldReturnNoError
{
MSIDOauth2Factory *factory = [MSIDOauth2Factory new];

NSString *rawClientInfo = [@{ @"uid" : @"1", @"utid" : @"1234-5678-90abcdefg"} msidBase64UrlJson];
MSIDTokenResponse *response = [[MSIDTokenResponse alloc] initWithJSONDictionary:@{@"id_token":@"fake_id_token",
@"refresh_token":@"fake_refresh_token",
@"client_info":rawClientInfo
}
error:nil];
NSError *error = nil;
BOOL result = [factory verifyResponse:response context:nil error:&error];

XCTAssertTrue(result);
XCTAssertNil(error);
}

#pragma mark - Tokens

- (void)testBaseTokenFromResponse_whenNilResponse_shouldReturnNil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ - (void)testSaveTokensWithRequestParams_withAccessToken_andIntuneEnrolled_should
[self setUpEnrollmentIdsCache:YES];
}

- (void)testSaveTokensWithRequestParams_withNilAccessToken_shouldNotSaveToken_returnError
- (void)testSaveTokensWithRequestParams_withNilAccessToken_shouldSaveToken
{
MSIDTokenResponse *tokenResponse = [MSIDTestTokenResponse v2TokenResponseWithAT:nil
RT:@"rt"
Expand All @@ -167,9 +167,62 @@ - (void)testSaveTokensWithRequestParams_withNilAccessToken_shouldNotSaveToken_re
context:nil
error:&error];

XCTAssertNotNil(error);
XCTAssertFalse(result);
XCTAssertEqual(error.code, MSIDErrorInternal);
XCTAssertNil(error);
XCTAssertTrue(result);

NSArray *idTokens = [MSIDTestCacheAccessorHelper getAllIdTokens:_cacheAccessor];
XCTAssertNil(error);

XCTAssertEqual([idTokens count], 1);
XCTAssertEqualObjects([idTokens[0] rawIdToken], tokenResponse.idToken);
}

- (void)testSaveTokensWithRequestParams_withNilIdToken_shouldSaveToken
{
MSIDTokenResponse *tokenResponse = [MSIDTestTokenResponse v2TokenResponseWithAT:@"access_token"
RT:@"rt"
scopes:[NSOrderedSet orderedSetWithObjects:DEFAULT_TEST_SCOPE, nil]
idToken:nil
uid:@"uid"
utid:@"utid"
familyId:@"family_id"];

NSError *error = nil;
BOOL result = [_cacheAccessor saveTokensWithConfiguration:[MSIDTestConfiguration v2DefaultConfiguration]
response:tokenResponse
factory:[MSIDAADV2Oauth2Factory new]
context:nil
error:&error];

XCTAssertNil(error);
XCTAssertTrue(result);

NSArray *accessTokens = [MSIDTestCacheAccessorHelper getAllDefaultAccessTokens:_cacheAccessor];
XCTAssertNil(error);

XCTAssertEqual([accessTokens count], 1);
XCTAssertEqualObjects([accessTokens[0] accessToken], tokenResponse.accessToken);
}

- (void)testSaveTokensWithRequestParams_withNilAccessTokenAndNilIdToken_shouldNotSaveToken
{
MSIDTokenResponse *tokenResponse = [MSIDTestTokenResponse v2TokenResponseWithAT:nil
RT:nil
scopes:[NSOrderedSet orderedSetWithObjects:DEFAULT_TEST_SCOPE, nil]
idToken:nil
uid:@"uid"
utid:@"utid"
familyId:@"family_id"];

NSError *error = nil;
BOOL result = [_cacheAccessor saveTokensWithConfiguration:[MSIDTestConfiguration v2DefaultConfiguration]
response:tokenResponse
factory:[MSIDAADV2Oauth2Factory new]
context:nil
error:&error];

XCTAssertNil(error);
XCTAssertTrue(result);

NSError *readError = nil;
NSArray *allTokens = [_cacheAccessor allTokensWithContext:nil error:&readError];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,7 @@ - (void)testAcquireTokenSilent_whenAccessTokenInCache_andForceRefreshYES_andNoAT
requestScopes:@"user.read tasks.read openid profile offline_access"
responseAT:@""
responseRT:@"new rt"
responseID:nil
responseID:@""
responseScope:@"user.read tasks.read"
responseClientInfo:differentClientInfo
url:DEFAULT_TEST_TOKEN_ENDPOINT_GUID
Expand Down