From a593b4f3e04ff680fd67e6bf80293363fcea23da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julia=20Sam=C3=B3l?= Date: Wed, 14 Jul 2021 15:58:20 +0200 Subject: [PATCH 1/3] feat(sign-in): configure sign in request with external nonce value --- GoogleSignIn/Sources/GIDConfiguration.m | 23 ++++++++++++++----- GoogleSignIn/Sources/GIDSignIn.m | 16 +++++++++++-- .../Public/GoogleSignIn/GIDConfiguration.h | 6 ++++- .../Tests/Unit/GIDConfiguration+Testing.m | 3 ++- GoogleSignIn/Tests/Unit/GIDSignInTest.m | 19 ++++++++------- 5 files changed, 49 insertions(+), 18 deletions(-) diff --git a/GoogleSignIn/Sources/GIDConfiguration.m b/GoogleSignIn/Sources/GIDConfiguration.m index 34ba3c8d..693179c6 100644 --- a/GoogleSignIn/Sources/GIDConfiguration.m +++ b/GoogleSignIn/Sources/GIDConfiguration.m @@ -26,6 +26,9 @@ // The key for the openIDRealm property to be used with NSSecureCoding. static NSString *const kOpenIDRealmKey = @"openIDRealm"; +// The key for the nonce property to be used with NSSecureCoding. +static NSString *const kNonceKey = @"nonce"; + NS_ASSUME_NONNULL_BEGIN @implementation GIDConfiguration @@ -34,7 +37,8 @@ - (instancetype)initWithClientID:(NSString *)clientID { return [self initWithClientID:clientID serverClientID:nil hostedDomain:nil - openIDRealm:nil]; + openIDRealm:nil + nonce:nil]; } - (instancetype)initWithClientID:(NSString *)clientID @@ -42,19 +46,22 @@ - (instancetype)initWithClientID:(NSString *)clientID return [self initWithClientID:clientID serverClientID:serverClientID hostedDomain:nil - openIDRealm:nil]; + openIDRealm:nil + nonce:nil]; } - (instancetype)initWithClientID:(NSString *)clientID serverClientID:(nullable NSString *)serverClientID hostedDomain:(nullable NSString *)hostedDomain - openIDRealm:(nullable NSString *)openIDRealm { + openIDRealm:(nullable NSString *)openIDRealm + nonce:(nullable NSString *)nonce { self = [super init]; if (self) { _clientID = [clientID copy]; _serverClientID = [serverClientID copy]; _hostedDomain = [hostedDomain copy]; _openIDRealm = [openIDRealm copy]; + _nonce = [nonce copy]; } return self; } @@ -62,13 +69,14 @@ - (instancetype)initWithClientID:(NSString *)clientID // Extend NSObject's default description for easier debugging. - (NSString *)description { return [NSString stringWithFormat: - @"<%@: %p, clientID: %@, serverClientID: %@, hostedDomain: %@, openIDRealm: %@>", + @"<%@: %p, clientID: %@, serverClientID: %@, hostedDomain: %@, openIDRealm: %@, nonce: $@>", NSStringFromClass([self class]), self, _clientID, _serverClientID, _hostedDomain, - _openIDRealm]; + _openIDRealm, + _nonce]; } #pragma mark - NSCopying @@ -89,6 +97,7 @@ - (nullable instancetype)initWithCoder:(NSCoder *)coder { NSString *serverClientID = [coder decodeObjectOfClass:[NSString class] forKey:kServerClientIDKey]; NSString *hostedDomain = [coder decodeObjectOfClass:[NSString class] forKey:kHostedDomainKey]; NSString *openIDRealm = [coder decodeObjectOfClass:[NSString class] forKey:kOpenIDRealmKey]; + NSString *nonce = [coder decodeObjectOfClass:[NSString class] forKey:kNonceKey]; // We must have a client ID. if (!clientID) { @@ -98,7 +107,8 @@ - (nullable instancetype)initWithCoder:(NSCoder *)coder { return [self initWithClientID:clientID serverClientID:serverClientID hostedDomain:hostedDomain - openIDRealm:openIDRealm]; + openIDRealm:openIDRealm + nonce:nonce]; } - (void)encodeWithCoder:(NSCoder *)coder { @@ -106,6 +116,7 @@ - (void)encodeWithCoder:(NSCoder *)coder { [coder encodeObject:_serverClientID forKey:kServerClientIDKey]; [coder encodeObject:_hostedDomain forKey:kHostedDomainKey]; [coder encodeObject:_openIDRealm forKey:kOpenIDRealmKey]; + [coder encodeObject:_nonce forKey:kNonceKey]; } @end diff --git a/GoogleSignIn/Sources/GIDSignIn.m b/GoogleSignIn/Sources/GIDSignIn.m index f7e6d04c..ff1cfafc 100644 --- a/GoogleSignIn/Sources/GIDSignIn.m +++ b/GoogleSignIn/Sources/GIDSignIn.m @@ -274,7 +274,8 @@ - (void)addScopes:(NSArray *)scopes [[GIDConfiguration alloc] initWithClientID:self.currentUser.authentication.clientID serverClientID:self.currentUser.serverClientID hostedDomain:self.currentUser.hostedDomain - openIDRealm:self.currentUser.openIDRealm]; + openIDRealm:self.currentUser.openIDRealm + nonce:nil]; GIDSignInInternalOptions *options = [GIDSignInInternalOptions defaultOptionsWithConfiguration:configuration presentingViewController:presentingViewController @@ -595,18 +596,29 @@ - (void)authenticateInteractivelyWithOptions:(GIDSignInInternalOptions *)options [GIDAuthentication parametersWithParameters:options.extraParams emmSupport:emmSupport isPasscodeInfoRequired:NO]]; + #elif TARGET_OS_OSX || TARGET_OS_MACCATALYST [additionalParameters addEntriesFromDictionary:options.extraParams]; #endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST additionalParameters[kSDKVersionLoggingParameter] = GIDVersion(); additionalParameters[kEnvironmentLoggingParameter] = GIDEnvironment(); + NSString *codeVerifier = [OIDAuthorizationRequest generateCodeVerifier]; + NSString *codeChallenge = [OIDAuthorizationRequest codeChallengeS256ForVerifier:codeVerifier]; + NSString *nonce = options.configuration.nonce ? options.configuration.nonce : [OIDAuthorizationRequest generateState]; + OIDAuthorizationRequest *request = [[OIDAuthorizationRequest alloc] initWithConfiguration:_appAuthConfiguration clientId:options.configuration.clientID - scopes:options.scopes + clientSecret:nil + scope:[OIDScopeUtilities scopesWithArray:options.scopes] redirectURL:redirectURL responseType:OIDResponseTypeCode + state:[OIDAuthorizationRequest generateState] + nonce:nonce + codeVerifier:codeVerifier + codeChallenge:codeChallenge + codeChallengeMethod:OIDOAuthorizationRequestCodeChallengeMethodS256 additionalParameters:additionalParameters]; _currentAuthorizationFlow = [OIDAuthorizationService diff --git a/GoogleSignIn/Sources/Public/GoogleSignIn/GIDConfiguration.h b/GoogleSignIn/Sources/Public/GoogleSignIn/GIDConfiguration.h index 4902fa37..97b0424a 100644 --- a/GoogleSignIn/Sources/Public/GoogleSignIn/GIDConfiguration.h +++ b/GoogleSignIn/Sources/Public/GoogleSignIn/GIDConfiguration.h @@ -37,6 +37,9 @@ NS_ASSUME_NONNULL_BEGIN /// Identifier in the OpenID Connect ID token. @property(nonatomic, readonly, nullable) NSString *openIDRealm; +/// A value generated by the app that enables replay protection. +@property(nonatomic, readonly, nullable) NSString *nonce; + /// Unavailable. Please use `initWithClientID:` or one of the other initializers below. /// :nodoc: + (instancetype)new NS_UNAVAILABLE; @@ -69,7 +72,8 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithClientID:(NSString *)clientID serverClientID:(nullable NSString *)serverClientID hostedDomain:(nullable NSString *)hostedDomain - openIDRealm:(nullable NSString *)openIDRealm NS_DESIGNATED_INITIALIZER; + openIDRealm:(nullable NSString *)openIDRealm + nonce:(nullable NSString *)nonce NS_DESIGNATED_INITIALIZER; @end diff --git a/GoogleSignIn/Tests/Unit/GIDConfiguration+Testing.m b/GoogleSignIn/Tests/Unit/GIDConfiguration+Testing.m index 8fd52fc1..558272dc 100644 --- a/GoogleSignIn/Tests/Unit/GIDConfiguration+Testing.m +++ b/GoogleSignIn/Tests/Unit/GIDConfiguration+Testing.m @@ -50,7 +50,8 @@ + (instancetype)testInstance { return [[GIDConfiguration alloc] initWithClientID:OIDAuthorizationRequestTestingClientID serverClientID:kServerClientID hostedDomain:kHostedDomain - openIDRealm:kOpenIDRealm]; + openIDRealm:kOpenIDRealm + nonce:nil]; } @end diff --git a/GoogleSignIn/Tests/Unit/GIDSignInTest.m b/GoogleSignIn/Tests/Unit/GIDSignInTest.m index 01bb447a..5d40303e 100644 --- a/GoogleSignIn/Tests/Unit/GIDSignInTest.m +++ b/GoogleSignIn/Tests/Unit/GIDSignInTest.m @@ -630,10 +630,11 @@ - (void)testAddScopes { } - (void)testOpenIDRealm { - _signIn.configuration = [[GIDConfiguration alloc] initWithClientID:kClientId - serverClientID:nil - hostedDomain:nil - openIDRealm:kOpenIDRealm]; + _signIn._configuration = [[GIDConfiguration alloc] initWithClientID:kClientId + serverClientID:nil + hostedDomain:nil + openIDRealm:kOpenIDRealm + nonce:nil]; [self OAuthLoginWithAddScopesFlow:NO authError:nil @@ -665,10 +666,12 @@ - (void)testOAuthLogin_LoginHint { } - (void)testOAuthLogin_HostedDomain { - _signIn.configuration = [[GIDConfiguration alloc] initWithClientID:kClientId - serverClientID:nil - hostedDomain:kHostedDomain - openIDRealm:nil]; + + _signIn._configuration = [[GIDConfiguration alloc] initWithClientID:kClientId + serverClientID:nil + hostedDomain:kHostedDomain + openIDRealm:nil + nonce:nil]; [self OAuthLoginWithAddScopesFlow:NO authError:nil From d0cf7cd931fdab2b133cbdb19d7e00cf45759ce3 Mon Sep 17 00:00:00 2001 From: toshi0383 Date: Tue, 25 Oct 2022 14:04:19 +0900 Subject: [PATCH 2/3] fix: compile --- GoogleSignIn/Sources/GIDSignIn.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/GoogleSignIn/Sources/GIDSignIn.m b/GoogleSignIn/Sources/GIDSignIn.m index ff1cfafc..2e38a32c 100644 --- a/GoogleSignIn/Sources/GIDSignIn.m +++ b/GoogleSignIn/Sources/GIDSignIn.m @@ -1054,13 +1054,14 @@ + (nullable GIDConfiguration *)configurationFromBundle:(NSBundle *)bundle { forKey:kConfigServerClientIDKey]; NSString *hostedDomain = [GIDSignIn configValueFromBundle:bundle forKey:kConfigHostedDomainKey]; NSString *openIDRealm = [GIDSignIn configValueFromBundle:bundle forKey:kConfigOpenIDRealmKey]; - + // If we have at least a client ID, try to construct a configuration. if (clientID) { configuration = [[GIDConfiguration alloc] initWithClientID:clientID serverClientID:serverClientID hostedDomain:hostedDomain - openIDRealm:openIDRealm]; + openIDRealm:openIDRealm + nonce:nil]; } return configuration; From 76acf9c2cfeb7e09305cae5b2e81da7011484d27 Mon Sep 17 00:00:00 2001 From: toshi0383 Date: Wed, 25 Jan 2023 20:50:17 +0900 Subject: [PATCH 3/3] Fix conflicts --- GoogleSignIn/Sources/GIDGoogleUser.m | 3 ++- GoogleSignIn/Sources/GIDSignIn.m | 35 +++------------------------- 2 files changed, 5 insertions(+), 33 deletions(-) diff --git a/GoogleSignIn/Sources/GIDGoogleUser.m b/GoogleSignIn/Sources/GIDGoogleUser.m index 828ac5b6..0ef8bc50 100644 --- a/GoogleSignIn/Sources/GIDGoogleUser.m +++ b/GoogleSignIn/Sources/GIDGoogleUser.m @@ -102,7 +102,8 @@ - (GIDConfiguration *)configuration { _cachedConfiguration = [[GIDConfiguration alloc] initWithClientID:clientID serverClientID:serverClientID hostedDomain:[self hostedDomain] - openIDRealm:openIDRealm]; + openIDRealm:openIDRealm + nonce:nil]; }; } return _cachedConfiguration; diff --git a/GoogleSignIn/Sources/GIDSignIn.m b/GoogleSignIn/Sources/GIDSignIn.m index 6c549455..108b8856 100644 --- a/GoogleSignIn/Sources/GIDSignIn.m +++ b/GoogleSignIn/Sources/GIDSignIn.m @@ -269,30 +269,8 @@ - (void)signInWithPresentingViewController:(UIViewController *)presentingViewCon - (void)addScopes:(NSArray *)scopes presentingViewController:(UIViewController *)presentingViewController completion:(nullable GIDSignInCompletion)completion { -<<<<<<< HEAD - // A currentUser must be available in order to complete this flow. - if (!self.currentUser) { - // No currentUser is set, notify callback of failure. - NSError *error = [NSError errorWithDomain:kGIDSignInErrorDomain - code:kGIDSignInErrorCodeNoCurrentUser - userInfo:nil]; - if (completion) { - dispatch_async(dispatch_get_main_queue(), ^{ - completion(nil, error); - }); - } - return; - } - GIDConfiguration *configuration = - [[GIDConfiguration alloc] initWithClientID:self.currentUser.authentication.clientID - serverClientID:self.currentUser.serverClientID - hostedDomain:self.currentUser.hostedDomain - openIDRealm:self.currentUser.openIDRealm - nonce:nil]; -======= GIDConfiguration *configuration = self.currentUser.configuration; ->>>>>>> upstream/main GIDSignInInternalOptions *options = [GIDSignInInternalOptions defaultOptionsWithConfiguration:configuration presentingViewController:presentingViewController @@ -593,16 +571,9 @@ - (void)authenticateInteractivelyWithOptions:(GIDSignInInternalOptions *)options #if TARGET_OS_IOS && !TARGET_OS_MACCATALYST [additionalParameters addEntriesFromDictionary: -<<<<<<< HEAD - [GIDAuthentication parametersWithParameters:options.extraParams - emmSupport:emmSupport - isPasscodeInfoRequired:NO]]; - -======= - [GIDEMMSupport parametersWithParameters:options.extraParams - emmSupport:emmSupport - isPasscodeInfoRequired:NO]]; ->>>>>>> upstream/main + [GIDEMMSupport parametersWithParameters:options.extraParams + emmSupport:emmSupport + isPasscodeInfoRequired:NO]]; #elif TARGET_OS_OSX || TARGET_OS_MACCATALYST [additionalParameters addEntriesFromDictionary:options.extraParams]; #endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST