OAuth 2.0 Flow


You can obtain the credentials to call the APIs in your private area. We implement two of the standard OAuth 2.0 flows: client credentials and authorization code.

How to choose the right flow for your needs?

  • you must choose authorization code when the user is into your application, and can insert his Mediobanca Premier credentials
  • you must choose client credentials when the user is not logged into your application (as the PSD2 directive states, there's a daily limit to this type of calls)

You can find more information about the OAuth2.0 standard here

Note that every call to external-api.mediobancapremier.io domain, included the OAuth handshake APIs, must be executed with mutual TLS using your QWAC certificate

Authorization code

If you need to call an API which requires the authorization of the user, you must choose the authorization code flow to obtain an access token. The flow is described in the following diagram.

OAuth 2.0 Authorization Code Flow

What are the required steps to perform this type of authentication?

  • Register to the developer portal
  • Request a new application with grant type = authorization_code
  • You'll be given a credential couple (client_id + client_secret)
  • Follow the flow as written here
  • You'll receive the access token and the refresh token (if expected)
  • Now you can call Mediobanca Premier APIs!

Authorization code steps

Here's and example of the needed requests to obtain an access token in curl format. You can invoke the /auth/oauth/v2/token API either with application/json or application/x-www-form-urlencoded content type. Optionally, you can use the state parameter as defined in the OAuth2.0 RFC; you can add it to the authorize request and it will be returned as a query parameter in the callback URL to your application, together with the authorization code.

Since the connection is secure, you have to add the external-api.mediobancapremier.io certificates (in the following example, the certificate chain is in the external-api.mediobancapremier.io.pem file).

Please notice that the login APIs are executed directly on Mediobanca Premier website: in fact, you, as a third party provider, should only propagate the redirect returned by the /authorize API to the browser, and the actual login (and the consent phase) will be executed on a page on mediobancapremier.com domain. At the end of the login verification, the Mediobanca Premier login page will redirect to your callback URL (configured when you requested your client_id). Then, the service exposed on your callback URL will have to call the /token API.

We show here the Login and the Consent requests only as an example to better understand the complete process.

Authorize request
curl --cacert external-api.mediobancapremier.io.pem \
  --cert tpp-qwac.crt --key tpp-qwac.key \
  -X GET \
  -H 'Date: Tue, 20 Aug 2019 10:17:38 GMT' \
  -H 'Postman-Token: 4c89fe1c-6b93-41df-a7d0-1a372bc4fa95' \
  -H 'Signature: keyId="<TPP_APP_NAME>",algorithm="rsa-sha256",headers="(request-target) tpp-request-id date",signature="mg2w72PImUPBEb4KYQP7AM5LW/NXTezGQu8n+oWEy7QU8vvO707+t24eNEAortQZ0h71rKSZCyhu6qCPN3WLFX/SFEk5tWwV6K8azN6Jm6ORalux6s9ZVqcxYNr4tQCDEdaqKlfFkrHSYqEoIYqYBEzzqggIOnVaLvaQUbxk1RceneivDUMEwzZKKPb3ZEm/DT54tyS3+qUohW38XcwtHtDSGNQVqNaDf06igNqTZKsP7rbAg4IwkcbZuq2N1NOrogpsBQ3XhHBZCnXxaxagFEdHcol1BmWzZL5h0Uxf0qnjGez+5DKbYoTGnskJoG/Dc78dJiBlIHKKTrEFFtyZJiWNJSQd/Cbx/zfAI7xjjF15cfUn2NP3zmV0ykSvKmaPQJWp5MpzWluQ7g9/+58nD4XpR4ULVgTIdIDjo+F2BLPGD3/xZwB+W3DM75Vr9zK6+i2bnVEpyb3JV5ZdNQ/qWrpREAuxYQvmpt6kLiTBCLjqxWlzh6LLMZEYuHaY1IXQq9/xpSJ9SACKQUyOqMAQNSc6i7dfVRbvSZTfCHtWUdPIxveBuLnHEl9qqxjnd8ZX2XR6njLV2TLwgHGJW04KhyS15fZ3SMIrxSNmSVZQN68PCbOD86TONsIbtRZJSYdR6bo9ndcKVMcuQMOY/iKxiKmCokdTmNkIwBuz6bTxIlI="' \
  -H 'TPP-Request-ID: 3006ef78-8b31-467a-b97e-2f8481004a01' \
  'https://external-api.mediobancapremier.io/auth/oauth/v2/authorize?response_type=code&client_id=<CLIENT_ID>&redirect_uri=<CALLBACK_URL>&state=<YOUR_OPTIONAL_STATE>'
Authorize response
< HTTP/1.1 302 Found
< Server: Apache-Coyote/1.1
< Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS,HEAD
< Access-Control-Allow-Headers: Content-Type
< Strict-Transport-Security: max-age=16070400; includeSubDomains
< X-Frame-Options: Deny
< Location: https://clienti.mediobancapremier.com/auth/oauth/v2/authorize/login?action=display&sessionID=<SESSION_ID>&sessionData=<SESSION_DATA>
< cb-apitrack-id: 5478152593
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 0
< Date: Tue, 12 Feb 2019 14:53:35 GMT
Login request
curl --cacert clienti.mediobancapremier.com.pem \
      -X POST \
      https://clienti.mediobancapremier.com/login \
      -H 'content-type: application/x-www-form-urlencoded' \
      -d 'user=<USER_ID>&pin=<USER_PIN>&action=login&sessionID=<SESSION_ID>&sessionData=<SESSION_DATA>&extLoginAndConsent=on'
Login response
< HTTP/1.1 302 Found
< Server: Apache-Coyote/1.1
< Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS,HEAD
< Access-Control-Allow-Headers: Content-Type
< Strict-Transport-Security: max-age=16070400; includeSubDomains
< X-Frame-Options: Deny
< location: https://clienti.mediobancapremier.com/oauth/consent-page/?sessionID=<SESSION_ID>&sessionData=<SESSION_DATA>
< cb-apitrack-id: 5504891511
< Content-Type: text/xml
< Content-Length: 0
< Date: Tue, 12 Feb 2019 15:13:48 GMT
Consent request
curl --cacert clienti.mediobancapremier.com.pem \
      -X POST \
      https://clienti.mediobancapremier.com/oauth/consent \
      -H 'content-type: application/x-www-form-urlencoded' \
      -d 'action=consent&sessionData=<SESSION_DATA>&sessionID=<SESSION_ID>'
Consent response
< HTTP/1.1 302 Found
< Server: Apache-Coyote/1.1
< Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS,HEAD
< Access-Control-Allow-Headers: Content-Type
< Strict-Transport-Security: max-age=16070400; includeSubDomains
< X-Frame-Options: Deny
< location: https://<YOURDOMAIN>/path/to/your/callback?code=<AUTHORIZATION_CODE>&state=<YOUR_OPTIONAL_STATE>
< cb-apitrack-id: 5504891511
< Content-Type: text/xml
< Content-Length: 0
< Date: Tue, 12 Feb 2019 15:13:48 GMT
Get token request
curl --cacert external-api.mediobancapremier.io.pem \
  --cert tpp-qwac.crt --key tpp-qwac.key \
  -X POST \
  -H 'Date: Tue, 20 Aug 2019 10:18:04 GMT' \
  -H 'Digest: SHA-256=UCiwgJXql+GKnCx3im0bs58j6sEQUxPfnvJEeBgaF/Q=' \
  -H 'Postman-Token: 7254f980-23a6-4429-806a-4fc79ddc3157' \
  -H 'Signature: keyId="<TPP_APP_NAME>",algorithm="rsa-sha256",headers="(request-target) digest tpp-request-id date",signature="K5Pb/mQ0S2ye8jBQZq73bR6mgmxVeIfdcXbRxFVxFcrzstvnm2Ju+96A2fcWshSsfYKnB3uuhm2rStwvROBjhnhdFGxPj/eYP+GXzNj3BmxNQTXMJtYFnjLGdOuVW1tNczlaOhus7dhumiKs/EttEwzTQJjVAEAHwJykuS7UjzBpKUJyFy3aXhrftAj9Jds0alrx7C6X5Md33sGB1Sa/CCJeCxSHNaaTFXzjwi5ILbqMR2ShRpn8eVPn3lpmKBJCVKMoWY/KjwhEtnVwL2rKzvko5zAVANDlEvnSGd5Hpvw4vg1Qpl84LpUhllJK2u6MhnwN9N6u4/qwW0yLwL6e6P1v09WW9wYfy2/jwgEzQAUORl5DfqKN5UoCR8Vmmju8XBugItYRm4BekorRmJab1v//6W9cqJpjG/mLiay3tbf28Hwm6UezdqkeSVMOpKpDu+2PR5uEvNinrBrHT9ha+f+VDfoSlzu/7uEvL5oeucpahVJ10w2E6DTjYBIMsm9Oax4YoXCL2gvz9Wd7RoqvIn6qrQ2cqVE7v3pF5RhDnd9kLDy7L+2e5U2tWHEwNhTszOP7Oigr2CSDeaCxX7Xp7744iGYV1YfHOILkdR/xNXebjdB4U4+FzhDWPjiYrMmsDbTQRPLbiUnk3R08e8qEp+ooaLlw6j4MFhmThjHuZ7s="' \
  -H 'TPP-Request-ID: 71f362d4-21b2-4669-95c2-baa5e1770901' \
  https://external-api.mediobancapremier.io/auth/oauth/v2/token \
  -H 'content-type: application/json' \
  -d '{
    "code":"<AUTHORIZATION_CODE>",
    "client_id":"<CLIENT_ID>",
    "client_secret":"<CLIENT_SECRET>",
    "grant_type":"authorization_code",
    "redirect_uri":"<TPP_CALLBACK_URL>"
    }'

