Skip to content
Closed
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
16 changes: 15 additions & 1 deletion flutter_appauth/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,18 @@ class _MyAppState extends State<MyApp> {
preferEphemeralSession: true),
),
),
if (Platform.isIOS)
Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
child: const Text(
'Sign in with auto code exchange using default system browser (iOS only)',
textAlign: TextAlign.center,
),
onPressed: () =>
_signInWithAutoCodeExchange(defaultSystemBrowser: true),
),
),
ElevatedButton(
child: const Text('Refresh token'),
onPressed: _refreshToken != null ? _refresh : null,
Expand Down Expand Up @@ -216,7 +228,8 @@ class _MyAppState extends State<MyApp> {
}

Future<void> _signInWithAutoCodeExchange(
{bool preferEphemeralSession = false}) async {
{bool preferEphemeralSession = false,
bool defaultSystemBrowser = false}) async {
try {
_setBusyState();

Expand All @@ -229,6 +242,7 @@ class _MyAppState extends State<MyApp> {
serviceConfiguration: _serviceConfiguration,
scopes: _scopes,
preferEphemeralSession: preferEphemeralSession,
defaultSystemBrowser: defaultSystemBrowser,
),
);

Expand Down
23 changes: 15 additions & 8 deletions flutter_appauth/ios/Classes/FlutterAppauthPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ @interface AuthorizationTokenRequestParameters : TokenRequestParameters
@property(nonatomic, strong) NSString *loginHint;
@property(nonatomic, strong) NSArray *promptValues;
@property(nonatomic, strong) NSString *responseMode;
@property(nonatomic, readwrite) BOOL defaultSystemBrowser;
@end

@implementation AuthorizationTokenRequestParameters
Expand All @@ -66,6 +67,7 @@ - (id)initWithArguments:(NSDictionary *)arguments {
_loginHint = [ArgumentProcessor processArgumentValue:arguments withKey:@"loginHint"];
_promptValues = [ArgumentProcessor processArgumentValue:arguments withKey:@"promptValues"];
_responseMode = [ArgumentProcessor processArgumentValue:arguments withKey:@"responseMode"];
_defaultSystemBrowser = [[ArgumentProcessor processArgumentValue:arguments withKey:@"defaultSystemBrowser"] isEqual:@YES];
return self;
}
@end
Expand All @@ -78,6 +80,7 @@ @interface EndSessionRequestParameters : NSObject
@property(nonatomic, strong) NSString *discoveryUrl;
@property(nonatomic, strong) NSDictionary *serviceConfigurationParameters;
@property(nonatomic, strong) NSDictionary *additionalParameters;
@property(nonatomic, readwrite) BOOL defaultSystemBrowser;
@end

@implementation EndSessionRequestParameters
Expand All @@ -89,6 +92,7 @@ - (id)initWithArguments:(NSDictionary *)arguments {
_discoveryUrl = [ArgumentProcessor processArgumentValue:arguments withKey:@"discoveryUrl"];
_serviceConfigurationParameters = [ArgumentProcessor processArgumentValue:arguments withKey:@"serviceConfiguration"];
_additionalParameters = [ArgumentProcessor processArgumentValue:arguments withKey:@"additionalParameters"];
_defaultSystemBrowser = [[ArgumentProcessor processArgumentValue:arguments withKey:@"defaultSystemBrowser"] isEqual:@YES];
return self;
}
@end
Expand Down Expand Up @@ -157,7 +161,7 @@ -(void)handleAuthorizeMethodCall:(NSDictionary*)arguments result:(FlutterResult)
}
if(requestParameters.serviceConfigurationParameters != nil) {
OIDServiceConfiguration *serviceConfiguration = [self processServiceConfigurationParameters:requestParameters.serviceConfigurationParameters];
[self performAuthorization:serviceConfiguration clientId:requestParameters.clientId clientSecret:requestParameters.clientSecret scopes:requestParameters.scopes redirectUrl:requestParameters.redirectUrl additionalParameters:requestParameters.additionalParameters preferEphemeralSession:requestParameters.preferEphemeralSession result:result exchangeCode:exchangeCode];
[self performAuthorization:serviceConfiguration clientId:requestParameters.clientId clientSecret:requestParameters.clientSecret scopes:requestParameters.scopes redirectUrl:requestParameters.redirectUrl additionalParameters:requestParameters.additionalParameters preferEphemeralSession:requestParameters.preferEphemeralSession result:result exchangeCode:exchangeCode defaultSystemBrowser:requestParameters.defaultSystemBrowser];
} else if (requestParameters.discoveryUrl) {
NSURL *discoveryUrl = [NSURL URLWithString:requestParameters.discoveryUrl];
[OIDAuthorizationService discoverServiceConfigurationForDiscoveryURL:discoveryUrl
Expand All @@ -169,7 +173,7 @@ -(void)handleAuthorizeMethodCall:(NSDictionary*)arguments result:(FlutterResult)
return;
}

[self performAuthorization:configuration clientId:requestParameters.clientId clientSecret:requestParameters.clientSecret scopes:requestParameters.scopes redirectUrl:requestParameters.redirectUrl additionalParameters:requestParameters.additionalParameters preferEphemeralSession:requestParameters.preferEphemeralSession result:result exchangeCode:exchangeCode];
[self performAuthorization:configuration clientId:requestParameters.clientId clientSecret:requestParameters.clientSecret scopes:requestParameters.scopes redirectUrl:requestParameters.redirectUrl additionalParameters:requestParameters.additionalParameters preferEphemeralSession:requestParameters.preferEphemeralSession result:result exchangeCode:exchangeCode defaultSystemBrowser:requestParameters.defaultSystemBrowser];
}];
} else {
NSURL *issuerUrl = [NSURL URLWithString:requestParameters.issuer];
Expand All @@ -182,12 +186,12 @@ -(void)handleAuthorizeMethodCall:(NSDictionary*)arguments result:(FlutterResult)
return;
}

