Authorization Endpoint

The Authorization Endpoint is the entry point that begins the authentication flow, redirecting the user to authenticate and authorize access requested by the client application.

As Corppass requires the use of Pushed Authorization Request (PAR) as defined in RFC 9126, the Relying Party (RP) will need to perform the following steps:

  1. Send a back-channel POST request to the pushed_authorization_request_endpoint defined in our authorization server's OpenID configuration.

  2. Construct the authorization URL, and redirect the user to this URL.


Step 1: Sending the Pushed Authorization Request

The Pushed Authorization Request (PAR) flow is an extension of the OIDC authorization code flow that improves security.

It allows the RP to send sensitive authorization request parameters to Corppass via a back-channel, rather than exposing them in the front-channel (browser). This reduces the risk of leaking sensitive data such as scope and redirect_uri.

Request

POST /request

Example

POST /request
Content-Type: application/x-www-form-urlencoded
DPoP: <signed-DPoP-JWT>

client_id=51YUlwazLASM7aqMiBNW
&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=eyJ...
&response_type=code
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcallback
&scope=openid%20authinfo
&state=5de6a954-a762-4975-a8f4-b692cc35b964
&nonce=4a0bb161-e3bb-4a56-9d75-ebea5de7a32c
&code_challenge=VQbq2FQzvY12kTkE-FoLmGHim5W7LRknTNYTUKuCKcE
&code_challenge_method=S256
&authentication_context_type=APP_AUTHENTICATION_DEFAULT
&authentication_context_message=login%20as%20corporate%20user
&acr_values=urn:singpass:authentication:loa:2
&dpop_jkt=boPCS...

Request Headers

Header
Required
Description

Content-Type

Yes

Must be set to application/x-www-form-urlencoded for POST requests. Indicates the encoding format of the request body.

DPoP

Yes

The JWK Thumbprint of your proof-of-possession public key. The JWK thumbprint should be computed using the SHA256 hash algorithm, and encoded using base64url.

Optional if you provide the DPoP Proof JWK in the dpop_jkt request parameter (see Request Body section below). If both are provided, they must match. For simplicity, we recommend sending the DPoP header over the use of dpop_jkt request parameter, as the DPoP header is mandatory for later steps. Refer to the Demonstrating Proof of Possession section for more details.

Request Body

Field
Required
Description

redirect_uri

Yes

The URL that Corppass will redirect the user to after authentication. The value must match one of the redirect URLs that were pre-registered with Corppass during onboarding.

scope

Yes

A space-delimited list of scopes.

This determines the data that is returned in the ID token and in the userinfo endpoint. For more information, please refer to the Scopes section. Must include at least openid scope. Unrecognized or unauthorized scopes will result in an error.

response_type

Yes

The authorization processing flow to use.

Only code is supported, as mandated by FAPI2.0 specifications.

client_id

Yes

The client identifier assigned to the RP during onboarding with Corppass.

client_assertion_type

Yes

The type of client assertion.

Must be set to urn:ietf:params:oauth:client-assertion-type:jwt-bearer, as mandated by OIDC specifications.

client_assertion

Yes

A JWT identifying the client.

Refer to Client Assertion JWT section for more details.

state

Yes

A client-provided value used to maintain state between the request and the callback. It helps mitigate Cross-Site Request Forgery (CSRF, XSRF) attacks.

This value should be unique, non-guessable, and generated for each authorization session.

The value is returned in the authorization response. The RP must validate that the returned state matches the value originally provided.

nonce

Yes

A client-provided value used to mitigate replay attacks.

This value should be unique, non-guessable, and generated for each authorization session.

The value is returned in the ID Token. The RP must validate that the returned nonce matches the value originally provided.

code_challenge

Yes

The encoded and hashed value of the client-generated code_verifier.

Refer to Proof Key of Code Exchange for more details.

code_challenge_method

Yes

The method used to generate the code_challenge from the code_verifier.

Only S256 is supported, as mandated by FAPI 2.0 specifications.

acr_values

Yes

A space-delimited string indicating desired level of assurance (LoA) for the authentication.

If multiple values are provided, they should be listed in descending order of preference. The authorization server will use the first supported / available value. The values must provided in the format urn:singpass:authentication:loa:<number> where the number indicates the level of assurance.

Supported values:

  • urn:singpass:authentication:loa:2 - 2FA required.

  • urn:singpass:authentication:loa:3 - Face verification as a third factor required.

dpop_jkt

No

The JWK Thumbprint of your proof-of-possession public key. The JWK thumbprint should be computed using the SHA256 hash algorithm, and encoded using base64url. Optional if DPoP header is provided. If both are provided, they must match. For simplicity, we recommend sending the DPoP header over the use of dpop_jkt request parameter, as the DPoP header is mandatory for later steps. Refer to the Demonstrating Proof of Possession section for more details.

authentication_context_type

Yes

A value from a predefined list describing the type of transaction for which your user is performing the authentication. This is used for anti-fraud purposes. Refer to the Authentication Context Parameters section for more details.

authentication_context_message

No

A string value providing context on what users are performing authentication for. This will be displayed to users during authentication.

Success Response