Please note that the redirect_uri parameter is mandatory by OAuth RFC (see https://tools.ietf.org/html/rfc6749#section-4.1) and it must contain the same uri specified in the authorization request

Get token response
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS,HEAD
< Access-Control-Allow-Headers: Content-Type
< cb-apitrack-id: 4067327926
< Cache-Control: no-store
< Pragma: no-cache
< Content-Type: application/json
< Content-Length: 366
< Date: Tue, 12 Feb 2019 16:06:27 GMT
< Connection: close
< Strict-Transport-Security: max-age=16070400; includeSubDomains
<
{
    "result": {
        "messages": [],
        "flushMessages": true,
        "outcome": "SUCCESS",
        "requestId": "<REQUEST_UNIQUE_ID>"
    },
    "data": {
        "access_token": "<ACCESS_TOKEN>",
        "token_type": "Bearer",
        "expires_in": <TIME>,
        "refresh_token": "<REFRESH_TOKEN>",
        "rt_expires_in": <TIME>,
        "scope": "<SCOPE>"
    }
}

Client credentials

If you need to call APIs when the user is not logged into your application, you can use the client credentials flow to obtain an OAuth access token. The flow is described in the following diagram.

OAuth 2.0 Client Credentials Flow

What are the required steps to perform this type of authentication?

  • Register to the developer portal
  • Request a new application with grant type = client_credentials
  • You'll be given a credential couple (client_id + client_secret)
  • Call the /oauth/v2/token API with the given credentials, as written [here]
  • You'll receive the access token and the refresh token (if expected)
  • Now you can call Mediobanca Premier APIs!

Client credentials steps

Here's and example of the needed requests to obtain an access token in curl format. You can invoke the /auth/oauth/v2/token API either with application/json or application/x-www-form-urlencoded content type.

Since the connection is secure, you have to add the external-api.mediobancapremier.io certificates (in the following example, the certificate chain is in the external-api.mediobancapremier.io.pem file).

Request
curl --cacert external-api.mediobancapremier.io.pem \
  --cert tpp-qwac.crt --key tpp-qwac.key \
  -X POST \
  -H 'Date: Tue, 20 Aug 2019 10:18:04 GMT' \
  -H 'Digest: SHA-256=UCiwgJXql+GKnCx3im0bs58j6sEQUxPfnvJEeBgaF/Q=' \
  -H 'Postman-Token: 7254f980-23a6-4429-806a-4fc79ddc3157' \
  -H 'Signature: keyId="<TPP_APP_NAME>",algorithm="rsa-sha256",headers="(request-target) digest tpp-request-id date",signature="K5Pb/mQ0S2ye8jBQZq73bR6mgmxVeIfdcXbRxFVxFcrzstvnm2Ju+96A2fcWshSsfYKnB3uuhm2rStwvROBjhnhdFGxPj/eYP+GXzNj3BmxNQTXMJtYFnjLGdOuVW1tNczlaOhus7dhumiKs/EttEwzTQJjVAEAHwJykuS7UjzBpKUJyFy3aXhrftAj9Jds0alrx7C6X5Md33sGB1Sa/CCJeCxSHNaaTFXzjwi5ILbqMR2ShRpn8eVPn3lpmKBJCVKMoWY/KjwhEtnVwL2rKzvko5zAVANDlEvnSGd5Hpvw4vg1Qpl84LpUhllJK2u6MhnwN9N6u4/qwW0yLwL6e6P1v09WW9wYfy2/jwgEzQAUORl5DfqKN5UoCR8Vmmju8XBugItYRm4BekorRmJab1v//6W9cqJpjG/mLiay3tbf28Hwm6UezdqkeSVMOpKpDu+2PR5uEvNinrBrHT9ha+f+VDfoSlzu/7uEvL5oeucpahVJ10w2E6DTjYBIMsm9Oax4YoXCL2gvz9Wd7RoqvIn6qrQ2cqVE7v3pF5RhDnd9kLDy7L+2e5U2tWHEwNhTszOP7Oigr2CSDeaCxX7Xp7744iGYV1YfHOILkdR/xNXebjdB4U4+FzhDWPjiYrMmsDbTQRPLbiUnk3R08e8qEp+ooaLlw6j4MFhmThjHuZ7s="' \
  -H 'TPP-Request-ID: 71f362d4-21b2-4669-95c2-baa5e1770901' \
  https://external-api.mediobancapremier.io/auth/oauth/v2/token \
  -H 'content-type: application/json' \
  -d '{
    "client_id":"<CLIENT_ID>",
    "client_secret":"<CLIENT_SECRET>",
    "grant_type":"client_credentials"
    }'
