Authentication
DS Server protects its services with OAuth: an application requests an access token at /oauth/token with the client ID and client secret of a security profile, and sends the token with every request. When a token request fails, DS Server answers with status 400 and a JSON object whose error and error_description name the cause. When a request with a token is refused, it answers with 401 and an empty body. The problems below are ordered from the admin portal settings to the token and the requests that use it; the responses are those of DS Server 5.0.2.
Requests Work Without a Token
Requests to the Web API succeed, or reach the license check, without an Authorization header or with any token at all.
OAuth is switched off after a new installation: the Security Profiles page of the admin portal shows the switch OAuth disabled in red. As long as it is off, DS Server doesn't check tokens, and anyone who can reach the server can use it.
- Open the admin portal and select Security Profiles.
- Click the switch so that it shows OAuth enabled in green. The setting is saved at once.
- Send a request without a token and check that it now returns 401.
Enable OAuth describes the switch and when to leave OAuth off.
Requests Return 401 Unauthorized
With OAuth enabled, a request returns HTTP/1.1 401 Unauthorized with an empty body.
The response headers tell the cases apart:
WWW-Authenticate: Bearerin the response: the request had no token.- No
WWW-Authenticateheader: the request had a token that DS Server doesn't accept. The token is unknown, has expired, or belongs to a security profile whose expiry date has passed. For an expired profile,/oauth/tokenstill returns a token, but every request with it returns 401.
The DS Server log adds TXTextControl was not authenticated. Failure message: Access not granted. for a refused token, and TXTextControl was not authenticated. Failure message: OAuth authorization: No authorization header, access token query parameter or access token cookie found. for a request without a token.
- Send the token in the header
Authorization: Bearer <access token>, as the query parameteraccess_tokenor in a cookie namedaccess_token. - Request a new token when the old one has expired. The token response names its lifetime in seconds in
expires_in,"3600"in DS Server 5.0. - Open the security profile in the admin portal and clear its Expiry date, or set a later one. After the expiry date is cleared, the tokens of the profile are accepted again.
The Token Request Reports a Missing Authorization Header
POST /oauth/token returns 400 with:
{
"error": "invalid_request",
"error_description": "Missing authorization header."
}
For the client credentials grant type, DS Server expects the client ID and secret in an HTTP Basic Authorization header. Sending them only as the form fields client_id and client_secret isn't enough.
Send the credentials as Basic authorization, for example with the
--useroption of curl:curl POST 'http://localhost:5000/oauth/token' \ '<client id>:<client secret>' \ grant_type=client_credentialsSend the body as form data (
application/x-www-form-urlencoded). A JSON body returns405 Method Not Allowed.
The POST /oauth/token reference lists the parameters of each grant type.
The Token Request Says the Grant Type Isn't Allowed
POST /oauth/token returns 400 with:
{
"error": "unsupported_grant_type",
"error_description": "This security profile does not allow the specified grant type. (client_credentials)"
}
A Document Editor that you initialize in JavaScript with a client ID and secret shows nothing, and the browser console reports:
Could not retrieve OAuth token. Error: unsupported_grant_type, error description: This security profile does not allow the specified grant type. (client_credentials)
An ASP.NET Core application that uses the Document Editor or Document Viewer package without a RedirectUri shows this in place of the component:
Authorization Error
Exception: OAuth access token request failed. error: "unsupported_grant_type", error_description: "This security profile does not allow the specified grant type. (client_credentials)"
The client credentials grant type is off for each new security profile. It is used whenever the client ID and secret are sent directly for a token: by your own requests, by the ASP.NET Core packages without a RedirectUri, and by the Angular and React packages and TXTextControl.init with a client ID and secret.
- On the Security Profiles page of the admin portal, open the profile with its Edit profile icon.
- Turn on the switch Allow “Client Credentials” grant type and click Save.
In a browser component, the client credentials are part of the page and visible to every visitor. To keep them on your server, request the token there and pass only the access token to the component, as Client-Side Libraries describes. OAuth Grant Types explains the switch.
The Token Request Reports an Invalid Client Secret
POST /oauth/token returns 400 with:
{
"error": "invalid_client",
"error_description": "Invalid client secret."
}
The client secret doesn't belong to the client ID. For the authorization code grant type, the same error appears when the form field client_secret is missing.
- Open the security profile in the admin portal and copy the Client ID and the Client Secret with their copy buttons.
- For the authorization code grant type, send
client_id,client_secret,codeandredirect_urias form fields.
The Redirect URI Doesn't Match
GET /oauth/authorize returns 400 with the plain text:
Missing, invalid or mismatching redirection URI.
In an ASP.NET Core application that uses the Document Editor or Document Viewer package with a RedirectUri, the page shows the same text in place of the component:
Authorization Error
Exception: OAuth access token request failed. Missing, invalid or mismatching redirection URI.
The redirect URI of the request isn't in the list Authorized Redirect URIs of the security profile. A profile without any redirect URI shows an alert icon in the profile list, with the tooltip Profile has no redirect URIs defined.
- Copy the address of your application from the address bar of the browser, for example
https://localhost:44374. - Open the security profile, click + Add URI and enter the address followed by the path of the package's callback, for example
https://localhost:44374/textcontrol/documenteditor/auth/callback. ASP.NET Core lists the callback path of each package. - Click Save and reload the page of your application.
With a trial token on the Text Control trial server, leave out RedirectUri: the trial profile allows the client credentials grant type. See Trial Token.
The Admin Password Is Lost
The browser keeps asking for the credentials of the admin portal, and the /admin and /license endpoints of the Web API return 401 with WWW-Authenticate: Basic realm=Access to the Admin page.
The admin portal and these endpoints use the admin credentials with HTTP Basic authentication. After the password has been changed, only the new one works. Setting a password shorter than eight characters fails with New password must be at least 8 characters long.
DS Server keeps the admin password, the security profiles and the OAuth switch in the file Admin.db in its installation folder. Without the file, it starts like a new installation.
- Stop DS Server.
- Move Admin.db to a backup folder.
- Start DS Server. It creates a new Admin.db, and the credentials are
adminandadminagain. - Change the password, create the security profiles again and enable OAuth.
All security profiles and their client credentials are lost with the old file, so every application needs new credentials. Keep the backup until the new setup works; moving it back restores the old state.
The Log Mentions Authentication Servers
With OAuth enabled, the log of DS Server writes this line for each token that the server didn't issue itself:
OAuthTokenAuthenticationService.IsAuthorized called but no authentication servers are registered.
The line itself is informational. DS Server can ask other DS Server instances, registered as authentication servers, whether a token is valid. Without any registered server, only the tokens it issued itself are valid, and the line reports that there is no other server to ask. The request is then refused with 401, as Requests Return 401 Unauthorized describes. Authentication Servers describes when to register them.