DS Server

Authentication Servers

Topic

When several DS Server instances serve the same applications, for example behind a load balancer or in several regions, each instance checks access tokens against its own security profiles. A token issued by one instance is unknown to the others, and every instance would need a copy of every profile. Authentication servers solve this: an instance can register other DS Server instances as authentication servers and ask them whether a token is valid. Since version 3.1.0, you register them on the Authentication page of the admin portal or with the Web API.

How It Works

Take two instances: ds1 processes documents and has no security profiles, and auth holds the profiles of your applications. On ds1, you register auth as an authentication server.

 Application                      ds1 (OAuth enabled)              auth (security profiles)
     |                                  |                                  |
     |-- POST /oauth/token ------------>|-- client unknown: forwarded ---->|
     |                                  |<---------------- token issued ---|
     |<-- token issued by auth ---------|                                  |
     |                                  |                                  |
     |-- request with the token ------->|-- token unknown: is it valid? -->|
     |                                  |<----------------------- valid ---|
     |<-- result, processed by ds1 -----|                                  |
  • Tokens. When ds1 receives a request with a token that it didn't issue, it asks its registered authentication servers with POST /oauth/validatetoken. If one of them knows the token, ds1 processes the request; if none does, it answers with status 401.
  • Token requests. When POST /oauth/token or GET /oauth/authorize can't authorize a client with its own profiles, ds1 forwards the request to the authentication servers. An application can request its token from ds1 with the client ID and secret of a profile that exists only on auth, and ds1 returns the token that auth issued.
  • The work. Documents are processed by the instance that received the request. The authentication server only answers whether a token is valid.

The check applies to instances with OAuth enabled. On the authentication server, the OAuth switch doesn't matter for this: it answers for the tokens of its own profiles either way. A registration takes effect at once, without a restart.

Plan the Setup

The blog article DS Server: Announcing Distributed OAuth Authentication for Scalable Applications describes two arrangements:

SetupHowConsider
Central authentication serverOne instance holds all security profiles. Every other instance registers it as its authentication server and has no profiles of its own.You manage the profiles in one place. When the central instance can't be reached, the others refuse tokens they didn't issue themselves.
Distributed authentication serversSeveral instances hold the same profiles, and each registers the others.When one instance fails, applications still get tokens from the others. The tokens that the failed instance issued are no longer accepted, because only the issuing instance knows a token, even when another instance has a copy of the same profile. The profiles have to be copied to each authentication server, as Multiple Servers with Load Balancing describes.

An instance can register several authentication servers. A registered server that can't be reached doesn't block the others: a token that another registered server knows is still accepted.

Register an Authentication Server in the Portal

Sign in to the admin portal of the instance that should use the authentication server, ds1 in the example above.

  1. Click Authentication in the navigation bar, or the Authentication Servers tile on the welcome page. The Authentication Servers list is empty on a new installation.

    The Authentication page with an empty list of authentication servers

  2. Click + Register.

  3. On the Register Authentication Server form, enter a Name that identifies the server and its address in Authentication Server Url, such as https://auth.example.com. This is the service URL of the other DS Server instance, the address its admin portal and Web API answer at.

    The Register Authentication Server form

  4. Click Register. The list shows the server with its Name and Url.

    The Authentication page with one registered authentication server

To remove a server, click its delete icon (tooltip "Deregister Authentication Server") and confirm Are you sure you want to deregister the authentication server? with Deregister.

As long as no authentication server is registered, DS Server with OAuth enabled writes "OAuthTokenAuthenticationService.IsAuthorized called but no authentication servers are registered." to its log for each token that it didn't issue itself, before it refuses the request with status 401. The message is informational: the instance has no other server to ask.

Register an Authentication Server With the Web API

The administration Web API has endpoints for the registered servers since version 3.1.0. Like the other administration endpoints, they take the admin user name and password in a Basic Authorization header.

TaskRequestBody and answer
List the IDsGET /admin/authenticationserversReturns an array such as [1, 2]
Register a serverPOST /admin/authenticationservers{"name": "...", "serverUrl": "..."}; returns the new ID
Read a serverGET /admin/authenticationservers/{id}Returns {"name": "...", "serverUrl": "..."}
Change the URLPATCH /admin/authenticationservers/{id}/serverurlThe new URL as a JSON string
Deregister a serverDELETE /admin/authenticationservers/{id}None

This request registers auth on ds1:

curl --request POST 'https://ds1.example.com/admin/authenticationservers' \
    --user 'admin:<admin password>' \
    --header 'Content-Type: application/json' \
    --data-raw '{"name": "Central authentication server", "serverUrl": "https://auth.example.com"}'

DS Server answers with the ID of the registration, such as 1. An ID that doesn't exist gets status 404.

Register an Authentication Server With the Admin Package

The TXTextControl.DocumentServices.Admin package has a method for each endpoint. This console application registers auth on ds1 and lists the registered servers:

using TXTextControl.DocumentServices.Admin;

// Connect to the instance that should use the authentication server
Admin admin = new Admin("https://ds1.example.com", "<admin password>");

// Register the other instance
AuthenticationServer server = new AuthenticationServer()
{
    Name = "Central authentication server",
    ServerUrl = "https://auth.example.com"
};

int id = await admin.AddAuthenticationServer(server);

// List every registered authentication server
foreach (int serverId in await admin.GetAuthenticationServerIds())
{
    AuthenticationServer registered = await admin.GetAuthenticationServer(serverId);
    Console.WriteLine($"{serverId}: {registered.Name} ({registered.ServerUrl})");
}

The code works as follows:

  • AddAuthenticationServer registers the server described by Name and ServerUrl and returns the ID of the registration.
  • GetAuthenticationServerIds returns the IDs, and GetAuthenticationServer the name and URL of one registration. Take the ID from the list: the object that GetAuthenticationServer returns doesn't fill its ID.
  • UpdateServerUrl(id, url) changes the address, and DeleteAuthenticationServer(id) removes the registration.

The Endpoints for Tokens

Version 3.1.0 also added OAuth endpoints that DS Server instances use among each other and that help you test a setup.

EndpointWhat it does
POST /oauth/validatetokenTakes a token as a JSON string in the body and answers true if this instance issued it and it is valid, otherwise false. It doesn't ask the registered authentication servers.
GET /oauth/testAnswers 200 if a request with the token in the Authorization header, the access_token query parameter or the access_token cookie would be admitted, and 401 if not. It asks the registered authentication servers, and it answers 200 to any request when OAuth is disabled.
POST /authenticationserver/tokenIssues a token like POST /oauth/token, but without forwarding a failed request to the registered authentication servers
GET /authenticationserver/authorizeAuthorizes like GET /oauth/authorize, but without forwarding a failed request

To check a new setup, request a token from the authentication server and call GET /oauth/test on the other instance with it:

curl --include 'https://ds1.example.com/oauth/test' \
    --header 'Authorization: Bearer <token issued by auth>'

HTTP/1.1 200 OK means that ds1 accepts the token of auth. Without the registration, the same request gets HTTP/1.1 401 Unauthorized on an instance with OAuth enabled.

Next Steps