Response
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Connection: close
< Content-Type: application/json;charset=UTF-8
< Content-Length: 347
< Date: Tue, 12 Feb 2019 11:54:50 GMT
< Strict-Transport-Security: max-age=16070400; includeSubDomains
<
{
"result": {
            "messages":[

            ],
            "flushMessages":true,
            "outcome":"SUCCESS",
            "requestId": "<REQUEST_UNIQUE_ID>"
        },"data":{

  "access_token":"<ACCESS_TOKEN>",
  "token_type":"Bearer",
  "expires_in":<TIME>,
  "scope":"<SCOPE>"

}

Refresh token

The refresh token is supported only for authorization_code application, as defined in the OAuth RFC.

Request
curl --cacert external-api.mediobancapremier.io.pem \
  --cert tpp-qwac.crt --key tpp-qwac.key \
  -X POST \
  -H 'Date: Tue, 20 Aug 2019 10:18:04 GMT' \
  -H 'Digest: SHA-256=UCiwgJXql+GKnCx3im0bs58j6sEQUxPfnvJEeBgaF/Q=' \
  -H 'Postman-Token: 7254f980-23a6-4429-806a-4fc79ddc3157' \
  -H 'Signature: keyId="<TPP_APP_NAME>",algorithm="rsa-sha256",headers="(request-target) digest tpp-request-id date",signature="K5Pb/mQ0S2ye8jBQZq73bR6mgmxVeIfdcXbRxFVxFcrzstvnm2Ju+96A2fcWshSsfYKnB3uuhm2rStwvROBjhnhdFGxPj/eYP+GXzNj3BmxNQTXMJtYFnjLGdOuVW1tNczlaOhus7dhumiKs/EttEwzTQJjVAEAHwJykuS7UjzBpKUJyFy3aXhrftAj9Jds0alrx7C6X5Md33sGB1Sa/CCJeCxSHNaaTFXzjwi5ILbqMR2ShRpn8eVPn3lpmKBJCVKMoWY/KjwhEtnVwL2rKzvko5zAVANDlEvnSGd5Hpvw4vg1Qpl84LpUhllJK2u6MhnwN9N6u4/qwW0yLwL6e6P1v09WW9wYfy2/jwgEzQAUORl5DfqKN5UoCR8Vmmju8XBugItYRm4BekorRmJab1v//6W9cqJpjG/mLiay3tbf28Hwm6UezdqkeSVMOpKpDu+2PR5uEvNinrBrHT9ha+f+VDfoSlzu/7uEvL5oeucpahVJ10w2E6DTjYBIMsm9Oax4YoXCL2gvz9Wd7RoqvIn6qrQ2cqVE7v3pF5RhDnd9kLDy7L+2e5U2tWHEwNhTszOP7Oigr2CSDeaCxX7Xp7744iGYV1YfHOILkdR/xNXebjdB4U4+FzhDWPjiYrMmsDbTQRPLbiUnk3R08e8qEp+ooaLlw6j4MFhmThjHuZ7s="' \
  -H 'TPP-Request-ID: 71f362d4-21b2-4669-95c2-baa5e1770901' \
  https://external-api.mediobancapremier.io/auth/oauth/v2/token \
  -H 'content-type: application/json' \
  -d '{
    "client_id":"<CLIENT_ID>",
    "client_secret":"<CLIENT_SECRET>",
    "refresh_token":"<REFRESH_TOKEN>",
    "grant_type":"refresh_token"
    }'
