(Created page with "==Overview== Share-VDE exposes an OAuth 2.0 authentication system we call Identity Provider (IdP). It provides both interactive and programmatic authentication, and in this document we will focus on the latter. The IdP is hosted on the domain ip.svde.org. The programmatic authentication is achieved through a RESTful HTTP API covering either client-based and user-based authentication use cases. These are very similar authentication scenarios, indicating, though, diff...") |
No edit summary |
||
Line 99: | Line 99: | ||
--header 'Content-Type: application/x-www-form-urlencoded' \ | --header 'Content-Type: application/x-www-form-urlencoded' \ | ||
--data-urlencode 'client_id=sharevde-api-gateway' \ | --data-urlencode 'client_id=sharevde-api-gateway' \ | ||
--data-urlencode 'client_secret= | --data-urlencode 'client_secret=a_valid_secret' \ | ||
--data-urlencode 'grant_type=client_credentials' | --data-urlencode 'grant_type=client_credentials' | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 111: | Line 111: | ||
c2hhcmV2ZGUtYXBpLWdhdGV3YXk6MDU3NzlmYzItNzI5Yy00NmYyLTg2YWYtMTIzNTJkYTY5MmU2' \ | c2hhcmV2ZGUtYXBpLWdhdGV3YXk6MDU3NzlmYzItNzI5Yy00NmYyLTg2YWYtMTIzNTJkYTY5MmU2' \ | ||
--data-urlencode 'grant_type=password' \ | --data-urlencode 'grant_type=password' \ | ||
--data-urlencode 'username= | --data-urlencode 'username=a_valid_user' \ | ||
--data-urlencode 'password= | --data-urlencode 'password=a_valid_password' | ||
====Example - Authentication response==== | ====Example - Authentication response==== | ||
Line 207: | Line 207: | ||
--data-urlencode 'grant_type=refresh_token' \ | --data-urlencode 'grant_type=refresh_token' \ | ||
--data-urlencode 'client_id=my-app-id' \ | --data-urlencode 'client_id=my-app-id' \ | ||
--data-urlencode 'client_secret= | --data-urlencode 'client_secret=a_valid_client_secret' \ | ||
--data-urlencode 'refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCIgOiA...' | --data-urlencode 'refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCIgOiA...' | ||
====Example - User refresh token==== | ====Example - User refresh token==== | ||
curl --location --request POST ' | curl --location --request POST 'https://idp<nowiki/>.svde.org/auth/realms/ShareVDE/protocol/openid-connect/token' \ | ||
--header 'Content-Type: application/x-www-form-urlencoded' \ | --header 'Content-Type: application/x-www-form-urlencoded' \ | ||
--data-urlencode 'grant_type=refresh_token' \ | --data-urlencode 'grant_type=refresh_token' \ | ||
--data-urlencode 'client_id=my-app-id' \ | --data-urlencode 'client_id=my-app-id' \ | ||
--data-urlencode 'client_secret= | --data-urlencode 'client_secret=a_valid_client_secret' \ | ||
--data-urlencode 'username= | --data-urlencode 'username=a_valid_username' \ | ||
--data-urlencode 'password= | --data-urlencode 'password=a_valid_password' \ | ||
--data-urlencode 'refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCIgOiA...' | --data-urlencode 'refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCIgOiA...' | ||
Revision as of 09:21, 8 February 2024
Overview
Share-VDE exposes an OAuth 2.0 authentication system we call Identity Provider (IdP).
It provides both interactive and programmatic authentication, and in this document we will focus on the latter.
The IdP is hosted on the domain ip.svde.org.
The programmatic authentication is achieved through a RESTful HTTP API covering either client-based and user-based authentication use cases.
These are very similar authentication scenarios, indicating, though, different expectations.
Client authentication refers to those cases where an application needs to be authenticated in order to access common service features. This authentication guarantees the server on client’s genuinity, but no further, specific authentication is needed in this case.
On the other hand, user-based authentication binds a client authentication scenario with a specific user authentication.
Both scenarios rely on the server issuing an authentication token, used by a client to sign subsequent business requests.
Before diving into each authentication use case, let’s explore API operations.
Roles
The following table lists the roles defined in Share-VDE at time of writing. Endpoints are not publicly exposed, the caller is supposed to have at least a svde-reader role, which grants read permissions.
Name | Code | Description |
---|---|---|
Reader | svde-reader | Minimum level role which grants read capabilities on Share-VDE resources. |
Basic Editor | svde-editor-base | Base editing capabilities required for the Curation API (i.e., resources editing). Includes the Reader role. |
Advanced Editor | svde-editor-advanced | Advanced editing capabilities that allow full capabilities on Share-VDE resources. Includes the Basic Editor role. |
API operations
Obtain a new authentication token
The first request a client must make to authenticate with ShareVDE is the /token request.
In case of client authentication, you will need client credentials, i.e. a Client ID and a Client Secret issued by Share-VDE.
In case of user authentication, you will need client credentials as well as a username and password.
The request returns a JSON structure containing a new authentication token to be used in subsequent operations.
Request endpoint
HTTP Method | Endpoint |
---|---|
POST | /auth/realms/ShareVDE/protocol/openid-connect/token |
Authorization header
Authorization: Basic <authorization hash>
Here the Client ID and Client Secret issued by Share-VDE come into play.
The authorization hash is computed as follows:
Base64(client_id + “:” + client_secret)
This header must always be present for token requests, regardless of the client or user authentication use case.
Content-Type header
Content-Type: application/x-www-form-urlencoded
Request body
Key | Description | Value
(Client auth) |
Value (User auth) |
---|---|---|---|
grant_type | The kind of grant operation that is going to be requested to the server | client_credentials | password |
username | The user id to authenticate | Not applicable | <Provided by the user> |
password | The password to use | Not applicable | <Provided by the user> |
Example - Client authentication request
curl --location --request POST 'https://sit3-ip-base-svde.atcult.it/auth/realms/ShareVDE/protocol/openid-connect/token' \
--header 'Authorization: Basic c2hhcmV2ZGUtYXBpLWdhdGV3YXk6MDU3NzlmYzItNzI5Yy00NmYyLTg2YWYtMTIzNTJkYTY5MmU2' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=sharevde-api-gateway' \
--data-urlencode 'client_secret=a_valid_secret' \
--data-urlencode 'grant_type=client_credentials'
Example - User authentication request
curl --location --request POST \ 'https://ip.share-vde.org/auth/realms/ShareVDE/protocol/openid-connect/token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --header 'Referer: https://af4080f8fb8a.ngrok.io/' \ --header 'Authorization: Basic \ c2hhcmV2ZGUtYXBpLWdhdGV3YXk6MDU3NzlmYzItNzI5Yy00NmYyLTg2YWYtMTIzNTJkYTY5MmU2' \ --data-urlencode 'grant_type=password' \ --data-urlencode 'username=a_valid_user' \ --data-urlencode 'password=a_valid_password'
Example - Authentication response
{ "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ...", "expires_in": 300, "refresh_expires_in": 1800, "refresh_token": ”eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6IC...", "token_type": "bearer", "not-before-policy": 0, "session_state": "acb9a64f-5309-4536-9fb2-682fe48fd58d", "scope": "email profile svde-resource-read" }
Regardless of the client or user authentication scenario, the successful authentication response has the same structure. Let’s analyze its contents:
access_token
: the token to be used to sign subsequent business REST requests (see the example later in this document). It is digitally signed by the Share-VDE realm.
expires_in
: the token’s TTL (in seconds). After this number of seconds has passed since token emission, the token won’t be valid anymore, unless a refresh request is issued by the client.
refresh_expires_in
: the refresh token’s TTL. It represents indeed the time window (in seconds) within which the client can request the server-side session’s TTL extension. The new session’s TTL will be equal to the amount of seconds expressed with the expires_in member. After the number of seconds expressed by this member has passed, the session won’t be usable anymore.refresh_token
: the token to be used to sign the next refresh request (see the example later in this document).- token_type: the type of the issued token; for Share-VDE it will be “bearer”, meaning the token must be used in a “Authorization: Bearer” header.
not-before-policy
: a time-based revocation policy. The server allows administrators to specify a time and date where any session or token issued before that time and date is invalid. For Share-VDE such value will always be zero (i.e. the token is valid starting from the exact moment it is issued).session_state
: the session state id. By definition, a session is a continuous period of time during which an end-user or an application accesses a Relying Party relying on the authentication of the end-user performed by the Identity Provider.scope
: a space-separated list of strings, showing the scopes represented by the access_token.
Refresh an authentication token
Via the /token
request it is possible to request a new access token maintaining the same session_status
.
This objective is achieved with the use of the refresh_token
operation type (a.k.a grant type).
It is important to point out that access tokens have a usually short TTL and they often expire after only minutes. The additional refresh token that was transmitted by the client_credentials
or password
operations has a longer TTL and allows the client to obtain a new access token after it expires, maintaining the same session of the original scope.
With short-lived access tokens, things are made more secure and more scalable for the whole system.
Request endpoint
HTTP Method | Endpoint |
---|---|
POST | /auth/realms/ShareVDE/protocol/openid-connect/token |
Authorization header
Authorization: Basic <authorization hash>
The authorization hash is computed as follows:
Base64(client_id + “:” + client_secret)
Content-Type header
Content-Type: application/x-www-form-urlencoded
Request body
Key | Description | Value (client auth) | Value (user auth) |
---|---|---|---|
grant_type | The kind of grant operation that is going to be requested to the server | refresh_token | refresh_token |
username | The user id to authenticate | Not applicable | <Provided by the user> |
password | The password to use | Not applicable | <Provided by the user> |
client_id | The client id used in the Authorization header | <client_id> | <client_id> |
client_secret | The client secret used in the Authorization header | <client secret> | <client secret> |
refresh_token | The refresh_token value received with the previous “new token” or “refresh token” response | <taken from the previous request> | <taken from the previous request> |
Example - Client refresh token
curl --location --request POST 'https://ip.svde.org/auth/realms/ShareVDE/protocol/openid-connect/token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=refresh_token' \ --data-urlencode 'client_id=my-app-id' \ --data-urlencode 'client_secret=a_valid_client_secret' \ --data-urlencode 'refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCIgOiA...'
Example - User refresh token
curl --location --request POST 'https://idp.svde.org/auth/realms/ShareVDE/protocol/openid-connect/token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=refresh_token' \ --data-urlencode 'client_id=my-app-id' \ --data-urlencode 'client_secret=a_valid_client_secret' \ --data-urlencode 'username=a_valid_username' \ --data-urlencode 'password=a_valid_password' \ --data-urlencode 'refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCIgOiA...'
Example - Refresh response
{ "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICz...", "expires_in": 300, "refresh_expires_in": 1800, "refresh_token": ”eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwiaAkzmjsHdu...", "token_type": "bearer", "not-before-policy": 0, "session_state": "acb9a64f-5309-4536-9fb2-682fe48fd58d", "scope": "email profile svde-resource-read" }
The successful refresh token response has the same structure as the new token response. Refer to that section for a description of each field.
Example of a business request
The general principle is that both GraphQL API and REST api are protected by Share-VDE’s IdP.
We must use received access tokens to sign every request towards those two interfaces.
Let’s see how to perform a request towards the /api/graphql
endpoint.
ℹ | NOTE: Until the definitive Share-VDE environment will be available, instead of api.svde.org please use beta-base.svde.org. |
curl --location --request POST 'https://api.svde.org/api/graphql' \ --header 'Authorization: Bearer eyJhbGcIgOiAiSldUIiwia2lkIiA6ICJ5eDZhRjZtM3ZTZkdIO...' \ --header 'Content-Type: application/json' \ --data-raw '{"query":"{\n person(uri: \"https://share-vde.org/agents/201631288953646\") {\n uri\n preferredHeading\n occupations {\n uri\n language\n preferredHeading\n alternateHeadings\n }\n }\n}","variables":null,"operationName":null}'
Error responses
In case of errors, the Share-VDE’s authentication RESTful API responds with the following HTTP status codes:
400 | Malformed request. The request is incomplete or the payload is malformed. |
401 | Unauthorized. The authentication is possible but has failed or has not been provided yet. |
403 | Forbidden. The resource is available, but the authorization level is not sufficient in order to access it. |