Manage OAuth 2.0 Clients
aqueduct auth command line tool creates OAuth 2.0 client application identifiers and inserts them into an application's database. To use this tool, you must use ManagedAuthStorage<T> and
your database must be contain the tables to support it (see this guide for more details).
Exchanging a username and password for an authorization token requires a registered client identifier. A token belongs to both the authenticating user and the client application. Clients are represented by instances of ManagedClient from
aqueduct/managed_auth. Authenticating clients must provide their client ID (and client secret, if applicable) in the Authorization header when requesting access tokens.
An OAuth 2.0 client must have a string identifier that uniquely identifies the client. For example,
com.food_app.mobile may be a client identifier for the mobile applications for some 'Food App'.
To create a simple OAuth 2.0 client, the following command line utility can be run:
aqueduct auth add-client \ --id com.food_app.mobile \ --connect postgres://user:[email protected]:5432/food_app
connect option identifies the database for the application, which this tool will connect to and insert a record into the ManagedClient database table. The identifier is provided through the id option.
When making requests to client authenticated endpoints (those protected with Authorizer.basic), the client secret is omitted from the authorization header. The string to base64 encode is
clientID:, where the colon (
:) is required. For example, to generate an authorization header in Dart for a public client:
var clientID = "com.foobar.xyz"; var clientCredentials = new Base64Encoder().convert("$clientID:".codeUnits); var header = "Basic $clientCredentials";
An OAuth 2.0 client is confidential if it has a client secret. Client secrets can be provided with the
aqueduct auth add-client \ --id com.food_app.mobile \ --secret myspecialsecret \ --connect postgres://user:[email protected]:5432/food_app
Client secrets are hashed (many times) with a randomly generated salt before they are stored. Therefore, their actual value must be stored securely elsewhere. (We use LastPass, for example.)
To allow the authorization code flow (provided by AuthCodeController), a client must have a redirect URI. This is the URI that an authenticating user's browser will be redirected to after entering their username and password. A client must be a confidential client to have a redirect URI.
aqueduct auth add-client \ --id com.food_app.mobile \ --secret myspecialsecret \ --redirect-uri https://someapp.com/callback \ --connect postgres://user:[email protected]:5432/food_app
If an application is using OAuth 2.0 scopes, a client can have scopes that it allows tokens to have access to. This allows scopes to be restricted by the client they are authenticating with.
aqueduct auth add-client \ --id com.food_app.mobile \ --secret myspecialsecret \ --allowed-scopes 'scopeA scopeB scopeC.readonly' \ --connect postgres://user:[email protected]:5432/food_app
Scopes are space-delimited and must be enclosed in quotes so that your shell will treat the entire string as one value.
Scope may be set after a client has already been created with
aqueduct auth set-scope:
aqueduct auth set-scope \ --id com.food_app.mobile \ --scopes 'scopeA scopeC' \ --connect postgres://user:[email protected]:5432/food_app
aqueduct commands that send commands to a database, the
connect option can be replaced by a
database.yaml file in the project directory with the following format:
username: "user" password: "password" host: "host" port: 5432 databaseName: "my_app"