Response
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS,HEAD
< Access-Control-Allow-Headers: Content-Type
< cb-apitrack-id: 4067327926
< Cache-Control: no-store
< Pragma: no-cache
< Content-Type: application/json
< Content-Length: 366
< Date: Tue, 12 Feb 2019 16:06:27 GMT
< Connection: close
< Strict-Transport-Security: max-age=16070400; includeSubDomains
<
{
    "result": {
        "messages": [],
        "flushMessages": true,
        "outcome": "SUCCESS",
        "requestId": "<REQUEST_ID>"
    },
    "data": {
        "access_token": "<ACCESS_TOKEN>",
        "token_type": "Bearer",
        "expires_in": <TIME>,
        "refresh_token":"<REFRESH_TOKEN>",
        "rt_expires_in":<TIME>,
        "scope": "<SCOPE>"
    }
}

Revoke a token

Request
curl --cacert external-api.mediobancapremier.io.pem \
  --cert tpp-qwac.crt --key tpp-qwac.key \
  -X POST \
  -H 'Date: Tue, 20 Aug 2019 10:18:04 GMT' \
  -H 'Digest: SHA-256=UCiwgJXql+GKnCx3im0bs58j6sEQUxPfnvJEeBgaF/Q=' \
  -H 'Postman-Token: 7254f980-23a6-4429-806a-4fc79ddc3157' \
  -H 'Signature: keyId="<TPP_APP_NAME>",algorithm="rsa-sha256",headers="(request-target) digest tpp-request-id date",signature="K5Pb/mQ0S2ye8jBQZq73bR6mgmxVeIfdcXbRxFVxFcrzstvnm2Ju+96A2fcWshSsfYKnB3uuhm2rStwvROBjhnhdFGxPj/eYP+GXzNj3BmxNQTXMJtYFnjLGdOuVW1tNczlaOhus7dhumiKs/EttEwzTQJjVAEAHwJykuS7UjzBpKUJyFy3aXhrftAj9Jds0alrx7C6X5Md33sGB1Sa/CCJeCxSHNaaTFXzjwi5ILbqMR2ShRpn8eVPn3lpmKBJCVKMoWY/KjwhEtnVwL2rKzvko5zAVANDlEvnSGd5Hpvw4vg1Qpl84LpUhllJK2u6MhnwN9N6u4/qwW0yLwL6e6P1v09WW9wYfy2/jwgEzQAUORl5DfqKN5UoCR8Vmmju8XBugItYRm4BekorRmJab1v//6W9cqJpjG/mLiay3tbf28Hwm6UezdqkeSVMOpKpDu+2PR5uEvNinrBrHT9ha+f+VDfoSlzu/7uEvL5oeucpahVJ10w2E6DTjYBIMsm9Oax4YoXCL2gvz9Wd7RoqvIn6qrQ2cqVE7v3pF5RhDnd9kLDy7L+2e5U2tWHEwNhTszOP7Oigr2CSDeaCxX7Xp7744iGYV1YfHOILkdR/xNXebjdB4U4+FzhDWPjiYrMmsDbTQRPLbiUnk3R08e8qEp+ooaLlw6j4MFhmThjHuZ7s="' \
  -H 'TPP-Request-ID: 71f362d4-21b2-4669-95c2-baa5e1770901' \
  https://external-api.mediobancapremier.io/auth/oauth/v2/token/revoke \
  -H 'content-type: application/json' \
  -d '{
    "client_id":"<CLIENT_ID>",
    "client_secret":"<CLIENT_SECRET>",
    "token":"<ACCESS_TOKEN|REFRESH_TOKEN>",
    "token_type_hint":"<access_token|refresh_token>"
    }'
Response
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS,HEAD
< Access-Control-Allow-Headers: Content-Type
< cb-apitrack-id: 4067327926
< Cache-Control: no-store
< Pragma: no-cache
< Content-Type: application/json
< Content-Length: 366
< Date: Tue, 12 Feb 2019 16:06:27 GMT
< Connection: close
< Strict-Transport-Security: max-age=16070400; includeSubDomains
<
{
    "result": {
        "messages": [],
        "flushMessages": true,
        "outcome": "SUCCESS",
        "requestId": "<REQUEST_ID>"
    },
    "data": {
        "tokenType": "access_token|refresh_token",
        "operationOutcome": "revoked"
    }
}