OAuth Grant Types
An application gets an access token from DS Server in one of two ways, called grant types in OAuth 2.0: the authorization code flow, which every security profile supports, or the client credentials flow, which a profile allows only when you switch it on. Which one fits depends on where the client secret would be: on your server, or in code that a browser downloads. Read on to choose a grant type, set up the security profile for it and request tokens with either flow.
Compare the Grant Types
| Authorization code | Client credentials | |
|---|---|---|
| How the token is requested | The application asks GET /oauth/authorize for a code, which DS Server sends to a registered redirect URI; the application's server exchanges the code and the client secret for a token | The application sends the client ID and the client secret to POST /oauth/token and receives a token directly |
| Security profile needs | The redirect URI under Authorized Redirect URIs | Allow “Client Credentials” grant type switched on |
| Refresh token | Yes | No |
| Client secret | Stays on your server | Stays on your server only if the request is made there; in browser code, every visitor can read it |
| Used by | The ASP.NET Core packages when OAuthSettings.RedirectUri is set | The ASP.NET Core packages without RedirectUri, the Angular and React components and the Document Editor script when they get a client ID and secret; your own backend services |
| Default | Available for every profile | Off for every new profile |
Use the authorization code flow for web applications. Use client credentials for machine-to-machine calls from your server, such as a service that converts documents with the DocumentProcessing Web API, where no browser ever sees the secret. Browser components that get the client ID and secret directly use client credentials too, which exposes the secret to every visitor: in production, request the token on your server and pass it to the component, as the Client-Side Libraries Overview shows.
The blog article DS Server User Authentication with OAuth: Authorization Code Flow vs. Client Credentials Flow compares the two flows with C# code for both.
Allow the Client Credentials Grant Type
Sign in to the admin portal, click Security Profiles and open the profile with its edit icon.
Click the Allow “Client Credentials” grant type switch. It turns green.

Click Save.
Without the switch, a client credentials request gets status 400 and this answer:
{
"error": "unsupported_grant_type",
"error_description": "This security profile does not allow the specified grant type. (client_credentials)"
}
The Web API equivalent is PATCH /admin/securityprofiles/{id}/allowclientcredentialsgranttype with the JSON body true, and in the TXTextControl.DocumentServices.Admin package, UpdateAllowClientCredentialsGrantType(id, true).
Request a Token With Client Credentials
Send the client ID and the client secret of the profile as HTTP Basic credentials and grant_type=client_credentials as form data:
curl POST 'http://localhost:5000/oauth/token' \
'<client ID>:<client secret>' \
'grant_type=client_credentials'
{
"access_token": "<access token>",
"token_type": "Bearer",
"expires_in": "3600"
}
The token is valid for 3,600 seconds, one hour. Request a new one when it expires. The client ID and secret have to be in the Authorization header: sent only as the form fields client_id and client_secret, the request gets status 400 with "Missing authorization header." The body has to be form data (application/x-www-form-urlencoded), not JSON.
Request a Token With an Authorization Code
The authorization code flow has two requests. First, the application sends the browser, or its own HTTP client, to GET /oauth/authorize with the client ID and one of the profile's redirect URIs:
http://localhost:5000/oauth/authorize?response_type=code&client_id=<client ID>&redirect_uri=https://yourdomain.com/textcontrol/documenteditor/auth/callback&state=<state>
DS Server checks the client ID and the redirect URI and redirects at once to the redirect URI with the code and the state value you sent. There is no sign-in or consent page:
HTTP/1.1 302 Found
Location: https://yourdomain.com/textcontrol/documenteditor/auth/callback?code=<code>&state=<state>
A redirect URI that is not listed in the profile gets status 400 and the text "Missing, invalid or mismatching redirection URI."
Second, the code at the redirect URI exchanges the code for a token with POST /oauth/token. It sends the client secret, so this request runs on your server:
curl POST 'http://localhost:5000/oauth/token' \
'grant_type=authorization_code' \
'code=<code>' \
'client_id=<client ID>' \
'client_secret=<client secret>' \
'redirect_uri=https://yourdomain.com/textcontrol/documenteditor/auth/callback'
{
"access_token": "<access token>",
"token_type": "Bearer",
"expires_in": "3600",
"refresh_token": "<refresh token>"
}
The ASP.NET Core packages run both steps for you: they send the request to /oauth/authorize and handle the redirect at the callback path of the component, which is why that path has to be listed in the profile. Creating Security Profiles lists the callback paths of the Document Editor, the Document Viewer and DocumentProcessing.
Renew a Token With the Refresh Token
The refresh token gets a new access token without another redirect:
curl POST 'http://localhost:5000/oauth/token' \
'grant_type=refresh_token' \
'refresh_token=<refresh token>' \
'client_id=<client ID>' \
'client_secret=<client secret>'
The answer has the same form, with a new access token and a new refresh token.
Get the Token in the Redirect
GET /oauth/authorize also accepts response_type=token, the implicit flow of OAuth 2.0. DS Server then puts the access token itself into the redirect, as ?access_token=<access token>&token_type=Bearer&expires_in=3600&state=<state>, without a code, a client secret or a refresh token. The token appears in the address of the redirect, so prefer response_type=code.
Next Steps
- Creating Security Profiles: the redirect URIs and the other settings of a profile.
- Enable OAuth: make DS Server require the tokens.
- OAuth in the Web API reference: every parameter of
/oauth/authorizeand/oauth/token.