My standard login process via the /authorize url is working fine and I have set it up to include user roles in the returned token with the following action:
exports.onExecutePostLogin = async (event, api) => {
const namespace = 'https://blah.blah.com'; // Use a custom namespace
// Check if event.authorization and roles exist
const assignedRoles = event.authorization && event.authorization.roles
? event.authorization.roles
: [];
// Set roles only if they exist
if (assignedRoles.length > 0) {
api.idToken.setCustomClaim(`${namespace}/roles`, assignedRoles);
api.accessToken.setCustomClaim(`${namespace}/roles`, assignedRoles);
}
};
Now for testing I want to be able to get a token for specific user types without requiring user input. To do this I believe the correct way is to use the /oauth/token endpoint. I’ve tried this with the “client_credentials” grant type:
async fn get_auth_token_cc() -> String {
let client = reqwest::Client::new();
let domain = std::env::var("DOMAIN").expect("DOMAIN not set");
let res = client
.post(&format!("{}/oauth/token", domain))
.header("content-type", "application/json")
.json(&serde_json::json!({
"client_id": std::env::var("CLIENT_ID").expect("CLIENT_ID not set"),
"client_secret": std::env::var("CLIENT_SECRET").expect("CLIENT_SECRET not set"),
"audience": &format!("{}/api/v2/", domain),
"grant_type": "client_credentials",
"username": std::env::var("AUTH0_USER_UN").expect("AUTH0_USER_UN not set"),
"password": std::env::var("AUTH0_USER_PW").expect("AUTH0_USER_PW not set"),
}))
.send()
.await
.expect("Failed to get token");
info!("{:?}", res);
let token: Auth0TokenResponse = res.json().await.expect("Invalid token response");
token.access_token
}
This succeeds but provides a token without any user or user role information.
I then thought that I needed to create a custom API for my Application and do an endpoint request with the “password” grant type:
async fn get_auth_token() -> String {
let client = reqwest::Client::new();
let domain = std::env::var("DOMAIN").expect("DOMAIN not set");
let res = client
.post(&format!("{}/oauth/token", domain))
.header("content-type", "application/json")
.json(&serde_json::json!({
"grant_type": "password",
"client_id": std::env::var("CLIENT_ID").expect("CLIENT_ID not set"),
"client_secret": std::env::var("CLIENT_SECRET").expect("CLIENT_SECRET not set"),
"audience": std::env::var("AUTH0_AUDIENCE").expect("AUTH0_AUDIENCE not set"),
"username": std::env::var("AUTH0_USER_UN").expect("AUTH0_USER_UN not set"),
"password": std::env::var("AUTH0_USER_PW").expect("AUTH0_USER_PW not set"),
"scope": "openid profile email",
"realm": "Username-Password-Authentication"
}))
.send()
.await
.expect("Failed to get token");
info!("{:?}", res);
let token: Auth0TokenResponse = res.json().await.expect("Invalid token response");
token.access_token
}
However this returns a 500 “Authorization server not configured with default connection”. Here is the full response:
{
"url":"https://dev-gdmpjq3p28gmc875.uk.auth0.com/oauth/token",
"status":500,
"headers":{
"date":"Mon, 07 Apr 2025 20:04:44 GMT",
"content-type":"application/json",
"content-length":"107",
"connection":"keep-alive",
"cf-ray":"92cc22beddcd6519-LHR",
"cf-cache-status":"DYNAMIC",
"cache-control":"private, no-store, no-cache, must-revalidate, post-check=0, pre-check=0, no-transform",
"set-cookie":"did=s%3Av0%3A3c8852bf-20e3-4269-9159-26ad7f477809.L7xzF7%2FmbWo7pKdPtNXibEcWkb1DrVet6cbR4dpK84k; Path=/; Expires=Wed, 08 Apr 2026 02:04:44 GMT; HttpOnly; Secure; SameSite=None",
"set-cookie":"did_compat=s%3Av0%3A3c8852bf-20e3-4269-9159-26ad7f477809.L7xzF7%2FmbWo7pKdPtNXibEcWkb1DrVet6cbR4dpK84k; Path=/; Expires=Wed, 08 Apr 2026 02:04:44 GMT; HttpOnly; Secure",
"strict-transport-security":"max-age=31536000; includeSubDomains",
"vary":"Origin",
"x-auth0-l":"0.033",
"x-auth0-requestid":"09abe69cf770170cd8ed",
"x-content-type-options":"nosniff",
"x-ratelimit-limit":"300",
"x-ratelimit-remaining":"299",
"x-ratelimit-reset":"1744056345",
"server":"cloudflare",
"alt-svc":"h3=\":443\"; ma=86400"
}
}
Do I have the correct method? If so, is there a setting I need to configure on the dashboard to get this to work?
Thanks!