token
The token endpoint is described in the OIDC specification:
- For Authorization Code Flow: Token Endpoint - Code
- For Implicit Flow: No token endpoint
- For Hybrid Flow:Token Endpoint - Hybrid
Note that the Implicit Flow does not have an explicit token endpoint, instead tokens are returned from the authorization endpoint. The flow used is determined by the response_type parameter value contained in the Authorization Request, see authorization.
The endpoint is also described (in a generic manner) in the OAuth2 specification: Token Endpoint - OAuth2.
As described in Authentication with OIDC the Authorization Code and Implicit Grant are covered by the OIDC specification. But the two remaining OAuth2 grants depend on the token endpoint:
- For Resource Owner Password Credentials Grant: Token Endpoint - Password Credentials
- For Client Credentials Grant: Token Endpoint - Client Credentials
Endpoint URL
The token endpoint URL can be found by looking at the value of the "token_endpoint" key in the openid-configuration.
Typical format of the URL is:
https://auth.buypass.no/auth/realms/SECURITYDOMAIN/protocol/openid-connect/token
Token Request
To obtain an Access Token, an ID Token, and optionally a Refresh Token, the client sends a request to the token endpoint. The parameters varies with the OIDC flow or OAuth2 grant in use. All parameters should be on the format "application/x-www-form-urlencoded".
Note that client authentication still apply.
Authorization Code Flow
A client makes a token request by presenting its authorization code to the token endpoint. The parameters are sent to endpoint using the HTTP POST method and the form serialization. Note that scope for the tokens is provided as parameters in the preceding request to token.
Parameter | Required | Description | Example |
---|---|---|---|
grant_type | yes | The value references the current OIDC Flow, in this case: http://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth | grant_type=authorization_code |
code | yes | The one-time code returned in the authorization response | code=SplxlOBeZQQYbYS6WxSbIA |
redirect_uri | yes | The same URL encoded redirect_uri parameter value that was included in the initial authorization request | redirect_uri=https%3A%2F%2Foidc-client.example.org%2Fcb |
Example request
BASEURL="https://auth.buypass.no/auth/realms/SECURITYDOMAIN/protocol/openid-connect"; CLIENT_ID="oidc-client" CLIENT_SECRET="mysecret" BASIC_AUTH=`echo -n "${CLIENT_ID}:${CLIENT_SECRET}"| base64` curl -i -w "\n" \ -H "Content-Type: application/x-www-form-urlencoded" \ -H "Authorization: Basic ${BASIC_AUTH}" \ -X POST "${BASEURL}/token" \ -d "grant_type=authorization_code"\ "&code=SplxlOBeZQQYbYS6WxSbIA"\ "&redirect_uri=https%3A%2F%2Foidc-client.example.org%2Fcb"
Hybrid Flow
When using the Hybrid Flow, the token endpoint is used in the same manner as for the Authorization Code Flow described above.
Resource Owner Password Credentials Grant
A client makes a token request by presenting the end-user username and password to the token endpoint. In addition the client can request scopes on behalf of the end-user.
Not that this grant will only be used in limited scenarios as it considered a lower-security option (since the user password is passed from system to system).
Parameter | Required | Description | Example |
---|---|---|---|
grant_type | yes | The value references the current OAuth2 Grant, in this case: | grant_type=password |
username | yes | The end-user´s username | username=someuser |
password | yes | The end-user´s password | password=somepassword |
scope | no | Requested scope for the requested token(s). Se also Scopes Note: To also get an ID Token, the scope must include "openid" | scope=openid user-api |
Example request
BASEURL="https://auth.buypass.no/auth/realms/SECURITYDOMAIN/protocol/openid-connect"; CLIENT_ID="oidc-client" CLIENT_SECRET="mysecret" BASIC_AUTH=`echo -n "${CLIENT_ID}:${CLIENT_SECRET}"| base64` SCOPE="openid user-api" USERID="someuser" USERPWD="somepassword" curl -i -w "\n" \ -H "Content-Type: application/x-www-form-urlencoded" \ -H "Authorization: Basic ${BASIC_AUTH}" \ -X POST "${BASEURL}/token" \ -d "grant_type=password"\ "&username=%{USERID}"\ "&password=${USERPWD}"\ "&scope=${SCOPE}"
Client Credentials Grant
A client makes a token request on its own behalf (not authenticating an end-user). This is basically a client authentication only. The returning Access Token is issued to the client (not on behalf of any user).
Note that it does not make sense to request an ID Token in this case, as there is no end-user. It is also worth noticing that the specification states that this grant should not support Refresh Tokens.
This grant will typically be used for system integration and API purposes. Note that the Client Credential Grant is described by the OAuth2 specification, but client authentication is detailed by the OIDC specification.
For Client Credential Grants he following client authentication methods are supported:
Method | Description |
---|---|
client_secret_basic | Requires a client_secret ("password"). HTTP Basic authentication scheme. |
client_secret_post | Requires a client_secret ("password"). Including the client credentials in the request body. |
private_key_jwt | Requires a PKI key pair. Clients that have registered a public key sign a JWT using that key. |
to-way TLS | Requires a PKI key pair. Clients use client certificate with Mutual TLS authentication (mTLS), https://tools.ietf.org/html/rfc5246#section-7.4.6 |
Request parameters for the actual token request:
Parameter | Required | Description | Example |
---|---|---|---|
grant_type | yes | The value references the current OAuth2 Grant, in this case: | grant_type=client_credentials |
scope | no | Requested scope for the requested token(s). Se also Scopes | scope=service-api |
Example request using client_secret_post
BASEURL="https://auth.buypass.no/auth/realms/SECURITYDOMAIN/protocol/openid-connect"; CLIENT_ID="oidc-client" CLIENT_SECRET="mysecret" BASIC_AUTH=`echo -n "${CLIENT_ID}:${CLIENT_SECRET}"| base64` SCOPE="service-api" curl -i -w "\n" \ -H "Content-Type: application/x-www-form-urlencoded" \ -H "Authorization: Basic ${BASIC_AUTH}" \ -X POST "${BASEURL}/token" \ -d "grant_type=client_credentials"\ "&scope=${SCOPE}"
Example request using to-way TLS
Note the parameter "?_tlsclientauth=1" added to the TOKEN_URL. The parameter is used to trigger two-way TLS only if requested, if multiple authentication methods are available.
SD="SECURITYDOMAIN" ISSUER_URL="https://auth.buypass.no/auth/realms/${SD}"; # Note: Parameter to trigger MTLS inly when requested TOKEN_URL="${ISSUER_URL}/protocol/openid-connect/token?_tlsclientauth=1"; CLIENT_ID="oidc-client"; # Assuming private key and certificate is available in the keystore named: # ${CLIENT_ID}-keystore.p12 # Export the certificate openssl pkcs12 -in ${CLIENT_ID}-keystore.p12 -nokeys -out ${CLIENT_ID}-cert.pem # Export the private key (unencrypted) openssl pkcs12 -in ${CLIENT_ID}-keystore.p12 -nodes -nocerts -out ${CLIENT_ID}-key.pem # Post client authorization request using curl curl -v -i -w "\n" \ --cert ${CLIENT_ID}-cert.pem \ --key ${CLIENT_ID}-key.pem \ -H "Content-Type: application/x-www-form-urlencoded" \ -X POST "${TOKEN_URL}" \ -d "grant_type=client_credentials"\ "&client_id=${CLIENT_ID}"
Token Response
The token endpoint ill on success return one or more tokens: an Access Token, an potentially a ID Token, and optionally a Refresh Token. The typical response will look like this:
{ "access_token": "eyJhbGciOihXk...", "expires_in": 300, "refresh_expires_in": 1800, "refresh_token": "eyJhbGciOiJSU...", "token_type": "bearer", "id_token": "eyJhbGciOiJSUzI1NiI...", "not-before-policy": 0, "session_state": "e6445b99-3f0b-4343-a653-68038752c7f0", "scope": "service-api" }
See Tokens for details on token attributes and claims.