TF-624 Add AuthenticationClient for mobile/web platform to authenticate oidc
This commit is contained in:
@@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
import 'package:model/oidc/oidc_configuration.dart';
|
||||||
|
import 'package:model/oidc/token_id.dart';
|
||||||
|
import 'package:model/oidc/token_oidc.dart';
|
||||||
|
import 'package:tmail_ui_user/features/login/data/network/authentication_client/authentication_client_mobile.dart'
|
||||||
|
if (dart.library.html) 'package:tmail_ui_user/features/login/data/network/authentication_client/authentication_client_web.dart';
|
||||||
|
|
||||||
|
abstract class AuthenticationClientBase {
|
||||||
|
Future authenticateOidcOnBrowser(
|
||||||
|
String clientId,
|
||||||
|
String redirectUrl,
|
||||||
|
String discoveryUrl,
|
||||||
|
List<String> scopes);
|
||||||
|
|
||||||
|
Future<TokenOIDC> getTokenOIDC(
|
||||||
|
String clientId,
|
||||||
|
String redirectUrl,
|
||||||
|
String discoveryUrl,
|
||||||
|
List<String> scopes);
|
||||||
|
|
||||||
|
Future<TokenOIDC> refreshingTokensOIDC(
|
||||||
|
String clientId,
|
||||||
|
String redirectUrl,
|
||||||
|
String discoveryUrl,
|
||||||
|
List<String> scopes,
|
||||||
|
String refreshToken);
|
||||||
|
|
||||||
|
Future<bool> logoutOidc(TokenId tokenId, OIDCConfiguration config);
|
||||||
|
|
||||||
|
factory AuthenticationClientBase() => getAuthenticationClientImplementation();
|
||||||
|
}
|
||||||
+87
@@ -0,0 +1,87 @@
|
|||||||
|
|
||||||
|
import 'package:core/utils/app_logger.dart';
|
||||||
|
import 'package:flutter_appauth/flutter_appauth.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:model/oidc/oidc_configuration.dart';
|
||||||
|
import 'package:model/oidc/token_id.dart';
|
||||||
|
import 'package:model/oidc/token_oidc.dart';
|
||||||
|
import 'package:tmail_ui_user/features/login/data/extensions/authentication_token_extension.dart';
|
||||||
|
import 'package:tmail_ui_user/features/login/data/extensions/token_response_extension.dart';
|
||||||
|
import 'package:tmail_ui_user/features/login/data/network/authentication_client/authentication_client_base.dart';
|
||||||
|
import 'package:tmail_ui_user/features/login/domain/exceptions/authentication_exception.dart';
|
||||||
|
|
||||||
|
class AuthenticationClientMobile implements AuthenticationClientBase {
|
||||||
|
|
||||||
|
final FlutterAppAuth _appAuth;
|
||||||
|
|
||||||
|
AuthenticationClientMobile(this._appAuth);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<TokenOIDC> getTokenOIDC(String clientId, String redirectUrl,
|
||||||
|
String discoveryUrl, List<String> scopes) async {
|
||||||
|
final authorizationTokenResponse = await _appAuth.authorizeAndExchangeCode(
|
||||||
|
AuthorizationTokenRequest(
|
||||||
|
clientId,
|
||||||
|
redirectUrl,
|
||||||
|
discoveryUrl: discoveryUrl,
|
||||||
|
scopes: scopes,
|
||||||
|
preferEphemeralSession: true));
|
||||||
|
|
||||||
|
log('AuthenticationClientMobile::getTokenOIDC(): token: ${authorizationTokenResponse?.accessToken}');
|
||||||
|
|
||||||
|
if (authorizationTokenResponse != null) {
|
||||||
|
final tokenOIDC = authorizationTokenResponse.toTokenOIDC();
|
||||||
|
if (tokenOIDC.isTokenValid()) {
|
||||||
|
return tokenOIDC;
|
||||||
|
} else {
|
||||||
|
throw AccessTokenInvalidException();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw NotFoundAccessTokenException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> logoutOidc(TokenId tokenId, OIDCConfiguration config) async {
|
||||||
|
final endSession = await _appAuth.endSession(EndSessionRequest(
|
||||||
|
idTokenHint: tokenId.uuid,
|
||||||
|
postLogoutRedirectUrl: config.redirectUrl,
|
||||||
|
discoveryUrl: config.discoveryUrl
|
||||||
|
));
|
||||||
|
log('AuthenticationClientMobile::logoutOidc(): ${endSession?.state}');
|
||||||
|
return endSession?.state?.isNotEmpty == true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<TokenOIDC> refreshingTokensOIDC(String clientId, String redirectUrl,
|
||||||
|
String discoveryUrl, List<String> scopes, String refreshToken) async {
|
||||||
|
final tokenResponse = await _appAuth.token(TokenRequest(
|
||||||
|
clientId,
|
||||||
|
redirectUrl,
|
||||||
|
discoveryUrl: discoveryUrl,
|
||||||
|
refreshToken: refreshToken,
|
||||||
|
scopes: scopes));
|
||||||
|
|
||||||
|
log('AuthenticationClientMobile::refreshingTokensOIDC(): refreshToken: ${tokenResponse?.accessToken}');
|
||||||
|
|
||||||
|
if (tokenResponse != null) {
|
||||||
|
final tokenOIDC = tokenResponse.toTokenOIDC();
|
||||||
|
if (tokenOIDC.isTokenValid()) {
|
||||||
|
return tokenOIDC;
|
||||||
|
} else {
|
||||||
|
throw AccessTokenInvalidException();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw NotFoundAccessTokenException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future authenticateOidcOnBrowser(String clientId, String redirectUrl,
|
||||||
|
String discoveryUrl, List<String> scopes) {
|
||||||
|
return Future.value(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthenticationClientBase getAuthenticationClientImplementation() =>
|
||||||
|
AuthenticationClientMobile(Get.find<FlutterAppAuth>());
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:tmail_ui_user/features/login/data/network/authentication_client/authentication_client_base.dart';
|
||||||
|
import 'package:flutter_appauth_platform_interface/flutter_appauth_platform_interface.dart';
|
||||||
|
import 'package:model/oidc/oidc_configuration.dart';
|
||||||
|
import 'package:model/oidc/token_id.dart';
|
||||||
|
import 'package:model/oidc/token_oidc.dart';
|
||||||
|
|
||||||
|
import '../../utils/library_platform/app_auth_plugin/app_auth_plugin.dart';
|
||||||
|
|
||||||
|
class AuthenticationClientWeb implements AuthenticationClientBase {
|
||||||
|
|
||||||
|
final AppAuthWebPlugin _appAuthWeb;
|
||||||
|
|
||||||
|
AuthenticationClientWeb(this._appAuthWeb);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<TokenOIDC> getTokenOIDC(String clientId, String redirectUrl,
|
||||||
|
String discoveryUrl, List<String> scopes) async {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<bool> logoutOidc(TokenId tokenId, OIDCConfiguration config) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<TokenOIDC> refreshingTokensOIDC(String clientId, String redirectUrl,
|
||||||
|
String discoveryUrl, List<String> scopes, String refreshToken) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future authenticateOidcOnBrowser(String clientId, String redirectUrl,
|
||||||
|
String discoveryUrl, List<String> scopes) async {
|
||||||
|
await _appAuthWeb.authorizeAndExchangeCode(
|
||||||
|
AuthorizationTokenRequest(
|
||||||
|
clientId,
|
||||||
|
redirectUrl,
|
||||||
|
discoveryUrl: discoveryUrl,
|
||||||
|
scopes: scopes));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthenticationClientBase getAuthenticationClientImplementation() =>
|
||||||
|
AuthenticationClientWeb(Get.find<AppAuthWebPlugin>());
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
import 'package:flutter_appauth_platform_interface/flutter_appauth_platform_interface.dart';
|
||||||
|
|
||||||
|
class AppAuthWebPlugin extends FlutterAppAuthPlatform {}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
export 'app_auth_mobile_plugin.dart' if (dart.library.html) 'app_auth_web_plugin.dart';
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
export 'package:flutter_appauth_web/flutter_appauth_web.dart';
|
||||||
Reference in New Issue
Block a user