Skip to content

Commit b08a01d

Browse files
authored
Merge pull request #65 from AFASSoftware/Authorization-pages-update
Updated authentication docs with OAuth
2 parents b0cd062 + c474433 commit b08a01d

2 files changed

Lines changed: 223 additions & 52 deletions

File tree

markdownpages/profit/en/authentication.md

Lines changed: 111 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,55 +4,140 @@ author: CLN
44
date: 2024-06-28
55
tags: tokens, jwt, bearer, oauth, access
66
---
7-
The AFAS Profit REST API uses static tokens that you include in the http authentication header of your request. These static tokens are created in the [`App Connector`](./concepts#app-connector) in Profit. An AFAS administrator with access to the Profit environment can create a token.
87

9-
> A token is unique to one environment and linked to a user. The permissions of this user will affect the permissions of the token.
8+
## Introduction
109

11-
The AFAS Profit REST API uses an authentication header to authenticate requests (the header is only used for authentication). To use this API, you always need to provide this header. In this description, you will learn How-To apply the token. Creating the token is done by the AFAS administrator or, if you have access to AFAS Profit, you can do it yourself. To do this, follow the steps in [Creating App Connectors](https://help.afas.nl/help/NL/SE/120718.htm).
10+
The AFAS Profit REST API supports two authentication methods:
11+
1. Classic token
12+
2. OAuth
13+
1. Client credentials flow
14+
2. Authorization code flow with PKCE
1215

13-
> TLS 1.2 is mandatory for all requests.
16+
Which method is used depends on the settings of the [App Connector](https://docs.afas.help/profit/en/concepts#app-connector) that is being used.
1417

15-
## Format and conversion
1618

17-
This is an example format of a token as generated in AFAS Profit:
19+
## Classic token
20+
21+
This method uses static tokens which you include in the HTTP Authorization header of all your requests. A token is unique to a single environment and is linked to a user. The permissions of that user affect the rights of the token.
22+
23+
The AFAS administrator creates the token, or if you have access to AFAS Profit you can create it yourself. Follow the steps in [Eigen app connector inrichten in vogelvlucht](https://help.afas.nl/help/NL/SE/120718.htm).
24+
25+
TLS 1.2 is required for all requests.
26+
27+
28+
### Format and conversion
29+
30+
A classic token as generated in AFAS Profit looks like this:
1831

1932
``` xml
2033
<token><version>1</version><data>949C1A9CD9AE4797950D94F55A7A4D056770472D4963CB9A8D3800BEE0CCE6A2</data></token>
2134
```
2235

23-
To use this token, you must convert it to **Base64**. After conversion, the token might look like this:
24-
`PHRva2VuPjx2ZXJzaW9uPjE8L3ZlcnNpb24+PGRhdGE+QURFMzcwQkU4REFGNDBEMEExN0ZGQjkxNEU0MjY3NUU5OTk4QzJENTQ2QTJGNEZBM0U0RjNBQkZBODY3Qjk2RjwvZGF0YT48L3Rva2VuPg==`
36+
To use this token in requests you must convert it to Base64. After conversion the token looks for example like this:
2537

26-
Example token conversion:
27-
28-
```csharp
29-
string token = await GetKeyVaultSecretAsync(keyVaultUri, secretName);
30-
string base64AfasToken = Convert.ToBase64String(Encoding.UTF8.GetBytes(token));
38+
``` xml
39+
PHRva2VuPjx2ZXJzaW9uPjE8L3ZlcnNpb24+PGRhdGE+QURFMzcwQkU4REFGNDBEMEExN0ZGQjkxNEU0MjY3NUU5OTk4QzJENTQ2QTJGNEZBM0U0RjNBQkZBODY3Qjk2RjwvZGF0YT48L3Rva2VuPg==
3140
```
3241

33-
## Applying token
3442

35-
Use the token in the http request header with an `AfasToken` prefix. Use the `Authorization` header with the token value `AfasToken PHRva2VuPjx2ZXJzaW9uPjE8L3ZlcnNpb04+PGRhdGE+QURFMzcwQkU4REFGNDBEMEExN0ZGQjkxNEU0MjY3NUU5OTk4QzJENTQ2QTJGNEZBM0U0RjNBQkZBODY3Qjk2RjwvZGF0YT48L3Rva2VuPg==`
43+
### Applying the token
3644

37-
``` bash
38-
curl -X GET "https://12345.rest.afas.online/ProfitRestServices/ProfitVersion" \
39-
-H "Accept: application/json" \
40-
-H "Authorization: AfasToken PHRva2VuPjx2ZXJzaW9uPjE8L3ZlcnNpb04+PGRhdGE+QURFMzcwQkU4REFGNDBEMEExN0ZGQjkxNEU0MjY3NUU5OTk4QzJENTQ2QTJGNEZBM0U0RjNBQkZBODY3Qjk2RjwvZGF0YT48L3Rva2VuPg=="
45+
Use the token in the HTTP request header with an `AfasToken` prefix. Use the `Authorization` header with the token value:
46+
47+
``` xml
48+
AfasToken PHRva2VuPjx2ZXJzaW9uPjE8L3ZlcnNpb24+PGRhdGE+QURFMzcwQkU4REFGNDBEMEExN0ZGQjkxNEU0MjY3NUU5OTk4QzJENTQ2QTJGNEZBM0U0RjNBQkZBODY3Qjk2RjwvZGF0YT48L3Rva2VuPg==
4149
```
50+
**Note**: Handle the token carefully as it provides access to sensitive data. Follow best practices when storing and managing the token and consider having your integration reviewed by an external security expert to address potential vulnerabilities.
51+
52+
53+
### Generating a token for a user via OTP
54+
55+
AFAS provides the option to use a One Time Password (OTP) to obtain a token. This is useful in scenarios where users must register themselves in an application.
56+
57+
58+
### Unauthorized
59+
60+
If the token is invalid or not applied correctly you will receive an HTTP 401 response. Request a new token or validate that you convert the token correctly. Use the tooling on [connect.afas.nl](https://connect.afas.nl) to validate that you are making the request correctly.
61+
62+
63+
64+
## OAuth
65+
66+
Within the OAuth protocol we support two flow types:
67+
1. Client credentials flow
68+
2. Authorization code flow with PKCE
69+
70+
71+
### Client credentials flow
72+
73+
The Client Credentials Flow is primarily used for server-to-server communication where there is no direct involvement of an end user. This flow is ideal for applications that need access to resources on their own behalf rather than on behalf of a user. It is suitable for situations where an application requires access to APIs to perform background tasks, such as syncing data or running batch jobs.
74+
75+
When an app connector uses the Client Credentials Flow, an 'OAuth client id' and an 'OAuth client secret' are created. The OAuth client secret is provided once during creation and cannot be retrieved afterwards.
76+
77+
#### Steps to access the API
78+
79+
To access the API, follow these steps:
80+
1. Obtain an access token
81+
1. Call the [token endpoint](#token-endpoint) (POST) with the following information in the body:
82+
1. grant_type: client_credentials
83+
2. client_id: `<fill in client id>`
84+
3. client_secret: `<fill in client secret>`
85+
2. In the response of this call you will find the following fields:
86+
1. access_token: the access token you must add to the Authorization header.
87+
2. refresh_token: for the client credentials flow this is always "null".
88+
3. token_type: Bearer
89+
4. expires_in: validity of the access token in seconds.
90+
3. Use the access token
91+
1. Copy the access token, prefix it with 'Bearer', and add it to your Authorization header.
92+
93+
94+
### Authorization code flow with PKCE
95+
96+
The Authorization Code Flow with PKCE is ideal for web applications that need to obtain access to resources on behalf of a user. The process starts with user authentication and authorization, where the user logs in and grants permission. An authorization code is then issued, which can be exchanged for an access token. This flow provides a secure way to access data from external services because it requires the user's involvement before access is granted.
97+
98+
99+
#### Steps to access the API
42100

43-
> **Note:** Handle the token with care, as it provides access to sensitive data. Ensure that you follow best practices for storing and managing the token and consider having your integration reviewed by an external security expert to address potential vulnerabilities.
101+
To access the API via the Authorization Code Flow, follow these steps:
102+
1. Obtain an authorization code
103+
1. Redirect the user to the [authorization endpoint](#authorization-endpoint) with the following parameters:
104+
1. response_type: code
105+
2. client_id: `<fill in client id>`
106+
3. redirect_uri: `<fill in redirect URI>`
107+
4. scope: `<fill in desired scopes>`
108+
5. state: `<optional unique value to protect against CSRF>`
109+
6. code_challenge: `<fill in codeChallenge>`
110+
7. code_challenge_method: `<fill in codeChallenge method>`
111+
2. The user logs in and grants permission. After granting permission the user is redirected back to the provided redirect_uri with an authorization code.
112+
2. Exchange the authorization code for an access token
113+
1. Call the [token endpoint](#token-endpoint) (POST) with the following information in the body:
114+
1. grant_type: authorization_code
115+
2. code: `<replace with obtained authorization code>`
116+
3. redirect_uri: `<fill in redirect URI>`
117+
4. client_id: `<fill in client id>`
118+
5. client_secret: `<fill in client secret>`
119+
6. code_verifier: `<fill in code verifier>`
120+
3. In the response of this call you will find the following fields:
121+
1. access_token: the access token you must add to the Authorization header.
122+
2. refresh_token: a token that can be used to obtain a new access token.
123+
3. token_type: Bearer
124+
4. expires_in: validity of the access token in seconds.
125+
3. Use the access token
126+
1. Copy the access token, prefix it with 'Bearer', and add it to your Authorization header.
44127

45-
## Unauthorized and Forbidden
128+
### Token endpoint
129+
Production: https://`<omgevingsnummer>`.rest.afas.online/ProfitRestServices/oauth/token
46130

47-
When the token is not valid or not correctly applied, you will receive an HTTP 401 response. Request a new token or validate whether you correctly convert the token. Use the tools on [connect.afas.nl](https://connect.afas.nl/) to validate if you correctly execute the request.
131+
Accept: : https://`<omgevingsnummer>`.restaccept.afas.online/ProfitRestServices/oauth/token
48132

49-
You will receive a forbidden message when an IP restriction applies to the App Connector. These IP restrictions are managed in the AFAS environment. Report this to the AFAS administrator of the environment you are connecting to and request to adjust it with your IP address.
133+
Test: https://`<omgevingsnummer>`.resttest.afas.online/ProfitRestServices/oauth/token
50134

51-
## Generate token for user via OTP
135+
### Authorization endpoint
136+
Production: https://`<omgevingsnummer>`.rest.afas.online/ProfitRestServices/oauth/authorize
52137

53-
AFAS offers the option to use a [One Time Password (OTP)](../../apidoc/en/Inrichting#post-/OtpRequest) instead of a token. This is useful in situations where users need to register themselves in an application.
138+
Accept: https://`<omgevingsnummer>`.restaccept.afas.online/ProfitRestServices/oauth/authorize
54139

55-
The OTP option offers a way to retrieve a token without sharing this via an external tool or email for example.
140+
Test: https://`<omgevingsnummer>`.resttest.afas.online/ProfitRestServices/oauth/authorize
56141

57142
### Read more
58143

0 commit comments

Comments
 (0)