-
Notifications
You must be signed in to change notification settings - Fork 35
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
Webview interaction and system webview #126
Changes from 6 commits
5f61177
e905d25
ba71b3d
fc1d8db
f29dcb3
c669afe
d8813b5
c8c826f
4dd6ec6
d987e60
8c99592
d99bc6f
10aae32
0e34d81
9e7fb0b
0bd3d7f
7b5255b
69e15a1
fbbb81e
c5675ec
f1207ee
d58eed6
6f737f0
b2c9929
0dc3a61
243fb01
9ea3817
a4d2286
459dc3a
a234566
a4eacd1
af44efc
36b3ef2
517a114
a5d230e
5ed28e3
2b8b756
1230844
dda26c7
375e1d4
f54800a
ec90fb5
b31e99f
8718d82
a9cff24
1ea816d
7b8979c
7d9ed31
58b7c6a
dad2296
9801600
9d505c8
97ddaa1
9ec3d45
804186a
17834c5
e5da20a
865eff9
185db0d
6183514
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>IDEDidComputeMac32BitWarning</key> | ||
<true/> | ||
</dict> | ||
</plist> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,9 +69,49 @@ typedef NS_ENUM(NSInteger, MSIDErrorCode) | |
MSIDErrorInvalidClient = -51015, | ||
MSIDErrorInvalidGrant = -51016, | ||
MSIDErrorInvalidParameter = -51017, | ||
|
||
/*! | ||
The user or application failed to authenticate in the interactive flow. | ||
Inspect MSALOAuthErrorKey and MSALErrorDescriptionKey in the userInfo | ||
dictionary for more detailed information about the specific error. | ||
*/ | ||
MSIDErrorAuthorizationFailed = -52018, | ||
|
||
/*! | ||
The state returned by the server does not match the state that was sent to | ||
the server at the beginning of the authorization attempt. | ||
*/ | ||
MSALErrorInvalidState = -52501, | ||
/*! | ||
Interaction required errors occur because of a wide variety of errors | ||
returned by the authentication service. | ||
*/ | ||
MSIDErrorMismatchedUser = -52101, | ||
MSIDErrorNoAuthorizationResponse = -52102, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: no authorization code? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no, it's just url nil response. |
||
MSIDErrorBadAuthorizationResponse = -52103, | ||
|
||
|
||
MSIDErrorUserCancel = -51019, | ||
/*! | ||
The authentication request was cancelled programmatically. | ||
*/ | ||
MSIDErrorSessionCanceled = -51020, | ||
/*! | ||
An interactive authentication session is already running with the | ||
SafariViewController visible. Another authentication session can not be | ||
launched yet. | ||
*/ | ||
MSIDErrorInteractiveSessionAlreadyRunning = -51021, | ||
/*! | ||
An interactive authentication session failed to start. | ||
*/ | ||
MSIDErrorInteractiveSessionStartFailure = -51022, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is the case when this would happen? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SFAuthenticationSession: when start is called on a cancelled session |
||
|
||
MSIDErrorCodeFirst = MSIDErrorInternal, | ||
MSIDErrorCodeLast = MSIDErrorInvalidParameter | ||
}; | ||
|
||
extern NSError *MSIDCreateError(NSString *domain, NSInteger code, NSString *errorDescription, NSString *oauthError, NSString *subError, NSError *underlyingError, NSUUID *correlationId, NSDictionary *additionalUserInfo); | ||
|
||
extern MSIDErrorCode MSIDErrorCodeForOAuthError(NSString *oauthError, MSIDErrorCode defaultCode); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,3 +49,20 @@ | |
} | ||
|
||
|
||
MSIDErrorCode MSIDErrorCodeForOAuthError(NSString *oauthError, MSIDErrorCode defaultCode) | ||
{ | ||
if (oauthError && [oauthError caseInsensitiveCompare:@"invalid_request"] == NSOrderedSame) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We already have this code in token response I think. Can we combine it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done, i've changed TokenResponse to call this. |
||
{ | ||
return MSIDErrorInvalidRequest; | ||
} | ||
if (oauthError && [oauthError caseInsensitiveCompare:@"invalid_client"] == NSOrderedSame) | ||
{ | ||
return MSIDErrorInvalidClient; | ||
} | ||
if (oauthError && [oauthError caseInsensitiveCompare:@"invalid_scope"] == NSOrderedSame) | ||
{ | ||
return MSIDErrorInvalidParameter; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: should we be more specific about which parameter is invalid? |
||
} | ||
|
||
return defaultCode; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,6 +30,7 @@ | |
#import "MSIDLegacySingleResourceToken.h" | ||
#import "MSIDIdToken.h" | ||
#import "MSIDAccount.h" | ||
#import "MSIDSystemWebviewController.h" | ||
|
||
@implementation MSIDOauth2Factory | ||
|
||
|
@@ -269,15 +270,24 @@ - (MSIDAccount *)fillAccount:(MSIDAccount *)account | |
#pragma mark - Webview controllers | ||
- (id<MSIDWebviewInteracting>)embeddedWebviewControllerWithRequest:(MSIDRequestParameters *)requestParams | ||
customWebview:(WKWebView *)webview | ||
completionHandler:(MSIDWebUICompletionHandler)completionHandler | ||
{ | ||
// TODO: return default | ||
return nil; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should be filled |
||
} | ||
|
||
- (id<MSIDWebviewInteracting>)systemWebviewControllerWithRequest:(MSIDRequestParameters *)requestParams | ||
callbackURLScheme:(NSString *)callbackURLScheme | ||
completionHandler:(MSIDWebUICompletionHandler)completionHandler | ||
{ | ||
// TODO: return default | ||
return nil; | ||
} | ||
|
||
- (NSURL *)startURLFromRequest:(MSIDRequestParameters *)requestParams | ||
{ | ||
// Default URL from authority | ||
return nil; | ||
} | ||
|
||
@end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,5 +40,7 @@ | |
|
||
@property (readwrite) NSString *loginHint; | ||
@property (readwrite) NSString *extraQueryParameters; | ||
@property (readwrite) NSString *promptBehavior; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think prompt behavior was something AAD V1 specific? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It also exists for MSAL in a different value.
|
||
@property (readwrite) NSString *claims; | ||
|
||
@end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,7 @@ | |
#import "MSIDRefreshToken.h" | ||
#import "MSIDLegacySingleResourceToken.h" | ||
#import "MSIDAccount.h" | ||
#import "MSIDDeviceId.h" | ||
|
||
@implementation MSIDAADV1Oauth2Factory | ||
|
||
|
@@ -151,15 +152,70 @@ - (MSIDLegacySingleResourceToken *)legacyTokenFromResponse:(MSIDTokenResponse *) | |
#pragma mark - Webview controllers | ||
- (id<MSIDWebviewInteracting>)embeddedWebviewControllerWithRequest:(MSIDRequestParameters *)requestParams | ||
Webview:(WKWebView *)webview | ||
completionHandler:(MSIDWebUICompletionHandler)completionHandler | ||
{ | ||
// Create MSIDEmbeddedWebviewRequest and create EmbeddedWebviewController | ||
return nil; | ||
} | ||
|
||
- (id<MSIDWebviewInteracting>)systemWebviewControllerWithRequest:(MSIDRequestParameters *)requestParams | ||
callbackURLScheme:(NSString *)callbackURLScheme | ||
completionHandler:(MSIDWebUICompletionHandler)completionHandler | ||
{ | ||
// Create MSIDSystemWebviewRequest and create SystemWebviewController | ||
return nil; | ||
} | ||
|
||
- (NSURL *)startURLFrom:(MSIDRequestParameters *)requestParams | ||
{ | ||
NSString *state = [self encodeProtocolState:requestParams]; | ||
|
||
// if value is nil, it won't appear in the dictionary | ||
NSMutableDictionary *queryParams = [NSMutableDictionary dictionaryWithObjectsAndKeys: | ||
MSID_OAUTH2_CODE, MSID_OAUTH2_RESPONSE_TYPE, | ||
[requestParams clientId], MSID_OAUTH2_CLIENT_ID, | ||
[requestParams resource], MSID_OAUTH2_RESOURCE, | ||
[requestParams redirectUri], MSID_OAUTH2_REDIRECT_URI, | ||
state, MSID_OAUTH2_STATE, | ||
requestParams.promptBehavior, @"prompt", | ||
@"1", @"hashchrome", //to hide back button in UI | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just curious, do we still need this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code is JZ's code. I was merely copying and pasting for now to make it compile. |
||
[NSString msidIsStringNilOrBlank:requestParams.loginHint] ? nil : requestParams.loginHint, MSID_OAUTH2_LOGIN_HINT, | ||
nil]; | ||
|
||
[queryParams addEntriesFromDictionary:[MSIDDeviceId deviceId]]; | ||
|
||
NSMutableString *startUrl = [NSMutableString stringWithFormat:@"%@?%@", | ||
[requestParams.authority.absoluteString stringByAppendingString:MSID_OAUTH2_AUTHORIZE_SUFFIX], [queryParams msidURLFormEncode]]; | ||
|
||
// we expect extraQueryParameters to be URL form encoded | ||
if (![NSString msidIsStringNilOrBlank:requestParams.extraQueryParameters]) | ||
{ | ||
//Add the '&' for the additional params if not there already: | ||
if ([requestParams.extraQueryParameters hasPrefix:@"&"]) | ||
{ | ||
[startUrl appendString:requestParams.extraQueryParameters.msidTrimmedString]; | ||
} | ||
else | ||
{ | ||
[startUrl appendFormat:@"&%@", requestParams.extraQueryParameters.msidTrimmedString]; | ||
} | ||
} | ||
|
||
// we expect claims to be URL form encoded | ||
if (![NSString msidIsStringNilOrBlank:requestParams.claims]) | ||
{ | ||
[startUrl appendFormat:@"&claims=%@", requestParams.claims]; | ||
} | ||
|
||
return [NSURL URLWithString:startUrl]; | ||
} | ||
|
||
// TODO: if same in MSAL, move to common logic | ||
// Encodes the state parameter for a protocol message | ||
- (NSString *)encodeProtocolState:(MSIDRequestParameters *)requestParams | ||
{ | ||
return [[[NSMutableDictionary dictionaryWithObjectsAndKeys:[requestParams authority], @"a", [requestParams resource], @"r", nil] | ||
msidURLFormEncode] msidBase64UrlEncode]; | ||
} | ||
|
||
@end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,8 +27,8 @@ | |
|
||
#import <Foundation/Foundation.h> | ||
|
||
@interface MSIDWebviewRequest : NSObject | ||
@interface MSIDCryptoHelper : NSObject | ||
|
||
@property NSURL *startURL; | ||
+ (NSData *)msidSHA256fromString:(NSString *)string; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't we already have this functionality in some category (e.g. msidComputeSHA256)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, didn't realize we had it there. |
||
|
||
@end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
//------------------------------------------------------------------------------ | ||
// | ||
// Copyright (c) Microsoft Corporation. | ||
// All rights reserved. | ||
// | ||
// This code is licensed under the MIT License. | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files(the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions : | ||
// | ||
// The above copyright notice and this permission notice shall be included in | ||
// all copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
// THE SOFTWARE. | ||
// | ||
//------------------------------------------------------------------------------ | ||
|
||
#import "MSIDCryptoHelper.h" | ||
#import <CommonCrypto/CommonDigest.h> | ||
#import "MSIDError.h" | ||
|
||
@implementation MSIDCryptoHelper | ||
|
||
+ (NSData *)msidSHA256fromString:(NSString *)string; | ||
{ | ||
NSData *inputData = [string dataUsingEncoding:NSASCIIStringEncoding]; | ||
NSMutableData *outData = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH]; | ||
|
||
// input length shouldn't be this big | ||
if (inputData.length > UINT32_MAX) | ||
{ | ||
MSID_LOG_ERROR(nil, @"InvalidArgumentException: length too big"); | ||
@throw [NSException exceptionWithName: NSInvalidArgumentException | ||
reason:@"Please provide a valid string parameter." | ||
userInfo:nil]; | ||
} | ||
CC_SHA256(inputData.bytes, (uint32_t)inputData.length, outData.mutableBytes); | ||
|
||
return outData; | ||
} | ||
|
||
@end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -94,4 +94,22 @@ - (NSDictionary *)dictionaryByRemovingFields:(NSArray *)fieldsToRemove | |
return mutableDict; | ||
} | ||
|
||
- (NSArray<NSURLQueryItem *> *)urlQueryItemsArray; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just curious, where is this being used? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we use this constructing startURL.
|
||
{ | ||
NSMutableArray<NSURLQueryItem *> *array = [NSMutableArray new]; | ||
|
||
for (id key in self.allKeys) | ||
{ | ||
|
||
NSString *value = [self[key] isKindOfClass:NSUUID.class] ? | ||
((NSUUID *)self[key]).UUIDString : [self[key] description]; | ||
|
||
[array addObject:[NSURLQueryItem queryItemWithName:[key description] | ||
value:value]]; | ||
} | ||
|
||
return array; | ||
} | ||
|
||
|
||
@end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just curious, when is this error returned?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When parameter sets a user, and we force webview to login as a different user.
We handled it as an error in MSAL, we can discuss about this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can we put errors in increasing order? (MSIDErrorInvalidState is in the middle)