Skip to content

Commit

Permalink
Hieund/sso seeding test app (#1021)
Browse files Browse the repository at this point in the history
* update msal test app for sso seeding
  • Loading branch information
hieunguyenmsft committed Jul 31, 2020
1 parent 98a6450 commit 9c17425
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 50 deletions.
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## [TBD] - TBD
* update MSAL test app for SSO Seeding flow #1021
* update new variable in configuration to allow user by pass URI check #1013
* Refactor crypto code for cpp integration and add api to generate ephemeral asymmetric key pair. #1018

Expand All @@ -11,6 +11,15 @@
* Clean up account metadata on account removal (#999)
* Silent token lookup for guest accounts with different UPNs (#986)

## [1.1.6] - 2020-07-24 * update new variable in configuration to allow user by pass URI check #1013

### Added
* Support proof of posession for access tokens (#926)

### Fixed
* Clean up account metadata on account removal (#999)
* Silent token lookup for guest accounts with different UPNs (#986)

## [1.1.5] - 2020-06-19

### Added
Expand Down
1 change: 1 addition & 0 deletions MSAL/MSAL Test App.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<string>$(AppIdentifierPrefix)com.microsoft.MSALTestApp</string>
<string>$(AppIdentifierPrefix)com.microsoft.adalcache</string>
<string>$(AppIdentifierPrefix)com.microsoft.workplacejoin</string>
<string>$(AppIdentifierPrefix)com.microsoft.ssoseeding</string>
</array>
</dict>
</plist>
1 change: 1 addition & 0 deletions MSAL/test/app/MSALTestAppSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,6 @@ extern NSString* MSALTestAppCacheChangeNotification;

- (BOOL)addScope:(NSString *)scope;
- (BOOL)removeScope:(NSString *)scope;
+ (BOOL)isSSOSeeding;

@end
5 changes: 5 additions & 0 deletions MSAL/test/app/MSALTestAppSettings.m
Original file line number Diff line number Diff line change
Expand Up @@ -308,5 +308,10 @@ - (void)setCurrentProfile:(NSUInteger)index
[self setValue:profileName forKey:MSAL_APP_PROFILE];
}

+ (BOOL)isSSOSeeding
{
NSString *currentProfile = [MSALTestAppSettings currentProfileName];
return [currentProfile isEqualToString:@"CompanyPortal"];
}

@end
177 changes: 128 additions & 49 deletions MSAL/test/app/ios/MSALTestAppAcquireTokenViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ @interface MSALTestAppAcquireTokenViewController () <UITextFieldDelegate>
@property (nonatomic) IBOutlet UIView *wkWebViewContainer;
@property (nonatomic) WKWebView *customWebview;
@property (weak, nonatomic) IBOutlet UISegmentedControl *authSchemeSegmentControl;

@property (nonatomic) NSString *accountIdentifier;
@end

@implementation MSALTestAppAcquireTokenViewController
Expand Down Expand Up @@ -156,6 +156,11 @@ - (void)viewWillAppear:(BOOL)animated
#pragma mark - Helper

- (MSALPublicClientApplication *)msalTestPublicClientApplication
{
return [self msalTestPublicClientApplicationWithSSOSeeding:NO];
}

- (MSALPublicClientApplication *)msalTestPublicClientApplicationWithSSOSeeding:(BOOL)ssoSeedingCall
{
MSALTestAppSettings *settings = [MSALTestAppSettings settings];
NSDictionary *currentProfile = [MSALTestAppSettings currentProfile];
Expand All @@ -171,7 +176,11 @@ - (MSALPublicClientApplication *)msalTestPublicClientApplication
}

pcaConfig.multipleCloudsSupported = self.instanceAwareSegmentControl.selectedSegmentIndex == 0;

if (ssoSeedingCall)
{
pcaConfig.cacheConfig.keychainSharingGroup = @"com.microsoft.ssoseeding";
pcaConfig.bypassRedirectURIValidation = YES;
}
NSError *error;
MSALPublicClientApplication *application = [[MSALPublicClientApplication alloc] initWithConfiguration:pcaConfig error:&error];

Expand All @@ -185,6 +194,31 @@ - (MSALPublicClientApplication *)msalTestPublicClientApplication
return application;
}

- (MSALInteractiveTokenParameters *)tokenParams:(BOOL)isSSOSeedingCall
{
MSALTestAppSettings *settings = [MSALTestAppSettings settings];
MSALInteractiveTokenParameters *parameters = [[MSALInteractiveTokenParameters alloc] initWithScopes:isSSOSeedingCall ? [self getSSOSeedingScope] : [settings.scopes allObjects]
webviewParameters:[self msalTestWebViewParameters]];

if (self.authSchemeSegmentControl.selectedSegmentIndex == 0 || isSSOSeedingCall)
{
parameters.authenticationScheme = [MSALAuthenticationSchemeBearer new];
}
else
{
NSURL *requestUrl = [NSURL URLWithString:@"https://signedhttprequest.azurewebsites.net/api/validateSHR"];
parameters.authenticationScheme = [[MSALAuthenticationSchemePop alloc] initWithHttpMethod:MSALHttpMethodPOST requestUrl:requestUrl nonce:nil additionalParameters:nil];
}

parameters.loginHint = self.loginHintTextField.text;
parameters.account = settings.currentAccount;
parameters.promptType = isSSOSeedingCall ? MSALPromptTypeDefault : [self promptTypeValue];

parameters.extraQueryParameters = isSSOSeedingCall ? [NSDictionary msidDictionaryFromWWWFormURLEncodedString:@"prompt=none"] : [NSDictionary msidDictionaryFromWWWFormURLEncodedString:self.extraQueryParamsTextField.text];

return parameters;
}

- (MSALWebviewParameters *)msalTestWebViewParameters
{
MSALWebviewParameters *webviewParameters = [[MSALWebviewParameters alloc] initWithAuthPresentationViewController:self];
Expand Down Expand Up @@ -233,49 +267,81 @@ - (void)showCompletionBlockHitMultipleTimesAlert
});
}

#pragma mark - IBAction
- (void)acquireSSOSeeding
{
MSALPublicClientApplication *application = [self msalTestPublicClientApplicationWithSSOSeeding:YES];

if (!application)
{
return;
}

__block BOOL fBlockHit = NO;
void (^completionBlock)(MSALResult *result, NSError *error) = ^(MSALResult *result, NSError *error) {

if (fBlockHit)
{
[self showCompletionBlockHitMultipleTimesAlert];
return;
}

fBlockHit = YES;
dispatch_async(dispatch_get_main_queue(), ^{

if (!result)
{
[self updateResultViewError:error];
}
[[NSNotificationCenter defaultCenter] postNotificationName:MSALTestAppCacheChangeNotification object:self];
});
[self hideCustomeWebViewIfNeed];
};

MSALInteractiveTokenParameters *parameters = [self tokenParams:YES];
[application acquireTokenWithParameters:parameters completionBlock:completionBlock];
}

#pragma mark - IBAction
- (IBAction)onSignoutTapped:(__unused id)sender
{
if (![self checkAccountSelected])
{
return;
}

MSALPublicClientApplication *application = [self msalTestPublicClientApplication];

if (!application)
{
return;
}

__block BOOL fBlockHit = NO;

MSALTestAppSettings *settings = [MSALTestAppSettings settings];

MSALSignoutParameters *signoutParameters = [[MSALSignoutParameters alloc] initWithWebviewParameters:[self msalTestWebViewParameters]];

[application signoutWithAccount:settings.currentAccount
signoutParameters:signoutParameters
completionBlock:^(BOOL success, NSError * _Nullable error) {

if (fBlockHit)
{
[self showCompletionBlockHitMultipleTimesAlert];
return;
}

fBlockHit = YES;
dispatch_async(dispatch_get_main_queue(), ^{

if (!success)
{
[self updateResultViewError:error];
NSString *errorString = [NSString stringWithFormat:@"ssoSeeding sign out error %@", error];
MSID_LOG_WITH_CTX(MSIDLogLevelInfo, nil, @"%@", errorString);
}
else
{
NSString *successText = [NSString stringWithFormat:@"Signout succeeded for user %@", settings.currentAccount.username];
self.resultTextView.text = successText;
MSID_LOG_WITH_CTX(MSIDLogLevelInfo, nil, @"ssoSeeding clear succesfully");
}
});
}];
Expand All @@ -284,15 +350,14 @@ - (IBAction)onSignoutTapped:(__unused id)sender
- (IBAction)onAcquireTokenInteractiveButtonTapped:(__unused id)sender
{
MSALPublicClientApplication *application = [self msalTestPublicClientApplication];

if (!application)
{
return;
}

__block BOOL fBlockHit = NO;
void (^completionBlock)(MSALResult *result, NSError *error) = ^(MSALResult *result, NSError *error) {

if (fBlockHit)
{
[self showCompletionBlockHitMultipleTimesAlert];
Expand All @@ -304,41 +369,26 @@ - (IBAction)onAcquireTokenInteractiveButtonTapped:(__unused id)sender

if (result)
{
[self updateResultView:result];
if ([MSALTestAppSettings isSSOSeeding])
{
[self acquireSSOSeeding];
}
else
{
[self updateResultView:result];
[self hideCustomeWebViewIfNeed];
}
}
else
{
[self updateResultViewError:error];
[self hideCustomeWebViewIfNeed];
}

[self.customWebview loadHTMLString:@"<html><head></head></html>" baseURL:nil];
self.customWebviewContainer.hidden = YES;

[[NSNotificationCenter defaultCenter] postNotificationName:MSALTestAppCacheChangeNotification object:self];
});
};

MSALTestAppSettings *settings = [MSALTestAppSettings settings];

MSALInteractiveTokenParameters *parameters = [[MSALInteractiveTokenParameters alloc] initWithScopes:[settings.scopes allObjects]
webviewParameters:[self msalTestWebViewParameters]];

if (self.authSchemeSegmentControl.selectedSegmentIndex == 0)
{
parameters.authenticationScheme = [MSALAuthenticationSchemeBearer new];
}
else
{
NSURL *requestUrl = [NSURL URLWithString:@"https://signedhttprequest.azurewebsites.net/api/validateSHR"];
parameters.authenticationScheme = [[MSALAuthenticationSchemePop alloc] initWithHttpMethod:MSALHttpMethodPOST requestUrl:requestUrl nonce:nil additionalParameters:nil];
}

parameters.loginHint = self.loginHintTextField.text;
parameters.account = settings.currentAccount;
parameters.promptType = [self promptTypeValue];
parameters.extraQueryParameters = [NSDictionary msidDictionaryFromWWWFormURLEncodedString:self.extraQueryParamsTextField.text];

[application acquireTokenWithParameters:parameters completionBlock:completionBlock];
[application acquireTokenWithParameters:[self tokenParams:NO] completionBlock:completionBlock];
}

- (IBAction)onAcquireTokenSilentButtonTapped:(__unused id)sender
Expand Down Expand Up @@ -414,13 +464,13 @@ - (IBAction)onClearCacheButtonTapped:(id)sender
MSALPublicClientApplicationConfig *pcaConfig = [[MSALPublicClientApplicationConfig alloc] initWithClientId:clientId
redirectUri:redirectUri
authority:authority];

if ([MSALTestAppSettings isSSOSeeding]) pcaConfig.bypassRedirectURIValidation = YES;
MSALPublicClientApplication *application = [[MSALPublicClientApplication alloc] initWithConfiguration:pcaConfig
error:&error];

BOOL result = [application.tokenCache clearWithContext:nil error:&error];
result &= [self clearAllTokenKeysForAccessGroup:pcaConfig.cacheConfig.keychainSharingGroup];

if (result)
{
self.resultTextView.text = @"Successfully cleared cache.";
Expand All @@ -436,6 +486,17 @@ - (IBAction)onClearCacheButtonTapped:(id)sender
{
self.resultTextView.text = [NSString stringWithFormat:@"Failed to clear cache, error = %@", error];
}
// we clear sso Seeding without updating the result
if ([MSALTestAppSettings isSSOSeeding])
{
BOOL resultSSOClear = TRUE;
MSALPublicClientApplication *ssoSeedingApplication = [self msalTestPublicClientApplicationWithSSOSeeding:YES];
resultSSOClear &=[ssoSeedingApplication.tokenCache clearWithContext:nil error:&error];
resultSSOClear &=[self clearAllTokenKeysForAccessGroup:ssoSeedingApplication.configuration.cacheConfig.keychainSharingGroup];
NSString *resultString ;
resultString = resultSSOClear ? @"successfully" : @"failed";
MSID_LOG_WITH_CTX(MSIDLogLevelInfo, nil, @"%@", resultString);
}
}

- (BOOL)clearAllTokenKeysForAccessGroup:(NSString *)accessGroup
Expand Down Expand Up @@ -597,8 +658,6 @@ - (void)updateResultViewError:(NSError *)error
{
NSString *resultText = [NSString stringWithFormat:@"%@", error];
[self.resultTextView setText:resultText];

NSLog(@"%@", resultText);
}

- (void)updateResultView:(MSALResult *)result
Expand All @@ -607,8 +666,6 @@ - (void)updateResultView:(MSALResult *)result
[result.accessToken msidTokenHash], result.expiresOn, result.tenantProfile.tenantId, result.account, result.scopes, result.authority];

[self.resultTextView setText:resultText];

NSLog(@"%@", resultText);
}

- (MSALPromptType)promptTypeValue
Expand Down Expand Up @@ -679,4 +736,26 @@ - (void)runStressTestWithType:(MSALStressTestType)type
}
}

- (void)hideCustomeWebViewIfNeed
{
if (self.webviewTypeSegmentControl.selectedSegmentIndex == 0 &&
self.customWebviewTypeSegmentControl.selectedSegmentIndex == TEST_EMBEDDED_WEBVIEW_CUSTOM)
{
[self.customWebview loadHTMLString:@"<html><head></head></html>" baseURL:nil];
self.customWebviewContainer.hidden = YES;
}
}

- (NSArray<NSString *> *)getSSOSeedingScope
{
NSDictionary *currentProfile = [MSALTestAppSettings currentProfile];
NSMutableArray<NSString *> *ssoSeedingScopes = [NSMutableArray new];
[ssoSeedingScopes addObject:[currentProfile objectForKey:@"resourceId"]];
if ([ssoSeedingScopes count])
{
[ssoSeedingScopes addObject:@"01cb2876-7ebd-4aa4-9cc9-d28bd4d359a9/.default"];
}
return ssoSeedingScopes;
}

@end

0 comments on commit 9c17425

Please sign in to comment.