Authenticate your user
To get an access token which will allow you to access basic user information, you’ll need to integrate with OAuth’s Authorization Code Flow.
Use the integration discovery endpoint
You can use the integration discovery endpoint (viewed at https://oidc.integration.account.gov.uk/.well-known/openid-configuration
) to get information needed to interact with GOV.UK One Login, for example:
- issuer name
- information about the keys
- supported scopes, which will contain the user attributes your service can request
When you configure your service for production, you can use the production discovery endpoint.
Make a request to the /authorize
endpoint
You can send a request to the /authorize
endpoint to:
- authenticate your user
- check your user’s level of identity confidence - you must have authenticated your user first
Choose one of the following example messages to make your own GET
request. You can use the following table to replace the placeholders in your example message.
Make a request for authentication
To authenticate your user, customise the following example GET
request by replacing the example’s placeholder values.
The following example specifies a medium level of authentication. There’s further guidance on choosing the level of authentication.
GET /authorize?response_type=code
&scope=YOUR_SCOPES
&client_id=YOUR_CLIENT_ID
&state=STATE
&redirect_uri=YOUR_REDIRECT_URI
&nonce=aEwkamaos5B
&vtr=["Cl.Cm"]
&ui_locales=en
HTTP/1.1
Host: oidc.integration.account.gov.uk
- a continuous line of text separating each parameter with an ampersand (&)
- not split across multiple lines
- without any additional separators such as newline, commas or tabs
Make a request for authentication and identity
If you need to authenticate your user and check their identity, you should send 2 separate requests: one for authentication and one for identity.
- Send a request to the
/authorize
endpoint to authenticate your user specifying the Vector of Trust (vtr
) parameter asCl.Cm
. - Send a request for identity to the
/authorize
endpoint specifying thevtr
asCl.Cm.P2
.
By using 2 separate requests:
- more users are likely to create their account successfully
- you can track which users could not prove their identity
- you can support your users better when returning from an in-person identity check because you’ll have authenticated them previously
- you simplify the migration of existing users to GOV.UK One Login
The following example uses medium authentication (Cl.Cm
) and a medium level of identity confidence (P2
). There’s further guidance on choosing the level of authentication and choosing the level of identity confidence.
You can replace your example’s placeholder values.
GET /authorize?response_type=code
&scope=YOUR_SCOPES
&client_id=YOUR_CLIENT_ID
&state=STATE
&redirect_uri=YOUR_REDIRECT_URI
&nonce=aEwkamaos5B
&vtr=["Cl.Cm.P2"]
&ui_locales=en
&claims=<claims-request>
HTTP/1.1
Host: oidc.integration.account.gov.uk
- a continuous line of text separating each parameter with an ampersand (&)
- not split across multiple lines
- without any additional separators such as newline, commas or tabs
Create a URL-encoded JSON object for <claims-request>
After you’ve made a request for authentication and identity, you should then create a URL-encoded JSON object for <claims-request>
. Your JSON object should look similar to this example:
{
"userinfo": {
"https://vocab.account.gov.uk/v1/coreIdentityJWT": null,
"https://vocab.account.gov.uk/v1/address": null,
"https://vocab.account.gov.uk/v1/passport": null,
"https://vocab.account.gov.uk/v1/drivingPermit": null
}
}
You can only request user attributes to be returned in the /userinfo
response. You cannot configure the claims returned in the ID token.
Secure your authorisation request parameters with JWT
You can use a JWT-secured OAuth 2.0 authorisation request (JAR) with encoded parameters to protect your request from attacks and hackers.
GOV.UK One Login follows the OIDC principles on passing request objects.
- Build a request object and sign it using the private key you created when setting up your integration with GOV.UK One Login.
- Encode the signed request object.
- Make a
GET
request replacingYOUR_REQUEST_OBJECT
with your signed and encoded request object.
Use this example to make your own GET
request, replacing the placeholder values:
GET /authorize?response_type=code
&scope=YOUR_SCOPES
&client_id=YOUR_CLIENT_ID
&request=YOUR_REQUEST_OBJECT
HTTP/1.1
Host: oidc.integration.account.gov.uk
You must make sure:
response_type
,scope
, andclient_id
are identical in the query parameters and the request object- you do not set any other OIDC parameters using query parameters
Before you encode and sign the request object, it should look similar to this example:
{
"aud": "https://oidc.integration.account.gov.uk/authorize",
"iss": "YOUR_CLIENT_ID",
"response_type": "code",
"client_id": "YOUR_CLIENT_ID",
"redirect_uri": "https://client.example.org/cb",
"scope": "YOUR_SCOPES",
"state": "af0ifjsldkj",
"nonce": "n-0S6_WzA2Mj",
"vtr": [
"Cl.Cm.P2"
],
"ui_locales": "en",
"claims": {
"userinfo": {
"https://vocab.account.gov.uk/v1/coreIdentityJWT": null,
"https://vocab.account.gov.uk/v1/address": null,
"https://vocab.account.gov.uk/v1/passport": null,
"https://vocab.account.gov.uk/v1/drivingPermit": null
}
}
}
You can replace your example’s placeholder values.
Replace the placeholder values in your example
Use the guidance in the following table to replace placeholder values in your example message.
Parameter | Required or optional | Description |
---|---|---|
response_type |
Required | You must set this value to be code: response_type=code .If you’re using JAR, make sure the response_type values in the query parameters and the request object are identical. |
scope |
Required | A space-separated list of scopes. You must include openid as one scope value. If you request openid but also request other incorrect scopes, the error invalid_scope will return with an HTTP 302 instead.You should refer to the guidance on choosing which user attributes your service can request for the scope parameter.If you’re using JAR, make sure the scope values in the query parameters and the request object are identical. |
client_id |
Required | The client identifier, which we generated for you when you registered your service to use GOV.UK One Login must match your client configuration. If you’re using JAR, make sure the client_id values in the query parameters and the request object are identical. |
state |
Required | When you receive a response at the redirect URL, there must be a way to verify the response came for a request which you sent. The state value solves this issue by binding the request and response, which reduces impact of Cross Site Request Forgery attacks.This value will be returned to the client in the authentication response. |
redirect_uri |
Required | You’ll have specified your redirect_uri when you registered your service to use GOV.UK One Login.To avoid an HTTP 400 Bad Response error, the redirect URI must exactly match one of the URIs configured in your client configuration and also include the protocol https:// or http .If you’re using request parameters, the value must be URL-encoded. |
nonce |
Required | A unique value generated by your application that is used to verify the integrity of the id_token and mitigate replay attacks.This value will be present in the id_token and should include the per-session state, as well as being impossible for attackers to guess.Your application will need to verify the nonce claim value is the same as the nonce parameter sent in the authentication request. |
aud |
Optional | If you’re using JAR, you must include aud in your JSON object.You must set this value to specify GOV.UK One Login’s authorisation server as the intended audience: aud=https://oidc.integration.account.gov.uk/authorize . |
iss |
Optional | If you’re using JAR, the iss parameter is required.You must set this value to be your client_id . GOV.UK One Login generated your client_id when you registered your service to use GOV.UK One Login. |
ui_locales |
Optional | GOV.UK One Login supports English and Welsh as language choices. If your service is in Welsh, you may want to display GOV.UK One Login in Welsh for a consistent user experience. You can use ui_locales to do this. In the ui_locales parameter, you can choose either en (English) or cy (Welsh). Using ui_locales is optional. If you do not include it, your service will continue using English by default. GOV.UK One Login does not support any other languages. |
vtr |
Optional | The vtr parameter represents ‘Vectors of Trust’ where you request authentication and, optionally, identity proving. For example, if you want the medium level of authentication and medium identity confidence, request vtr=[“Cl.Cm.P2”] . You selected your Vector of Trust when you chose the level of authentication and the level of identity confidence for your service. You can read more about how to combine the vectors for authentication level and identity confidence in Section 3 of RFC 8485. If you need identity proving, you must request Cl.Cm (the medium level of authentication).If you do not specify the vtr parameter, your service will automatically log your users in at the medium level of authentication (Cl.Cm ). This means you will not receive identity attributes in your response. |
claims |
Optional | To get the identity attributes your service needs, you should specify these in the claims parameter using the /userinfo endpoint. The /userinfo endpoint returns a JSON object listing the requested claims.You can read more about choosing which user attributes your service can request. You can read more about the structure of the claims request in OpenID Connect section 5.5. |
Generate an authorisation code
If your user does not have an existing session they’re signed in to when your service makes the request to the /authorize
endpoint, the OIDC sign-in page will open. Your user can enter their details on this page to authenticate themselves.
If your user has an existing session, or after they authenticate, they will be redirected to the redirect_uri
your service specified.
The authorisation code generated by your user’s session can be used once and displays in the query string of the URL, for example:
HTTP/1.1 302 Found
Location: https://YOUR_REDIRECT_URI?code=AUTHORIZATION_CODE&state=xyzABC123
If your request included the state
parameter, the URI will also include this parameter.
Error handling for ‘Make a request to the /authorize
endpoint’
You must check the HTTP return code from the /authorize
request.
HTTP 400 Bad Request
If your GET
request to the /authorize
endpoint produces a Request is missing parameters
or Invalid request
with HTTP 400 (Bad Request)
, it might be because the parameters are not included correctly.
You should check you have included the correct parameters, especially the client_id
, redirect_uri
, response_type
and scope
parameters.
HTTP 302 Found
To understand more about what the error is, you can look in the response. Depending on the type of error you receive, the response may contain an error
and an error_description
which will provide you with information.
If there’s an error in your request, you’ll be redirected to the URI you specified for redirect_uri
in the authorisation URL. You’ll be able to see the error description tagged onto the end of the authorisation URL, for example:
HTTP/1.1 302 Found
Location: https://YOUR_REDIRECT_URI?error=invalid_request
&error_description=Unsupported%20response
&state=1234
Error | More information about your error |
---|---|
unauthorized_client |
In rare circumstances, such as a security incident, One Login may prevent users from logging in to your service. If this happens, the error code unauthorized_client will be returned with the error description client deactivated . When your service receives this error, you must show the user a custom error page to explain that they cannot use your service at the moment and should try again later. |
invalid_request |
The request has one or more of the following issues:
You can check which parameters GOV.UK One Login supports when you make an authorisation request. |
invalid_request - Request vtr not valid |
You’ve requested single factor authentication and identity information. To make a successful identity request, you must request two-factor authentication and the identity level of confidence, for example Cl.Cm.P2 . |
invalid_scope |
The scope or scopes you have requested are invalid, unknown, or are not in the correct format. You can read more about scopes in choosing which user attributes your service can request. |
unsupported_response_type |
Your service is not registered for the requested response_type . You must set the response_type to be code: response_type=code . |
server_error |
The GOV.UK One Login authentication server has experienced an internal server error. |
temporarily_unavailable |
If you’re only making an authentication request (as opposed to requesting both authentication and identity), this error code means the GOV.UK One Login authentication server is temporarily unavailable, which might be caused by temporary overloading or planned maintenance. Make your request again in a few minutes. If you’re making an identity request and you get this error, it means the identity proving and verification does not currently have capacity for this request. |
access_denied |
GOV.UK One Login returns this error in 2 scenarios. The first scenario is that the identity evidence your user provided has a lower score than the identity confidence specified in your request. As a result, GOV.UK One Login could not return the medium level of identity confidence ( P2 ) and instead returned a lower level of identity confidence.If you’re using return codes, you will not receive this error. Instead, GOV.UK One Login returns an array of single letter returnCode values through the userinfo endpoint. Find more information on understanding the return codes claim.The second scenario is that the session in the user’s browser is unavailable. This can happen when your user’s cookies have been lost or your user changed browsers during the identity verification process. In this scenario, you should ask your user to log in again or restart the identity verification process. |
Make a token request
You need to exchange your authorisation code for tokens. You’ll use these tokens to make a call to the /userinfo
endpoint.
To exchange your authorisation code for tokens, you’ll need to make a POST
request to the /token
endpoint using the client authentication method private_key_jwt
or client_secret_post
(only available for certain third-party platforms). There’s further guidance on using the correct token authentication method.
Before you can make a POST
request, you need to:
- Create a JWT assertion.
- Include the JWT assertion in your
POST
request.
GOV.UK One Login will then authenticate your request by verifying the signature and payload of the JWT assertion. This authentication will generate a token response, which will include:
- an access token
- an ID token
Create a JWT assertion
To create a JWT assertion, you need to:
- Use the key pair you generated earlier in the process.
- Create a JWT.
- Sign your JWT with the key you created - how you sign your JWT will vary depending on the language you’re using.
Create a JWT
To create a JWT assertion, you need to create a JWT which contains certain required claims. There’s some optional claims you can choose to include or not include.
Claim | Required or recommended | Description |
---|---|---|
aud |
Required |
aud stands for ‘audience’. This identifies GOV.UK One Login’s authorisation server as an intended audience. This value should be the URL: https://oidc.integration.account.gov.uk/token. |
iss |
Required |
iss stands for ‘issuer’. This claim should contain your client_id you got when you registered your service to use GOV.UK One Login. |
sub |
Required |
sub stands for ‘subject’. This claim should contain your client_id you got when you registered your service to use GOV.UK One Login. There’s further guidance on how to use this value in the response to the /userinfo endpoint. |
exp |
Required |
exp stands for ‘expiration time’. This is the expiration time for this token, which must be an integer timestamp representing the number of seconds since the Unix Epoch. This is the time after which you must not accept the JWT. We recommend an expiration after 5 minutes. The current date and time must be before the expiration date and time listed in the exp claim. |
jti |
Required |
jti stands for ‘JWT ID’. In this claim, you should include a unique identifier for the token. This unique identifier will prevent the token being reused as your application must only use these tokens once. |
iat |
Recommended |
iat stands for ‘issued at’. This identifies the time at which your application created the JWT. You can use this claim to understand the age of the JWT.This must appear as an integer timestamp representing the number of seconds since the Unix Epoch. |
Your JWT body will look similar to this example:
{
"aud":"https://oidc.integration.account.gov.uk/token",
"iss":"229pcVGuHP1lXX37T7Wfbr5SIgm",
"sub":"229pcVGuHP1lXX37T7Wfbr5SIgm",
"exp":1536165540,
"jti":"RANDOM_VALUE_JTI",
"iat":1536132708
}
Once you have created your JWT and signed your JWT with the key pair, you have created your JWT assertion.
Make a POST
request to the /token
endpoint
Now you have generated your JWT assertion, you’re ready to make a POST
request to the /token
endpoint, for example:
POST /token HTTP/1.1
Host: oidc.integration.account.gov.uk
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient.example.org%2F
&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIiLCJpc3MiOiIiLCJhdWQi
OiIiLCJqdGkiOiIifQ.r1Ylfhhy6VNSlhlhW1N89F3WfIGuko2rvSRWO4yK1BI
- a continuous line of text separating each parameter with an ampersand (&)
- not split across multiple lines
- without any additional separators such as newline, commas or tabs
Parameter | Required or recommended | Description |
---|---|---|
grant_type |
Required | You need to set the parameter to authorization_code . |
redirect_uri |
Required | You’ll have specified your redirect_uri when you made the initial authorisation request. |
client_assertion |
Required | You’ll include the JWT assertion you created in the payload when you make the POST request to the /token endpoint. |
client_assertion_type |
Required | When you’re using private_key_jwt , you must set the value to urn:ietf:params:oauth:client-assertion-type:jwt-bearer . |
code |
Required | The code you received when you generated an authorisation code. |
Receive response for ‘Make a token request’
If your token request is successful, the /token
endpoint will return a response similar to this example:
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "SlAV32hkKG",
"token_type": "Bearer",
"expires_in": 180,
"id_token":"eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzc
yI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg"
}
You can use the following table to understand the response for ‘Make a token request’.
Parameter | Description |
---|---|
access_token |
The access token value is an opaque access token which you can use with the /userinfo endpoint to return a user’s profile. |
token_type |
The token type value. GOV.UK One Login only supports the bearer token. |
expires_in |
The length of time the token is valid for. This is displayed in seconds. |
id_token |
A signed JWT that contains basic attributes about the user. By default, GOV.UK One Login signs this JWT using the ES256 algorithm.If your service cannot support the ES256 algorithm (for example, some third-party tooling does not support ES256 ), GOV.UK One Login can sign the JWT using the RS256 algorithm. You’ll have specified whether your service can support ES256 when you registered your service to use GOV.UK One Login.The public key used to verify this JWT is available from the jwks_uri parameter found in the discovery endpoint. |
Understand your ID token
The id_token
parameter in the response for ‘Make a token request’ contains the following claims:
{
"at_hash": "ZDevf74CkYWNPa8qmflQyA",
"sub": "urn:fdc:gov.uk:2022:VtcZjnU4Sif2oyJZola3OkN0e3Jeku1cIMN38rFlhU4",
"aud": "YOUR_CLIENT_ID",
"iss": "https://oidc.integration.account.gov.uk/",
"vot": "Cl.Cm",
"exp": 1704894526,
"iat": 1704894406,
"nonce": "lZk16Vmu8-h7r8L8bFFiHJxpC3L73UBpfb68WC1Qoqg",
"vtm": "https://oidc.integration.account.gov.uk/trustmark",
"sid": "dX5xv0XgHh6yfD1xy-ss_1EDK0I"
}
You can use the following table to understand the ID token’s claims.
Claim | Description |
---|---|
at_hash |
at_hash stands for ‘access token hash’. You use at_hash to validate your access token. This is not mandatory. There is further guidance on at_hash in the Open ID Connect specification. |
sub |
sub stands for the subject identifier or the unique ID of a user. |
aud |
aud stands for the audience, which will be the client_id you received when you registered your service to use GOV.UK One Login. |
iss |
iss stands for the GOV.UK One Login OpenID Provider’s Issue identifier as specified in the discovery endpoint. |
vot |
vot stands for ‘Vector of Trust’. Check the vot matches the authentication protection level you requested in your authorise request. The vot claim will only contain the credential trust level and not the level of confidence, even if you make an identity request. |
exp |
exp stands for ‘expiration time’. This is the expiration time for this token, which will be an integer timestamp representing the number of seconds since the Unix Epoch. |
iat |
iat stands for ‘issued at’. This identifies the time at which GOV.UK One Login created the JWT. You can use this claim to understand the age of the JWT.This will appear as an integer timestamp representing the number of seconds since the Unix Epoch. |
nonce |
The nonce value your application provided when you made the request to the /authorize endpoint. |
vtm |
vtm stands for ‘vector trust mark’. This is an HTTPS URL which lists the range of values GOV.UK One Login accepts and provides. |
sid |
sid stands for ‘session identifier’. This uniquely identifies the user’s journey within GOV.UK One Login. |
Now you’ve understood what’s in your ID token, you’ll need to validate it.
Validate your ID token
- If you’re using a library, check whether your library has support for validating ID tokens.
- The value of
iss
must exactly match the Issuer Identifier as specified in GOV.UK One Login’s discovery endpoint. - The
aud
claim must contain your client ID you received when you registered your service to use GOV.UK One Login. - You must validate the signature according to the JSON Web Signature Specification. You must first validate that the JWT
alg
header matches what was returned from thejwks_uri
. Then you can use the value of the JWTalg
header parameter to validate the ID token. Your application must use the keys provided by the discovery endpoint. - Check the current time is before the time in the
exp
claim. - Check the current time is after the time in the
iat
claim. - If you set a
nonce
value in the request to the/authorize
endpoint, check this matches thenonce
value in the ID token. - The
vot
claim must contain the credential trust level you asked for in the request to the/authorize
endpoint. Thevot
claim will only contain the credential trust level, not the level of confidence, even if you make an identity request. For example, if you set thevtr
parameter toCl.Cm.P2
, you must ensure thevot
claim is equal toCl.Cm
.
Error handling for ‘Make a token request’
To understand more about what the error is, you can look in the response. Depending on the type of error you receive, the response may contain an error
and an error_description
which will provide you with information.
If the token request is invalid or unauthorised, you’ll receive an error response with the Content-Type
of application/json, for example:
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "invalid_request"
"error_description": "invalid scope"
}
Error | More information about your error |
---|---|
invalid_request |
The request is missing a parameter so the server cannot proceed with the request. This error may also be returned if the request includes an unsupported parameter or repeats a parameter. Review your parameters and check they are supported and not repeated. |
invalid_client |
Client authentication failed, which could be caused by the request containing an invalid client_id or an issue in validating the signature of the client_assertion . To resolve, check:
|
invalid_grant |
The authorisation code is invalid or expired. This is also the error which would return if the redirect URL given in the authorisation request does not match the URL provided in this access token request. |
unauthorized_client |
The application is successfully authenticated, but it’s not registered to use the requested grant type. |
unsupported_grant_type |
The grant type is not supported by the server. |
Retrieve user information
You can retrieve information about your users by making a request to the /userinfo
endpoint.
Make the request to the /userinfo
endpoint using the access token you received when making a token request.
Using the authorisation header field, send the access token as a bearer token.
You’ll receive a JSON object which contains a collection of name and value pairs.
An example request to the /userinfo
endpoint would look similar to this example:
GET /userinfo HTTP/1.1
Host: oidc.integration.account.gov.uk
Authorization: Bearer <access_token>
Receive response for ‘Retrieve user information’
The response you’ll get after making a request to the /userinfo
endpoint will be a JSON object containing user attributes.
If you included all the scopes when you were choosing which user attributes your service can request and made a request to the /userinfo
endpoint, the response would look similar to this:
HTTP/1.1 200 OK
Content-Type: application/json
{
"sub": "urn:fdc:gov.uk:2022:56P4CMsGh_02YOlWpd8PAOI-2sVlB2nsNU7mcLZYhYw=",
"email": "test@example.com",
"email_verified": true,
"phone_number": "01406946277",
"phone_number_verified": true
}
If you included a level of identity confidence when you made a request to the /userinfo
endpoint, you’ll also see identity attributes in the response. You can read more about how to prove your user’s identity.
Claim returned | Description |
---|---|
sub |
The subject identifier (sub ) is the unique ID for a user. This will not change unless your user deletes their GOV.UK One Login and sets it up again. Do not use the sub as the primary identifier for your user. Instead, generate your own unique value for your user within your service and map this against the GOV.UK One Login sub . Mapping the sub makes account recovery easier. For example, if a user deletes their GOV.UK One Login, you can re-map the user’s new sub to your service without creating a new primary identifier for your user. |
email |
The email address your user entered when they registered their GOV.UK One Login. Do not:
|
email_verified |
This means the email was verified using a one-time code when the user created their account. This is always true . |
phone_number |
This is the phone number your user entered when they registered their GOV.UK One Login. This will not appear if the user used an authenticator app for their two-factor authentication. |
phone_number_verified |
This will be returned as:
|
Error handling for ‘Retrieve user information’
To understand more about what the error is, you can look in the response. Depending on the type of error you receive, the response may contain an error
and an error_description
which will provide you with information.
When a request fails, the /userinfo
endpoint will respond with:
- an HTTP status code (usually 401 or 403)
- an error code (usually error parameter and an error description) included in the response
An error response for the /userinfo
endpoint would look similar to this example:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="invalid_token",
error_description="The Access Token expired"
Error | More information about your error |
---|---|
invalid_token |
GOV.UK One Login denied your request as you have an invalid or missing bearer access token. To proceed, you must use the authorisation header field to send the token as a bearer token. |
Once you’ve authenticated your user, you can continue with proving your user’s identity.
If you’re only authenticating your users, skip the next section and move onto managing your users’ sessions.