# OAuth Grant Types

> Choose the authorization code or client credentials grant type of DS Server and request and refresh access tokens with /oauth/authorize and /oauth/token.

- **Product:** DS Server
- **Section:** Documentation
- **Kind:** Topic
- **Path:** DS Server > Administration and Settings > OAuth Grant Types
- **1970 words**
- **Web URL:** https://docs.textcontrol.com/ds-server/administration/oauth-grant-types/
- **LLMs URL:** https://docs.textcontrol.com/ds-server/administration/oauth-grant-types/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/ds-server/administration/oauth-grant-types/llms-full.txt

---

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](https://docs.textcontrol.com/ds-server/client-libraries/overview/#authorize-a-library) shows.

The blog article [DS Server User Authentication with OAuth: Authorization Code Flow vs. Client Credentials Flow](https://www.textcontrol.com/blog/2024/03/12/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

1. Sign in to the admin portal, click **Security Profiles** and open the profile with its edit icon.
2. Click the **Allow “Client Credentials” grant type** switch. It turns green.

    ![A security profile with two redirect URIs and the client credentials grant type allowed](https://docs.textcontrol.com/assets/img/ds-server/portal-client-credentials.221d7483.webp)
3. Click **Save**.

Without the switch, a client credentials request gets status 400 and this answer:

```json
{
  "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](https://docs.textcontrol.com/ds-server/reference/web-api/administration/securityprofiles-id-allowclientcredentialsgranttype/patch/llms-full.txt) 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:

```bash
curl --request POST 'http://localhost:5000/oauth/token' \
    --user '<client ID>:<client secret>' \
    --data-urlencode 'grant_type=client_credentials'
```

```json
{
  "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](https://docs.textcontrol.com/ds-server/reference/web-api/oauth/authorize/get/llms-full.txt) with the client ID and one of the profile's redirect URIs:

```text
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:

```text
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](https://docs.textcontrol.com/ds-server/reference/web-api/oauth/token/post/llms-full.txt). It sends the client secret, so this request runs on your server:

```bash
curl --request POST 'http://localhost:5000/oauth/token' \
    --data-urlencode 'grant_type=authorization_code' \
    --data-urlencode 'code=<code>' \
    --data-urlencode 'client_id=<client ID>' \
    --data-urlencode 'client_secret=<client secret>' \
    --data-urlencode 'redirect_uri=https://yourdomain.com/textcontrol/documenteditor/auth/callback'
```

```json
{
  "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](https://docs.textcontrol.com/ds-server/administration/security-profiles/#add-the-redirect-uris) 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:

```bash
curl --request POST 'http://localhost:5000/oauth/token' \
    --data-urlencode 'grant_type=refresh_token' \
    --data-urlencode 'refresh_token=<refresh token>' \
    --data-urlencode 'client_id=<client ID>' \
    --data-urlencode '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](https://docs.textcontrol.com/ds-server/administration/security-profiles/llms-full.txt): the redirect URIs and the other settings of a profile.
- [Enable OAuth](https://docs.textcontrol.com/ds-server/administration/oauth/llms-full.txt): make DS Server require the tokens.
- [OAuth](https://docs.textcontrol.com/ds-server/reference/web-api/oauth/llms-full.txt) in the Web API reference: every parameter of `/oauth/authorize` and `/oauth/token`.

---

## Nearby

- **Previous:** [Enable OAuth](https://docs.textcontrol.com/ds-server/administration/oauth/llms-full.txt)
- **Next:** [Authentication Servers](https://docs.textcontrol.com/ds-server/administration/authentication-servers/llms-full.txt)