[self performAuthorization:configuration clientId:requestParameters.clientId clientSecret:requestParameters.clientSecret scopes:requestParameters.scopes redirectUrl:requestParameters.redirectUrl additionalParameters:requestParameters.additionalParameters preferEphemeralSession:requestParameters.preferEphemeralSession result:result exchangeCode:exchangeCode];
[self performAuthorization:configuration clientId:requestParameters.clientId clientSecret:requestParameters.clientSecret scopes:requestParameters.scopes redirectUrl:requestParameters.redirectUrl additionalParameters:requestParameters.additionalParameters preferEphemeralSession:requestParameters.preferEphemeralSession result:result exchangeCode:exchangeCode defaultSystemBrowser:requestParameters.defaultSystemBrowser];
}];
}
}

- (void)performAuthorization:(OIDServiceConfiguration *)serviceConfiguration clientId:(NSString*)clientId clientSecret:(NSString*)clientSecret scopes:(NSArray *)scopes redirectUrl:(NSString*)redirectUrl additionalParameters:(NSDictionary *)additionalParameters preferEphemeralSession:(BOOL)preferEphemeralSession result:(FlutterResult)result exchangeCode:(BOOL)exchangeCode{
- (void)performAuthorization:(OIDServiceConfiguration *)serviceConfiguration clientId:(NSString*)clientId clientSecret:(NSString*)clientSecret scopes:(NSArray *)scopes redirectUrl:(NSString*)redirectUrl additionalParameters:(NSDictionary *)additionalParameters preferEphemeralSession:(BOOL)preferEphemeralSession result:(FlutterResult)result exchangeCode:(BOOL)exchangeCode defaultSystemBrowser:(BOOL)defaultSystemBrowser {
OIDAuthorizationRequest *request =
[[OIDAuthorizationRequest alloc] initWithConfiguration:serviceConfiguration
clientId:clientId
Expand All @@ -199,7 +203,7 @@ - (void)performAuthorization:(OIDServiceConfiguration *)serviceConfiguration cli
UIViewController *rootViewController =
[UIApplication sharedApplication].delegate.window.rootViewController;
if(exchangeCode) {
id<OIDExternalUserAgent> externalUserAgent = [self userAgentWithViewController:rootViewController useEphemeralSession:preferEphemeralSession];
id<OIDExternalUserAgent> externalUserAgent = [self userAgentWithViewController:rootViewController useEphemeralSession:preferEphemeralSession useDefaultSystemBrowser:defaultSystemBrowser];
_currentAuthorizationFlow = [OIDAuthState authStateByPresentingAuthorizationRequest:request externalUserAgent:externalUserAgent callback:^(OIDAuthState *_Nullable authState,
NSError *_Nullable error) {
if(authState) {
Expand All @@ -210,7 +214,7 @@ - (void)performAuthorization:(OIDServiceConfiguration *)serviceConfiguration cli
}
}];
} else {
id<OIDExternalUserAgent> externalUserAgent = [self userAgentWithViewController:rootViewController useEphemeralSession:preferEphemeralSession];
id<OIDExternalUserAgent> externalUserAgent = [self userAgentWithViewController:rootViewController useEphemeralSession:preferEphemeralSession useDefaultSystemBrowser:defaultSystemBrowser];
_currentAuthorizationFlow = [OIDAuthorizationService presentAuthorizationRequest:request externalUserAgent:externalUserAgent callback:^(OIDAuthorizationResponse *_Nullable authorizationResponse, NSError *_Nullable error) {
if(authorizationResponse) {
NSMutableDictionary *processedResponse = [[NSMutableDictionary alloc] init];
Expand All @@ -225,7 +229,10 @@ - (void)performAuthorization:(OIDServiceConfiguration *)serviceConfiguration cli
}
}

- (id<OIDExternalUserAgent>)userAgentWithViewController:(UIViewController *)rootViewController useEphemeralSession:(BOOL)useEphemeralSession {
- (id<OIDExternalUserAgent>)userAgentWithViewController:(UIViewController *)rootViewController useEphemeralSession:(BOOL)useEphemeralSession useDefaultSystemBrowser:(BOOL)useDefaultSystemBrowser {
if (useDefaultSystemBrowser) {
return [OIDExternalUserAgentIOSCustomBrowser CustomBrowserSafari];
}
if (useEphemeralSession) {
return [[OIDExternalUserAgentIOSNoSSO alloc]
initWithPresentingViewController:rootViewController];
Expand Down Expand Up @@ -333,7 +340,7 @@ - (void)performEndSessionRequest:(OIDServiceConfiguration *)serviceConfiguration

UIViewController *rootViewController =
[UIApplication sharedApplication].delegate.window.rootViewController;
id<OIDExternalUserAgent> externalUserAgent = [self userAgentWithViewController:rootViewController useEphemeralSession:false];
id<OIDExternalUserAgent> externalUserAgent = [self userAgentWithViewController:rootViewController useEphemeralSession:false useDefaultSystemBrowser:requestParameters.defaultSystemBrowser];


_currentAuthorizationFlow = [OIDAuthorizationService presentEndSessionRequest:endSessionRequest externalUserAgent:externalUserAgent callback:^(OIDEndSessionResponse * _Nullable endSessionResponse, NSError * _Nullable error) {
Expand Down
4 changes: 3 additions & 1 deletion flutter_appauth/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ name: flutter_appauth
description: This plugin provides an abstraction around the Android and iOS AppAuth SDKs so it can be used to communicate with OAuth 2.0 and OpenID Connect providers
version: 2.4.1
homepage: https://github.com/MaikuB/flutter_appauth/tree/master/flutter_appauth
publish_to: 'none' # Remove this line if you wish to publish to pub.dev

environment:
sdk: ">=2.12.0 <3.0.0"
Expand All @@ -10,7 +11,8 @@ environment:
dependencies:
flutter:
sdk: flutter
flutter_appauth_platform_interface: ^4.1.0
flutter_appauth_platform_interface:
path: ../flutter_appauth_platform_interface

flutter:
plugin:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ mixin AuthorizationParameters {

/// Whether to use an ephemeral session that prevents cookies and other browser data being shared with the user's normal browser session.
///
/// This property is only applicable to iOS versions 13 and above.
/// This property is only applicable to iOS versions 13 and above. This setting is only validated when [defaultSystemBrowser] is set to false.
bool? preferEphemeralSession;

String? responseMode;

/// Whether to open the default system browser outside the app.
///
/// This property is only applicable to iOS. Set this to true if you want to use the cookies/context of the system main browser (such as SSO flows). This setting will nullify [preferEphemeralSession].
bool? defaultSystemBrowser;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class AuthorizationRequest extends CommonRequestDetails
bool allowInsecureConnections = false,
bool preferEphemeralSession = false,
String? responseMode,
bool defaultSystemBrowser = false,
}) {
this.clientId = clientId;
this.redirectUrl = redirectUrl;
Expand All @@ -31,6 +32,7 @@ class AuthorizationRequest extends CommonRequestDetails
this.allowInsecureConnections = allowInsecureConnections;
this.preferEphemeralSession = preferEphemeralSession;
this.responseMode = responseMode;
this.defaultSystemBrowser = defaultSystemBrowser;
assertConfigurationInfo();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class AuthorizationTokenRequest extends TokenRequest
bool allowInsecureConnections = false,
bool preferEphemeralSession = false,
String? responseMode,
bool defaultSystemBrowser = false,
}) : super(
clientId,
redirectUrl,
Expand All @@ -36,5 +37,6 @@ class AuthorizationTokenRequest extends TokenRequest
this.promptValues = promptValues;
this.preferEphemeralSession = preferEphemeralSession;
this.responseMode = responseMode;
this.defaultSystemBrowser = defaultSystemBrowser;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class EndSessionRequest with AcceptedAuthorizationServiceConfigurationDetails {
String? issuer,
String? discoveryUrl,
AuthorizationServiceConfiguration? serviceConfiguration,
this.defaultSystemBrowser = false,
}) {
assert((idTokenHint == null && postLogoutRedirectUrl == null) ||
(idTokenHint != null && postLogoutRedirectUrl != null));
Expand All @@ -37,4 +38,9 @@ class EndSessionRequest with AcceptedAuthorizationServiceConfigurationDetails {
bool allowInsecureConnections;

final Map<String, String>? additionalParameters;

/// Whether to open the default system browser outside the app.
///
/// This property is only applicable to iOS.
final bool defaultSystemBrowser;
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ extension EndSessionRequestMapper on EndSessionRequest {
'issuer': issuer,
'discoveryUrl': discoveryUrl,
'serviceConfiguration': serviceConfiguration?.toMap(),
'defaultSystemBrowser': defaultSystemBrowser,
};
}
}
Expand Down Expand Up @@ -99,5 +100,6 @@ Map<String, Object?> _convertAuthorizationParametersToMap(
'promptValues': authorizationParameters.promptValues,
'preferEphemeralSession': authorizationParameters.preferEphemeralSession,
'responseMode': authorizationParameters.responseMode,
'defaultSystemBrowser': authorizationParameters.defaultSystemBrowser,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ void main() {
'allowInsecureConnections': false,
'preferEphemeralSession': false,
'promptValues': null,
'responseMode': null
'responseMode': null,
'defaultSystemBrowser': false,
})
],
);
Expand All @@ -48,7 +49,9 @@ void main() {
test('authorizeAndExchangeCode', () async {
await flutterAppAuth.authorizeAndExchangeCode(AuthorizationTokenRequest(
'someClientId', 'someRedirectUrl',
discoveryUrl: 'someDiscoveryUrl', loginHint: 'someLoginHint', responseMode: 'fragment'));
discoveryUrl: 'someDiscoveryUrl',
loginHint: 'someLoginHint',
responseMode: 'fragment'));
expect(
log,
<Matcher>[
Expand All @@ -69,7 +72,8 @@ void main() {
'authorizationCode': null,
'grantType': 'authorization_code',
'codeVerifier': null,
'responseMode': 'fragment'
'responseMode': 'fragment',
'defaultSystemBrowser': false,
})
],
);
Expand Down Expand Up @@ -176,6 +180,7 @@ void main() {
'issuer': null,
'discoveryUrl': 'someDiscoveryUrl',
'serviceConfiguration': null,
'defaultSystemBrowser': false,
})
]);
});
Expand Down