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.
- A redirect request is made by the third party to ITC
- ITC receive the request for a third party login, and display the login form to the user
- The user enters their username and password
- If enabled, a two factor auth screen is additionally displayed
- If the user is authenticated successfully by ITC, we redirect back to the third party website with a code
- The third party makes a request to ITC, to exchange the code for an access token
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
$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
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 theAccept
header to determine the JWT format.By default, this will always return a version 2 structured JWT token.
Request
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"
}