Response Example

{
  "request_uri": "urn:ietf:params:oauth:request_uri:h8YQPVV0Dgm5MGaD_koAm",
  "expires_in": 300
}

Response Structure

Field
Type
Description

request_uri

String

Reference to the authorization request payload sent in this request.

expires_in

Numeric

The lifetime of the request_uri in seconds.

Use the value of request_uri in the subsequent request to the Authorization Endpoint (/mga/sps/oauth/oauth20/authorize).

Error Response

Response Example

{
  "error": "invalid_request",
  "error_description": "The redirect_uri is not valid for the given client",
  "state": "5de6a954-a762-4975-a8f4-b692cc35b964"
 }

Response Structure

Field
Type
Description

error

String

The error code identifying the type of error. The possible values are detailed below.

error_description

String

Human-readable description of the error.

state

String

The same state parameter value provided by the client in the pushed authorization request, returned as-is.

Error Codes

Error Code
HTTP Status
Error Description

invalid_request

400

The request is missing a required parameter, includes an unsupported value, or is malformed.

invalid_client

400 / 401

Client authentication failed due to a missing, invalid, expired, or improperly formatted client credential or assertion.

invalid_scope

400

The requested scope is invalid, unknown, malformed, or exceeds the scope granted to the client.

invalid_dpop_proof

401

The DPoP proof is invalid, expired, malformed, or failed verification.

server_error

500

The authorization server encountered an unexpected internal error while processing the request.

temporarily_unavailable

503

The server is temporarily unable to handle the request due to maintenance or high load.

Step 2: Redirecting the User to the Authorization URL

GET /mga/sps/oauth/oauth20/authorize 

After RPs complete the pushed authorization request, the next step is to redirect the user to open the authorization URL in their browser.

Instead of appending the full set of request parameters in the authorization URL, RPs only need to include two query parameters as detailed below.

Request

Request Example

GET /mga/sps/oauth/oauth20/authorize
?client_id=51YUlwazLASM7aqMiBNW
&request_uri=urn:ietf:params:oauth:request_uri:h8YQPVV0Dgm5MGaD_koAm HTTP/1.1
Host: id.corppass.gov.sg

Query Parameter
Required
Description

client_id

Yes

The client identifier assigned to the RP during onboarding with Corppass.

This must match the client_id value provided in the request body of the pushed authorization request (Step 1).

request_uri

Yes

The request_uri value returned in the response of the pushed authorization request (Step 1).

Success Response

If the above request is successfully validated by Corppass, the user will be redirected to the Singpass login page to perform authentication.

Response Example

HTTP/1.1 302 Found
Location: https://id.singpass.gov.sg/auth?client_id=...

Step 3: Receiving the Authorization Response (after user authentication)

Upon successful authentication, the user is redirected to the RP's redirect_uri via a 302 redirect. The URL contains two key query parameters as detailed below.

Success Response

Response Example

HTTP/1.1 302 Found
Location: https://client.example.org/cb
?code=KxygiAyIIHu4OCCqjF9XAxpCjKk0uUkKNA6mfVD9HZw
&state=5de6a954-a762-4975-a8f4-b692cc35b964

Response Structure

Query Parameter
Description

code

One-time authorization code to be used by the RP to obtain the user's ID token and access token via the Token Endpoint. The code is valid for 60 seconds and cannot be used for token exchange once expired.

state

The same state parameter value provided by the client in the pushed authorization request (Step 1), returned as-is to mitigate Cross-Site Request Forgery (CSRF, XSRF) attacks.

The RP must validate that the returned state matches the value originally provided.

Validation Steps

Upon receiving the code and state values, clients must validate that the state value matches the value originally sent in the pushed authorization request (Step 1).

Error Response

If an error occurs after authentication, the user will be redirected to the RP's redirect_uri with the error parameters detailed below. This allows clients to obtain more context about the user's login journey.

Response Example

HTTP/1.1 302 Found
Location: https://client.example.org/callback
?error=invalid_request_uri
&error_description=The%20request_uri%20is%20invalid%2C%20expired%2C%20malformed%2C%20or%20was%20not%20issued%20by%20the%20authorization%20server.
&state=5de6a954-a762-4975-a8f4-b692cc35b964

Response Structure

Query Parameter
Description

error

The error code identifying the type of error. The possible values are detailed below.

error_description

Human-readable description of the error.

state

The same state parameter value provided by the client in the pushed authorization request (Step 1), returned as-is.

Error Codes

Error Code
Description

invalid_request

The request is missing a required parameter, includes invalid or unsupported values, or is otherwise malformed.

Examples:

  • Missing or unrecognized client_id

  • client_id does not match the client associated with the referenced request_uri

  • Invalid client JWKS URL or invalid values being returned by the URL

invalid_request_uri

The request_uri parameter provided was missing, malformed, expired, or does not match the client associated with the referenced request_uri.

server_error

The authorization server encountered an unexpected internal error while processing the request. The error can potentially be due to the RP’s JWK endpoint being unreachable or returning a malformed JWK.

temporarily_unavailable

The server is temporarily unable to handle the request due to maintenance or high load.

Last updated