authenticate function
The authentication function
Implementation
Future<Map> authenticate(
Uri issuerUri, List<String> scopes, BuildContext context) async {
/// Platform type parameter
String platformType;
/// Re-direct URIs
String redirUrl;
List redirUriList;
/// Authentication method
String authMethod;
/// Authentication response
Credential authResponse;
/// Output data from the authentication
Map authData;
/// Check the platform
if (currPlatform.isWeb()) {
platformType = 'web';
} else if (currPlatform.isAppOS()) {
platformType = 'mobile';
} else {
platformType = 'desktop';
}
/// Get issuer metatada
Issuer issuer = await Issuer.discover(issuerUri);
/// Get end point URIs
String regEndpoint = issuer.metadata['registration_endpoint'];
String tokenEndpoint = issuer.metadata['token_endpoint'];
var authMethods = issuer.metadata['token_endpoint_auth_methods_supported'];
if (authMethods is String) {
authMethod = authMethods;
} else {
if (authMethods.contains('client_secret_basic')) {
authMethod = 'client_secret_basic';
} else {
authMethod = authMethods[1];
}
}
if (platformType == 'web') {
redirUrl = authManager.getWebUrl();
redirUriList = [redirUrl];
} else {
redirUrl = 'http://localhost:$_port/';
redirUriList = ['http://localhost:$_port/'];
}
/// Dynamic registration of the client (our app)
var regResponse =
await clientDynamicReg(regEndpoint, redirUriList, authMethod, scopes);
/// Decode the registration details
var regResJson = jsonDecode(regResponse);
/// Generating the RSA key pair
Map rsaResults = await genRsaKeyPair();
var rsaKeyPair = rsaResults['rsa'];
var publicKeyJwk = rsaResults['pubKeyJwk'];
///Generate DPoP token using the RSA private key
String dPopToken =
genDpopToken(tokenEndpoint, rsaKeyPair, publicKeyJwk, "POST");
final String _clientId = regResJson['client_id'];
final String _clientSecret = regResJson['client_secret'];
var client = Client(issuer, _clientId, clientSecret: _clientSecret);
if (platformType != 'web') {
/// Create a function to open a browser with an url
Future<void> urlLauncher(String url) async {
if (!await launchUrl(Uri.parse(url))) {
throw Exception('Could not launch $url');
}
}
/// create an authenticator
var authenticator = oidc_mobile.Authenticator(
client,
scopes: scopes,
port: _port,
urlLancher: urlLauncher,
redirectUri: Uri.parse(redirUrl),
popToken: dPopToken,
);
/// starts the authentication + authorisation process
authResponse = await authenticator.authorize();
/// close the webview when finished
/// closing web view function does not work in Windows applications
if (platformType == 'mobile') {
//closeWebView();
closeInAppWebView();
}
} else {
///create an authenticator
var authenticator =
authManager.createAuthenticator(client, scopes, dPopToken);
var oidc = authManager.getOidcWeb();
var callbackUri = await oidc.authorizeInteractive(
context: context,
title: 'authProcess',
authorizationUrl: authenticator.flow.authenticationUri.toString(),
redirectUrl: redirUrl,
popupWidth: 700,
popupHeight: 500);
var regResponse = Uri.parse(callbackUri).queryParameters;
authResponse = await authenticator.flow.callback(regResponse);
}
/// The following function call first check if the existing access token
/// is expired or not.
/// If its not expired then returns the token data as a token object
/// If expired then run the refresh token and get a new token and
/// returns the new token data as a token object
var tokenResponse = await authResponse.getTokenResponse();
String? accessToken = tokenResponse.accessToken;
/// Generate the logout URL
final _logoutUrl = authResponse.generateLogoutUrl().toString();
/// Store authentication data
authData = {
'client': client,
'rsaInfo': rsaResults,
'authResponse': authResponse,
'tokenResponse': tokenResponse,
'accessToken': accessToken,
'idToken': tokenResponse.idToken,
'refreshToken': tokenResponse.refreshToken,
'expiresIn': tokenResponse.expiresIn,
'logoutUrl': _logoutUrl
};
return authData;
}