Authentication
Once OAuth is enabled in the admin portal, every request to the DocumentProcessing Web API must carry an OAuth access token. A backend gets the token from DS Server itself with the client ID and client secret of a security profile, sends it in the Authorization header and requests a new one when it expires. The same steps apply to curl, to any HTTP client and to the .NET package TXTextControl.DocumentServices.DocumentProcessing, which runs them for you.
How Authentication Works
DS Server contains its own OAuth 2.0 server. An admin creates a security profile for each application in the admin portal, as Creating Security Profiles shows. The profile holds the credentials that your application exchanges for an access token:
| Part of the profile | Used for |
|---|---|
| Client ID and client secret | Requesting an access token at POST /oauth/token |
| Allow "Client Credentials" grant type | Lets a backend get a token with the client ID and secret alone; off by default |
| Authorized redirect URIs | The addresses DS Server may send an authorization code to, for the authorization code flow |
| Expiry date | Optional. Once it has passed, DS Server refuses every token of the profile |
Two grant types give your application a token:
- Client credentials. A backend, a script or a service sends the client ID and secret and receives an access token in one request. This is the flow for server-to-server calls, and the examples in this section use it. Enable Allow "Client Credentials" grant type in the profile first, as OAuth Grant Types shows.
- Authorization code. The client requests a code that DS Server sends to a registered redirect URI, and exchanges the code for an access token and a refresh token. It is meant for applications with a callback address, such as the ASP.NET Core client packages.
All endpoints sit below the service URL of your DS Server. It is http://localhost:5000 when DS Server runs on its own on the default port, and it contains the path of the IIS site behind IIS, such as https://yourdomain.com/DocumentServices. Architecture explains the parts behind the address. The samples below keep the service URL in the variable DS.
Request an Access Token
Send a POST request to /oauth/token with the form field grant_type=client_credentials. The client ID and the client secret go into an HTTP Basic Authorization header, which curl builds from --user:
DS=http://localhost:5000
curl POST "$DS/oauth/token" \
"<client ID>:<client secret>" \
grant_type=client_credentials
DS Server answers with a JSON object:
{
"access_token": "<access_token>",
"token_type": "Bearer",
"expires_in": "3600"
}
What the request and the response contain:
- The Basic header is required. The client ID and secret as the form fields
client_idandclient_secretalone are refused with400and"error_description": "Missing authorization header.". A request with both the header and the fields works. - The body is form data,
application/x-www-form-urlencoded, as--data-urlencodesends it. A JSON body is refused with405 Method Not Allowed. expires_inis the lifetime of the token in seconds, 3,600 seconds or one hour. DS Server returns it as a string.access_tokenis the value you send with every request to the Web API.
To keep the token in a shell variable for the next requests, extract it with the JSON processor jq:
TOKEN=$(curl POST "$DS/oauth/token" \
"<client ID>:<client secret>" \
grant_type=client_credentials | jq .access_token)
Send the Token With a Request
Pass the token in a Bearer authorization header. The request below converts document.docx to PDF, as Converting Documents explains:
base64 0 document.docx | jq . > document.json
curl POST "$DS/documentprocessing/document/convert?returnFormat=PDF" \
"Authorization: Bearer $TOKEN" \
"Content-Type: application/json" \
@document.json
DS Server also accepts the token in the access_token query parameter, for example ?returnFormat=PDF&access_token=<access_token>. Prefer the header: a query string ends up in server logs and browser histories.
A request without a token is answered with 401 Unauthorized and the header WWW-Authenticate: Bearer. An invalid token, or a token of a security profile whose expiry date has passed, also gets 401, with an empty body. Errors and Status Codes lists the other answers.
Renew the Token
A token is valid for the expires_in seconds of its response. Tokens outlive a restart of DS Server, but not the expiry date of their security profile: once that date has passed, every request with a token of the profile gets 401, although /oauth/token still issues new tokens.
Client credentials. Request a new token with the same call before the old one expires, or when a request answers
401. This grant type has no refresh token.Authorization code. The token response also contains a
refresh_token. Exchange it for a new access token and a new refresh token withgrant_type=refresh_token:curl POST "$DS/oauth/token" \ grant_type=refresh_token \ "refresh_token=<refresh_token>" \ "client_id=<client ID>" \ "client_secret=<client secret>"
Use the Authorization Code Flow
For an application that has a callback address, the authorization code flow keeps the client secret out of the first request:
Your application redirects to, or calls,
GET /oauth/authorizewithresponse_type=code, itsclient_id, aredirect_uriregistered in the security profile and astatevalue.DS Server redirects to the redirect URI with the parameters
codeandstate. It shows no sign-in or consent page of its own. A redirect URI that is not registered in the profile is refused with400and the text "Missing, invalid or mismatching redirection URI.".Your application sends the code to
/oauth/tokenas form fields:curl POST "$DS/oauth/token" \ grant_type=authorization_code \ "code=<code>" \ "client_id=<client ID>" \ "client_secret=<client secret>" \ "redirect_uri=https://your.app/callback"The response holds
access_token,token_type,expires_inandrefresh_token.
The ASP.NET Core packages of the Document Editor and the Document Viewer run this flow and provide the callback endpoints themselves, as ASP.NET Core lists them. The endpoints are described in GET /oauth/authorize and POST /oauth/token.
Authenticate With the .NET Package
TXTextControl.DocumentServices.DocumentProcessing requests the token for you. Pass the credentials in an OAuthSettings object when you create the DocumentProcessing instance:
using TXTextControl.DocumentServices.DocumentProcessing;
using TXTextControl.DocumentServices.DocumentProcessing.OAuth;
// Client ID and secret of a profile that allows the client credentials grant type
var oauthSettings = new OAuthSettings("<client ID>", "<client secret>");
// The constructor requests the access token from DS Server
var documentProcessing = new DocumentProcessing("http://localhost:5000", oauthSettings);
byte[] pdf = await documentProcessing.Convert(
await File.ReadAllBytesAsync("document.docx"), ReturnFormat.PDF);
The code works as follows:
OAuthSettingswith a client ID and a secret uses the client credentials grant type. A third argument, the redirect URI, is for the authorization code flow in an ASP.NET Core application; the package provides the callback at/textcontrol/documentprocessing/auth/callbackof your application.- The
DocumentProcessingconstructor requests the access token right away. Wrong credentials throw anAggregateExceptionthere, with the OAuth error in its message, such as"invalid_client"and"Invalid client secret.". - The class also has the static method
CreateInstanceAsync. In version 5.0.0 of the package, it requests an access token but doesn't send it with the requests that follow, so they fail with401when OAuth is enabled. The samples on these pages use the constructor. - Every method, such as
Convert, sends the token with its request. A refused request throws aServiceRequestException, whoseStatusCodeholds the HTTP status. RefreshAccessTokenrequests a new token with the refresh token of the authorization code flow. With client credentials, it throws an exception that says the grant type does not support refresh tokens; create a new instance to get a new token.
The classes are listed in the DocumentProcessing namespace of the .NET API.
When OAuth Is Disabled
The admin can switch OAuth off on the Security Profiles page of the admin portal, as Enable OAuth describes. A fresh installation starts with OAuth disabled. DS Server then checks no token at all: requests without a token, with a valid token or with an invalid one reach the endpoint alike.
Without OAuth, leave out the Authorization header, and create the .NET instance with the service URL only, new DocumentProcessing("http://localhost:5000"). Run DS Server this way only where the network or another application protects it, and enable OAuth before the server can be reached from outside.
Next Steps
- Converting Documents: the first request with a token, a document conversion.
- Creating Security Profiles: create the client ID and secret.
- OAuth Grant Types: allow the client credentials grant type for a profile.
- Errors and Status Codes: what a
401or400answer means.