Skip to content

User-centric Authentication

This page describes the use of the APIs of the OIDC provider for the authentication part and of the VC service for issuing, revoking and verifying verifiable credentials. These APIs are integrated with the i3market wallet and the i3market Besu blockchain. These APIs are deployed and usable through the services deployed on the node https://identity1.i3-market.eu/

Endpoints:

OIDC Provider

Compared to traditional OIDC providers, in which users are saved in a centralized database, the i3-Market user management follows the the self-sovereign identity model. In this identity management model, all the users information is exclusively kept by users in their wallet applications. Authentication and authorization occurs through the selective disclosure of part of the user attributes.

Client Registration

The first step to use the OIDC provider is to register a new client in the provider. There is an easy procedure to do this. Using the GET /developers/login API with you receive an initial access token. It is necessary to authorize the API using the following credentials:

email: test@i3-market.eu, pass: i3market

Later, this initial access token has to be used as bearer token in the API POST /oidc/reg. This API creates a new client. The client parameters are specified in the body. The body of this API call should follow the following structure:

{
   "grant_types": [
     "authorization_code"
   ],
   "token_endpoint_auth_method": "none" // Put one of "none" (PKCE required), "client_secret_basic", "client_secret_jwt", "client_secret_post", "private_key_jwt",
   "redirect_uris": [
     "https://client.example.org/callback",
     "https://client.example.org/callback2"
   ],
   "post_logout_redirect_uris": [
       "https://client.example.org/oidc/logout/cb" 
    ]
   "client_name": "MyCLientExample",
   "id_token_signed_response_alg": "EdDSA"
}

The response from this API contains the information that you will need to save and use to configure your OIDC library and then use the provider. You can use any standard OIDC library. Few example are: - https://www.npmjs.com/package/oidc-client - https://www.passportjs.org/

Authentication and Authorization

Well, now that you've created your client it's time to authenticate and authorize! Through the OIDC provider it is possible to implement the authorization code flow + PKCE flow. More information at this link. An important aspect of configuring a proper authentication flow is to correctly specify the scope parameter. In particular, it must contain the following claims: - openid: Mandatory for the Open ID Connect standard. It returns the sub field of the id token, and its value is the user did. - vc: It adds the field vero able claims into the id token. Useful when the Open ID Connect Provider wants to check any information about the vero able claims asked.

Compared to the standard scope of Open ID Connect, the scopes added are vc and vce. On the other hand, the standard email scope, which returns the user's email, is not present. There are two different types of scopes: - vc:vc_name: It asks the user for the specific verifiable claim vc name. It is optional, so the user can decide whether to append it or not. If the issuer of the verifiable claim is not trusted, it will be added into untrusted verifiable claims array of the id token. - vce:vc_name: It asks the user for the essential verifiable claim with name: vc name. It is mandatory, so if the user does not provide it or the issuer is untrusted, the login and consent process will be cancelled.

The authorization code flow involves calling two different APIs. La prima è la GET /auth. You can have a look to the Swagger references of the deployed instance here.

As you can see, this first API returns an HTML page as a response. This page is the login page to be rendered by the user's browser. This means that the user must be redirected to this page via a redirect. Under the hood, this page contains scripts that allow pairing with the wallet. In particular, if a valid pairing is not detected, an automatic procedure is activated. A form is then shown in which the user must copy a code generated through the UI of the i3-Market desktop wallet. Once the pairing code has been entered correctly, the procedure continues automatically and a notification will appear in the wallet to allow the disclosure of the credentials.

The second API is the POST /token. You can have a look to the swagger references here. The POST /token is required to exchange an authorization code (previously generated by the GET /auth). As a result it provides an access_token and an id_token, which contains the verifiable credentials revealed during authentication. These credentials contain information about the user.

Logout

To destroy a session and disconnect a user, the following url must be redirected:

https://<OIDC_URL>/oidc/session/end?post_logout_redirect_uri=<POST_LOGOUT_REDIRECT_URL>&client_id=<CLIENT_ID>
Example

