authenticate method

Future<String> authenticate(
  1. String audience, [
  2. AuthenticationOptions? options
])

Authenticates the ServiceAccount against the provided audience (or issuer) to fetch an access token. To authenticate with special options, use the options parameter.

The function returns an access token that can be sent to authenticate any request as the given service account. The access token is valid for 60 minutes.

Errors

This method may fail when:

  • The key in the service account is not a valid PEM encoded RSA private key.
  • When the audience (issuer) is not reachable.
  • When any error in the request happens.
  • When the response status code is not 200 OK.
  • When the response cannot be parsed as valid JSON.

Examples

Just authenticate the service account against ZITADEL:

final sa = ServiceAccount.fromJson(json);
final token = await sa.authenticate('https://issuer.zitadel.ch');

Authenticate the service account against ZITADEL with ZITADEL API access:

final sa = ServiceAccount.fromJson(json);
final token = await sa.authenticate(
  'https://issuer.zitadel.ch',
  AuthenticationOptions(apiAccess: true));

Implementation

Future<String> authenticate(String audience,
    [AuthenticationOptions? options]) async {
  options ??= AuthenticationOptions();

  final discoveryResponse = await get(
    Uri.parse(_discoveryEndpoint(options.discoveryEndpoint ?? audience)),
    headers: {'accept': 'application/json; charset=UTF-8'},
  );
  final issuerJson = jsonDecode(utf8.decode(discoveryResponse.bodyBytes));
  final tokenEndpoint = issuerJson['token_endpoint'];
  final jwt = _getSignedJwt(audience);

  final response = await post(
    Uri.parse(tokenEndpoint),
    headers: {'accept': 'application/json; charset=UTF-8'},
    body: {
      'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer',
      'assertion': jwt,
      'scope': options.createScopes(),
    },
  );

  if (response.statusCode > 299) {
    throw Exception(
        'An error occurred. Status Code: ${response.statusCode}.');
  }

  final json = jsonDecode(utf8.decode(response.bodyBytes));

  return json['access_token'];
}