I have to move a legacy authentication system to Keycloak and I cannot change the actual workflow on the client. As such, I need to provide with my api (in node.js) a user creation and login system that in turns create and get access tokens from Keycloak on behalf of the user.
I'm able to create a user but I've not been able to find a way to generate an access token for that user. The only workaround I found is to create a user and set a random password, then asking to grant the user providing username and password but this means that I have to store a password on my side, which is exactly the reason why I wanted to move to Keycloak.
const KcAdminClient = require('keycloak-admin').default;
const Keycloak = require('keycloak-connect');
const _keycloakAdmin = new KcAdminClient({
baseUrl: process.env.KEYCLOAK_SERVER_AUTH_URL,
realm: process.env.KEYCLOAK_REALM
});
await _keycloakAdmin.auth({
realm: process.env.KEYCLOAK_REALM,
username: process.env.KEYCLOAK_USER,
password: process.env.KEYCLOAK_PASSWORD,
grantType: 'password',
clientId: process.env.KEYCLOAK_CLIENT_ID,
});
//Create a user and set password
const newUser = await _keycloakAdmin.users.create({
realm: process.env.KEYCLOAK_REALM,
username: 'something',
email: '[email protected]',
firstName: 'Some',
lastName: 'One',
emailVerified: true,
enabled: true,
});
await _keycloakAdmin.users.resetPassword({
realm: process.env.KEYCLOAK_REALM,
id: newUser.id,
credential: {
temporary: false,
type: 'password',
value: 'randompassword'
}
});
//generate a token for the user
const _keycloak = new Keycloak({}, {
clientId: process.env.KEYCLOAK_CLIENT_ID,
serverUrl: process.env.KEYCLOAK_SERVER_AUTH_URL,
realm: process.env.KEYCLOAK_REALM,
credentials: {
secret: process.env.KEYCLOAK_CLIENT_SECRET
}
});
const grant = await _keycloak.grantManager.obtainDirectly('something', 'randompassword');
const access_token = grant.access_token.token;
I cannot believe doesn't exist a more elegant way to do it so I think I'm missing something fundamental in the configuration of my Keycloak client and in understanding some basic concept and naming convention. I would have expected something like
await _keycloakAdmin.users.generateAccessToken(userId, realm, clientId, ...)
but I wasn't able to find it. I only found here on SO this unanswered question: Keycloak :REST API call to get access token of a user through admin username and password