Skip to content

Aqueduct Authorization and Authentication Snippets

Enable OAuth 2.0

import 'package:aqueduct/aqueduct.dart';
import 'package:aqueduct/managed_auth.dart';

class AppChannel extends ApplicationChannel {
  AuthServer authServer;
  ManagedContext context;

  @override
  Future prepare() async {
    final dataModel = new ManagedDataModel.fromCurrentMirrorSystem();
    final psc = new PostgreSQLPersistentStore(
        "username",
        "password",
        "localhost",
        5432
        "my_app");

    context = new ManagedContext(dataModel, psc);

    final delegate = new ManagedAuthDelegate<User>(context);
    authServer = new AuthServer(delegate);
  }

  @override
  Controller get entryPoint {
    final router = Router();
    router.route("/auth/token").link(() => AuthController(authServer));  
    return router;
  }
}

Add OAuth 2.0 Clients to Database

aqueduct auth add-client \
  --id com.app.test \
  --secret supersecret \
  --allowed-scopes 'profile kiosk:location raw_db_access.readonly' \
  --connect postgres://username:password@localhost:5432/my_app

Require OAuth 2.0 Scope to Access Routes

import 'package:aqueduct/aqueduct.dart';
import 'package:aqueduct/managed_auth.dart';

class AppChannel extends ApplicationChannel {
  AuthServer authServer;
  ManagedContext context;

  @override
  Future prepare() async {
    final dataModel = ManagedDataModel.fromCurrentMirrorSystem();
    final psc = PostgreSQLPersistentStore(
        "username",
        "password",
        "localhost",
        5432
        "my_app");

    context = new ManagedContext(dataModel, psc);

    final delegate = ManagedAuthDelegate<User>(context);
    authServer = AuthServer(delegate);
  }

  @override
  Controller get entryPoint {
    router.route("/auth/token").link(() => AuthController(authServer));

    router
      .route("/profile")
      .link(() => Authorizer.bearer(authServer, scopes: ["profile.readonly"]))
      .link(() => ProfileController(context));
  }
}

class ProfileController extends ResourceController {
  ProfileController(this.context);

  final ManagedContext context;

  @Operation.get()
  Future<Response> getProfile() async {
    final id = request.authorization.ownerID;
    final query = new Query<User>(context)
      ..where((u) => u.id).equalTo(id);

    return new Response.ok(await query.fetchOne());
  }
}

Basic Authentication

import 'package:aqueduct/aqueduct.dart';

class AppChannel extends ApplicationChannel {
  @override
  Controller get entryPoint {
    final router = new Router();
    router
      .route("/profile")
      .link(() => Authorizer.basic(PasswordVerifier()))
      .linkFunction((req) async => new Response.ok(null));

    return router;
  }
}

class PasswordVerifier extends AuthValidator {
  @override
  FutureOr<Authorization> validate<T>(AuthorizationParser<T> parser, T authorizationData, {List<AuthScope> requiredScope}) {
    if (!isPasswordCorrect(authorizationData)) {
      return null;
    }

    return Authorization(null, authorizationData.username, this);
  }
}

Add OAuth 2.0 Authorization Code Flow

import 'package:aqueduct/aqueduct.dart';
import 'package:aqueduct/managed_auth.dart';

class AppChannel extends ApplicationChannel {
  AuthServer authServer;
  ManagedContext context;

  @override
  Future prepare() async {
    final dataModel = ManagedDataModel.fromCurrentMirrorSystem();
    final psc = PostgreSQLPersistentStore(
        "username",
        "password",
        "localhost",
        5432
        "my_app");

    context = new ManagedContext(dataModel, psc);

    final delegate = new ManagedAuthDelegate<User>(context);
    authServer = new AuthServer(delegate);
  }  

  @override
  Controller get entryPoint {
    final router = new Router();

    router.route("/auth/token").link(() => AuthController(authServer));  

    router.route("/auth/code").link(() => AuthCodeController(authServer, delegate: this));

    return router;
  }

  Future<String> render(AuthCodeController forController, Uri requestUri, String responseType, String clientID,
      String state, String scope) async {
    return """
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>

<body>
<div class="container">
    <h1>Login</h1>
    <form action="${requestUri.path}" method="POST">
        <input type="hidden" name="state" value="$state">
        <input type="hidden" name="client_id" value="$clientID">
        <input type="hidden" name="response_type" value="$responseType">
        <div class="form-group">
            <label for="username">User Name</label>
            <input type="text" class="form-control" name="username" placeholder="Please enter your user name">
        </div>
        <div class="form-group">
            <label for="password">Password</label>
            <input type="password" class="form-control" name="password" placeholder="Please enter your password">
        </div>
        <button type="submit" class="btn btn-success">Login</button>
    </form>
</div>
</body>

</html>
    """;    
  }
}