https://identity1.i3-market.eu/release2/oidc/session/end?post_logout_redirect_uri=https%3A%2F%2Fwww.google.com&client_id=ybB4dEEIuEu9CeAmYwrJO

Troubleshooting

An effective method of debugging is to inspect the database of the OIDC provider. In fact, it is possible to see the clients created, the tokens issued, the active sessions in order to understand if something is not configured correctly. The OIDC provider has a MongoDB database where it saves information about sessions and clients. This DB is deployed as a microservice on a docker container. As a first step you need to inspect the container with the following command:

docker exec -it <CONTAINER_ID> /bin/sh
Then connect to the mongo database:
mongo -u oidp -p <DB_PASS> --authenticationDatabase admin <DB_NAME>

It is possible to see which are the collections present in the db with the following command:

var collections = db.getCollectionNames(); print(collections);
In particular, the logged collections are the following:

accesstoken, account, authorizationcode, client, initialaccesstoken, interaction, registrationaccesstoken, replaydetection, session

It is possible to log all the database collections and see all the data inside it with the following command:

var collections = db.getCollectionNames();
for(var i = 0; i< collections.length; i++) {    
    db.getCollection(collections[i]).find().forEach(printjson);
}

It is possible to export the database by performing a dump with the following command:

docker exec -i <MONGO_CONTAINER_ID> /bin/bash -c "PGPASSWORD=<DB_PASS> pg_dump --username <DB_USER> <DB_NAME>" > /dump.sql`

Verifiable Credential Service

This service manages verifiable credentials, allowing through APIs to issue, verify, revoke verifiable credentials in the W3C standard. Since authentication and authorization takes place through the selective detection of user attributes (i.e., verifiable credentials), a service is therefore necessary that allows the issuance, revocation and verification. This service acts as an "issuer" role in the self-sovereign identity model. Read more here.

Issue a credential

This APIs produces an HTML page that must be displayed on a browser. It is therefore necessary to redirect the user at the url of this API. The generated HTML page contains a script that communicates with the i3market wallet, which must be running on localhost:8000. Following the rendering of this page, a notification will appear on the wallet asking you to select the identity (DID) on which to save the verifiable credential. After selecting it, it automatically generates the credential and sends it back to the i3market wallet. The wallet will present a new notification asking if you want to accept the credential. Upon acceptance, the credential will be saved and viewable in the wallet.

Endpoint:

GET /issue/{credential}/callbackUrl/{callbackUrl}

  • The {credential} parameter is a JSON that represent the verifiable credential paylod encoded as a URL. An example of a credentials payload can be:

    { 
      consumer: true
    }
    
    You can encode this payload as a url in this way encodeURIComponent(JSON.stringify({ consumer: true }), obtaining the string %7B%22consumer%22%3Atrue%7D, that is has to be passed as parameter.

  • The {callbackUrl} parameter is a URL encoded as a URL. E.g., https://i3m-marketplace.eu will become %22https%3A%2F%2Fi3m-marketplace.eu%22.

Revoke a credential

This API takes a verifiable credential as input in the body, calculates the hash and registers it in the credential registry, on the i3market Besu blockchain.

Endpoint:

POST /revoke

With the following body

{
  "credentialJwt": "string"
}

Swagger references here.

Verify a credential

This API checks whether a credential in JWT format is registered in the revocation registry. The JWT of the verifiable credential and optionally the DID of the revoker you want to verify must be passed in the body. If the credentialIssuer, i.e. the revoker, it is not specified, it will be checked whether the issuer of the verifiable credential has revoked the credential or not. This way you can check if the credential has been revoked from a specific DID or not.

Endpoint:

POST /verify

With the following body

{
  "credentialJwt": "string",
  "credentialIssuer": "string"
}

Swagger references here.


Last update: 2022-06-30
Created: 2022-04-06
Back to top