Third Party Authentication

Third party authentication provides us with a way to allow external companies to authenticate ITC users, or provide internal applications a single way to authenticate users.

This requires more effort than first party authentication, because we need to verify the third party application as well as the user. This method should only be used when third parties need to authenticate our users, because it prevents the third party knowing our users passwords.

Third party authentication requires the third party to redirect the user to a login page that ITC provides. This is a standardised login page, which only provides login and password reset functionality. Once the user has authenticated themselves with us, we redirect them back to the third party website.


Understanding the flow

A couple of redirects and API calls need to be made in order for this grant type to work. This is the most complicated grant type, so an understanding of what each step is, and why it's done is important.

  1. A redirect request is made by the third party to ITC
  2. ITC receive the request for a third party login, and display the login form to the user
  3. The user enters their username and password
  4. If enabled, a two factor auth screen is additionally displayed
  5. If the user is authenticated successfully by ITC, we redirect back to the third party website with a code
  6. The third party makes a request to ITC, to exchange the code for an access token

GET/oauth/flows/authorize

Initial Redirect

To begin, the third party site needs to redirect the user to ITCs login page. When making the request, they must also provide some details about who the third party application is, and what we should do after authenticating.

Required URL Parameters

  • Name
    response_type
    Required
    Type
    string
    Description

    Should always be set to code

  • Name
    client_id
    Required
    Type
    string
    Description

    ID of the client performing authentication

  • Name
    redirect_uri
    Required
    Type
    string
    Description

    Redirect the user back to this pre-registered URI after a successful authentication

  • Name
    scope
    Required
    Type
    string
    Description

    A list of space separated scopes that should be attached to the token

  • Name
    state
    Required
    Type
    string
    Description

    A value generating by the platform requesting authentication, and returned after ITC redirect back.

    This is a randomly generated string, similar to a CSRF token. It can be any string, but a UUID4 is probably simplest.

    You should compare this value with the value stored in the user’s session to ensure the authorization code obtained is in response to requests made by this client rather than another client application.

Request

GET
/oauth/flows/authorize
$querystring = http_query_build([
    'response_type' => 'code',
    'client_id' => 'example-client-id',
    'redirect_uri' => 'https://third-party.com/oauth/login',
    'scope' => 'profile.read profile.write',
    'state' => 'b1334ebc',
]);

header("Location: https://auth.itccompliance.co.uk/oauth/flows/authorize?{$querystring}");
exit;

Receiving the initial return

Once a user has authenticated themselves using our login page, we redirect back to the URI provided in the initial request.

We'll also return 2 sets of data in the request querystring.

The third party should then verify that the state returned from ITC is what they sent to us. This state is usually stored in the session and can be removed after verifying.

The code that is returned from ITC can be used in the next request. The code is a temporary token that can be given back to ITC, and in return ITC will return an access token. Think of the code as kind of like a username and password.

URL Parameters

  • Name
    code
    Required
    Type
    string
    Description

    A unique code which can be exchanged by the third party for an access token

  • Name
    state
    Required
    Type
    string
    Description

    The state that was provided in the initial redirect. This is so the third party can verify that it is ITC that is calling the endpoint


POST/oauth/token

Exchanging the code

Once the third party has received the initial return, they need to make another request to ITC to exchange the code we've returned for an access token.

You'll notice if you've read the "First Party Authentication" section, that the request is similar to a password grant or client_credentials grant login.

The code value is kind of like a reference to the user that just authenticated, so the third party doesn't need to provide the user username and password to login, they just provide that short lived code.

The response from this request will be the standard token response that returns an access token and refresh token.

Required Attributes

  • Name
    grant_type
    Required
    Type
    string
    Description

    Determines the method of authentication used. For third party authentication, this must be authorization_code

  • Name
    client_id
    Required
    Type
    string
    Description

    ID of the client performing authentication

  • Name
    client_secret
    Required
    Type
    string
    Description

    Secret password of the client performing authentication. This will only be known to the system that makes the authentication request.

  • Name
    redirect_uri
    Required
    Type
    string
    Description

    The URI registered with the OAuth server.

  • Name
    code
    Required
    Type
    string
    Description

    The code returned from OAuth, which will be exchanged for the access token.

Header Attributes

  • Name
    Accept
    Required
    Type
    string
    Description

    This should always be set to application/json. Additionally, you can provide a version argument in the Accept header to determine the JWT format.

    By default, this will always return a version 2 structured JWT token.

Request

POST
/oauth/token
use Compliance\Sdk\Authentication\OAuth\Contracts\OAuthSdkInterface;
use Compliance\Sdk\Authentication\Types\Machine;

private OAuthSdkInterface $sdk;

$response = $this->sdk->v1(new Machine())->issueToken([
    'grant_type' => 'authorization_code',
    'client_id' => 'example-client-id',
    'client_secret' => 'example-client-secret',
    'redirect_uri' => 'https://third-party.com/oauth/login',
    'code' => 'bbc51731c07440a5a70a39ef40271ebb77f6750102104d9daf397df5ec747fd49959fdfe0f5c4f22a8e934e0305fcca1'
], '2.0');

Response

{
    "token_type": "Bearer",
    "expires_in": "31536000",
    "access_token": "jwt.access.token",
    "refresh_token": "reference_token"
}