aaf_rapid_connect 1.0.1 copy "aaf_rapid_connect: ^1.0.1" to clipboard
aaf_rapid_connect: ^1.0.1 copied to clipboard

Australian Access Federation Rapid Connect Service Provider (SP)

example/example.dart

// Example

import 'dart:io';

import 'package:aaf_rapid_connect/aaf_rapid_connect.dart';
import 'package:woomera/woomera.dart';

//################################################################
// Constants

const port = 8080;

// Details about this Service Provider

const name = 'Test SP';
const callbackUrlPath = '/auth/aaf'; // POST handler: implemented by this server

const issuer = 'https://rapid.test.aaf.edu.au'; // defined by AAF
const audience = 'https://service-provider.example.com'; // provided to reg.
const secret = 'abcdefghijklmnopqrstuvwxyz012345'; // provided to reg.

// Redirect URL is issued by AAF after registration.
const redirectUrl =
    'https://rapid.test.aaf.edu.au/jwt/authnrequest/auresearch/...';

/*
// For testing with the QCIF's Rapid Connect Test Harness
const redirectUrl2 =
    'http://localhost:18080/rapidAAF/idp/?'
    'iss=https%3A%2F%2Frapid.test.aaf.edu.au&'
    'aud=https%3A%2F%2Fservice-provider.example.com&'
    'secret=abcdefghijklmnopqrstuvwxyz012345&'
    'callback=http%3A%2F%2Flocalhost%3A8080%2Fauth%2Faaf';
*/

//################################################################
// There are three steps to implement a Service Provider.

// 1. Use the details from the registration.

ServiceProvider sp = sp = ServiceProvider(issuer, audience, secret,
    name: name,
    redirectUrl: redirectUrl,
    allowedClockSkew: const Duration(minutes: 2));

// 2. Redirect the browser to the redirect URL, when requiring authentication.

Future<Response> handleLoginPage(Request req) async =>
    ResponseBuffered(ContentType.html)
      ..status = HttpStatus.ok
      ..write('''
<html lang="en">
  <head>
    <title>Example Service Provider</title>
  </head>
  <body>
    <h1>Example Service Provider</h1>

    <p><a href="${HEsc.attr(sp.redirectUrl)}">Sign in with AAF</a></p>
  </body>
</html>
''');

// 3. Handle the the "assertion" parameter in the callback HTTP POST request.

Future<Response> handleAafCallback(Request req) async {
  final assertion = req.postParams!['assertion'];
  stdout.writeln('Assertion: $assertion');

  try {
    final attrs = ClaimStandard(sp.authenticate(assertion));
    return _successful(attrs);
  } on AafException catch (e) {
    stdout.writeln('Assertion rejected: $e'); // For more details use logging.

    // For security, do not reveal to client why it failed.
    return _failed('Assertion was not valid.');
  }
}

Response _successful(ClaimStandard attr) {
  final resp = ResponseBuffered(ContentType.html)
    ..status = HttpStatus.ok
    ..write('''
<html lang="en">
<head><title>Successful</title></head>
<body>
  <h1>Sign in successful</h1>
  <table>
''');

  for (final k in attr.attributes.keys) {
    final v = attr.attributes[k];
    resp.write('<tr><th>${HEsc.text(k)}</th><td>${HEsc.text(v)}</td>\n');
  }

  resp.write('''
  </table>
  <p><a href="/">Home</a></p>
</body>
</html>
''');

  return resp;
}

Response _failed(String message) => ResponseBuffered(ContentType.html)
  ..status = HttpStatus.badRequest
  ..write('''
<html lang="en">
<head><title>Failed</title></head>
<body>
  <h1>Failed</h1>
  <p>${HEsc.text(message)}</p>
  <p><a href="/">Home</a></p>
</body>
</html>
''');

//################################################################

void main() async {
  final server = Server()
    ..bindAddress = InternetAddress.loopbackIPv4
    ..bindPort = port;

  server.pipelines.first
    ..get('~/', handleLoginPage)
    ..post('~/auth/aaf', handleAafCallback);

  stdout.writeln('Listening on ${server.bindAddress} port ${server.bindPort}');

  await server.run();
}
0
likes
130
pub points
7%
popularity

Publisher

verified publisherhoylen.com

Australian Access Federation Rapid Connect Service Provider (SP)

Repository (GitHub)
View/report issues

Documentation

API reference

License

BSD-3-Clause (LICENSE)

Dependencies

jaguar_jwt, logging

More

Packages that depend on aaf_rapid_connect