Endpoint cheat sheet
A quick reference for exercising LuxID's OIDC endpoints by hand when you need to check whether an endpoint is reachable, what it returns, or where a flow breaks. Every snippet is variable-driven so you can set your values once and reuse them.
The examples target UAT (login-uat.luxid.lu). For production, set the issuer host to login.luxid.lu.
These commands put your Client Secret and live tokens on the command line. Use a throwaway shell, avoid committing them to history, and never run production secrets through a shared machine. Access tokens, refresh tokens, and ID tokens are bearer credentials - treat them like passwords. The Bash snippets pipe JSON through jq (opens in a new tab); omit | jq . if you do not have it installed.
Set up variables
- Bash (Linux / macOS)
- PowerShell (Windows)
LUXID_ISS=login-uat.luxid.lu # login.luxid.lu in production
LUXID_CID=YOUR_CLIENT_ID
LUXID_CST=YOUR_CLIENT_SECRET
REDIRECT_URI=https://app.example.lu/auth/callback
# HTTP Basic credential for the endpoints that accept it
LUXID_BASIC_AUTH=$(printf '%s:%s' "$LUXID_CID" "$LUXID_CST" | base64 | tr -d '\n')
$LUXID_ISS = 'login-uat.luxid.lu' # login.luxid.lu in production
$LUXID_CID = 'YOUR_CLIENT_ID'
$LUXID_CST = 'YOUR_CLIENT_SECRET'
$REDIRECT_URI = 'https://app.example.lu/auth/callback'
# HTTP Basic credential for the endpoints that accept it
$LUXID_BASIC_AUTH = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("${LUXID_CID}:${LUXID_CST}"))
LuxID's token, refresh and introspection endpoints accept client authentication either as an HTTP Authorization: Basic header or as client_id / client_secret in the form body. The examples below use whichever is most common for each call; to switch styles, drop the Authorization header and add client_id / client_secret to the body (or vice versa).
0. Is the IdP reachable? (discovery)
The fastest "is it up and which endpoints does it expose?" check - no credentials needed.
- Bash (Linux / macOS)
- PowerShell (Windows)
curl -s "https://$LUXID_ISS/.well-known/openid-configuration" | jq .
Invoke-RestMethod "https://$LUXID_ISS/.well-known/openid-configuration" | ConvertTo-Json -Depth 10
1. Start an authorisation request (interactive)
This step happens in a browser. Build the authorisation URL, open it, sign in, and read the code and state from the callback. For generating code_verifier / code_challenge, state, and nonce, and for a script that assembles this URL, see Configure LuxID - Steps 1 to 3.
https://login-uat.luxid.lu/mga/sps/oauth/oauth20/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https%3A%2F%2Fapp.example.lu%2Fauth%2Fcallback
&scope=openid
&state=STATE
&nonce=NONCE
&code_challenge_method=S256
&code_challenge=CODE_CHALLENGE
After sign-in, LuxID redirects to your redirect_uri with the code and your state (some setups also see extra parameters such as iss and am-ext-user-id):
https://app.example.lu/auth/callback?state=STATE&code=AUTHORISATION_CODE&iss=https%3A%2F%2Flogin-uat.luxid.lu
Capture the code for the next step:
- Bash (Linux / macOS)
- PowerShell (Windows)
AUTH_CODE=AUTHORISATION_CODE # from the callback
CODE_VERIFIER=YOUR_CODE_VERIFIER # the verifier you generated in step 1
$AUTH_CODE = 'AUTHORISATION_CODE' # from the callback
$CODE_VERIFIER = 'YOUR_CODE_VERIFIER' # the verifier you generated in step 1
2. Exchange the code for tokens
- Bash (Linux / macOS)
- PowerShell (Windows)
curl -s -X POST "https://$LUXID_ISS/mga/sps/oauth/oauth20/token" \
-H "Accept: application/json" \
-d "grant_type=authorization_code" \
-d "client_id=$LUXID_CID" \
-d "client_secret=$LUXID_CST" \
-d "code=$AUTH_CODE" \
-d "code_verifier=$CODE_VERIFIER" \
-d "redirect_uri=$REDIRECT_URI" | jq .
$body = @{
grant_type = 'authorization_code'
client_id = $LUXID_CID
client_secret = $LUXID_CST
code = $AUTH_CODE
code_verifier = $CODE_VERIFIER
redirect_uri = $REDIRECT_URI
}
$resp = Invoke-RestMethod -Method POST -Uri "https://$LUXID_ISS/mga/sps/oauth/oauth20/token" `
-ContentType 'application/x-www-form-urlencoded' -Body $body
$resp | ConvertTo-Json -Depth 10
A successful response looks like this (values truncated):
{
"access_token": "...",
"refresh_token": "...",
"scope": "openid",
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ii4uLiJ9.eyJpc3MiOiJodHRwczovL2xvZ2luLXVhdC5sdXhpZC5sdSIsInN1YiI6Ii4uLiJ9.<signature>",
"token_type": "bearer",
"expires_in": 599
}
Store the tokens for the calls below. The id_token is a JWT; for a decoded example payload see Identity fundamentals.
- Bash (Linux / macOS)
- PowerShell (Windows)
ACCESS_TOKEN=PASTE_ACCESS_TOKEN
REFRESH_TOKEN=PASTE_REFRESH_TOKEN
# If you captured $resp above, reuse it directly:
$ACCESS_TOKEN = $resp.access_token
$REFRESH_TOKEN = $resp.refresh_token
3. Refresh the tokens
- Bash (Linux / macOS)
- PowerShell (Windows)
curl -s -X POST "https://$LUXID_ISS/mga/sps/oauth/oauth20/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Authorization: Basic $LUXID_BASIC_AUTH" \
-d "grant_type=refresh_token" \
-d "refresh_token=$REFRESH_TOKEN" | jq .
$resp = Invoke-RestMethod -Method POST -Uri "https://$LUXID_ISS/mga/sps/oauth/oauth20/token" `
-Headers @{ Authorization = "Basic $LUXID_BASIC_AUTH" } `
-ContentType 'application/x-www-form-urlencoded' `
-Body @{ grant_type = 'refresh_token'; refresh_token = $REFRESH_TOKEN }
$resp | ConvertTo-Json -Depth 10
Each refresh returns a new access_token (and may rotate the refresh_token) - update your variables with the new values before the next call.
4. Read the user's claims (UserInfo)
- Bash (Linux / macOS)
- PowerShell (Windows)
curl -s "https://$LUXID_ISS/mga/sps/oauth/oauth20/userinfo" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Accept: application/json" | jq .
Invoke-RestMethod -Uri "https://$LUXID_ISS/mga/sps/oauth/oauth20/userinfo" `
-Headers @{ Authorization = "Bearer $ACCESS_TOKEN" } | ConvertTo-Json -Depth 10
5. Inspect a token (introspection)
Confirms whether a token is active and shows its metadata (active, scope, exp, sub, ...).
- Bash (Linux / macOS)
- PowerShell (Windows)
curl -s -X POST "https://$LUXID_ISS/mga/sps/oauth/oauth20/introspect" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Authorization: Basic $LUXID_BASIC_AUTH" \
-d "token=$ACCESS_TOKEN" \
-d "token_type_hint=access_token" | jq .
$resp = Invoke-RestMethod -Method POST -Uri "https://$LUXID_ISS/mga/sps/oauth/oauth20/introspect" `
-Headers @{ Authorization = "Basic $LUXID_BASIC_AUTH" } `
-ContentType 'application/x-www-form-urlencoded' `
-Body @{ token = $ACCESS_TOKEN; token_type_hint = 'access_token' }
$resp | ConvertTo-Json -Depth 10
Endpoint reference
| Purpose | Method | Path |
|---|---|---|
| Discovery | GET | /.well-known/openid-configuration |
| Authorisation | GET | /mga/sps/oauth/oauth20/authorize |
| Token / Refresh | POST | /mga/sps/oauth/oauth20/token |
| UserInfo | GET | /mga/sps/oauth/oauth20/userinfo |
| Introspection | POST | /mga/sps/oauth/oauth20/introspect |
For the meaning of the values these endpoints return, see Token validation issues, the UserInfo endpoint, and Token introspection. For decoding errors, see Diagnose a failing request.