Skip to content

Commit fc4b27d

Browse files
fix: extend refresh logic with reauth (anonrig#11, anonrig#76) (anonrig#90)
The keycloak-admin documentation advises to periodically refresh the token by calling an openid-client. However, RFC 6749 section 4.4.3 says that refresh token should not be issued on client_credentials grants. Since the plugin only uses client_credentials, I removed the call to keycloak-admin, relying only on openid-client to get the TokenSet. I also added a bit of logic to reauth when the TokenSet is expired. Testing it by setting Keycloak to expire tokens after one minute seems to be working; when tokens are marked as expired, the plugin reauths and requests proceed as normal. Note that I only use the resource creation part of the plugin; more testing is required before I could call this a complete fix.
1 parent f3512be commit fc4b27d

File tree

1 file changed

+8
-18
lines changed

1 file changed

+8
-18
lines changed

src/service.ts

+8-18
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Logger, InternalServerErrorException, Global } from '@nestjs/common'
2-
import AdminClient from 'keycloak-admin'
32
import { Client, Issuer, TokenSet } from 'openid-client'
43
import { resolve } from 'url'
54
import { ResourceManager } from './lib/resource-manager'
@@ -24,7 +23,6 @@ export class KeycloakService {
2423
public connect: Keycloak
2524
public permissionManager!: PermissionManager
2625
public resourceManager!: ResourceManager
27-
public client: AdminClient
2826

2927
constructor(options: KeycloakModuleOptions) {
3028
if (!options.baseUrl.startsWith('http')) {
@@ -46,10 +44,6 @@ export class KeycloakService {
4644
}
4745

4846
this.connect = keycloak as Keycloak
49-
this.client = new AdminClient({
50-
baseUrl: this.options.baseUrl,
51-
realmName: this.options.realmName,
52-
})
5347

5448
this.requestManager = new RequestManager(this, this.baseUrl)
5549
}
@@ -67,12 +61,6 @@ export class KeycloakService {
6761
this.resourceManager = new ResourceManager(this, data.resource_registration_endpoint)
6862
this.permissionManager = new PermissionManager(this, data.token_endpoint)
6963

70-
await this.client.auth({
71-
clientId,
72-
clientSecret,
73-
grantType: 'client_credentials',
74-
} as any)
75-
7664
const keycloakIssuer = await Issuer.discover(data.issuer)
7765

7866
this.issuerClient = new keycloakIssuer.Client({
@@ -104,18 +92,20 @@ export class KeycloakService {
10492
const { refresh_token } = this.tokenSet
10593

10694
if (!refresh_token) {
107-
this.logger.warn(`Could not refresh token. Refresh token is missing.`)
108-
return null
95+
this.logger.log(`Refresh token is missing. Reauthenticating.`)
96+
97+
const { clientId, clientSecret } = this.options
98+
return (this.tokenSet = await this.issuerClient?.grant({
99+
clientId,
100+
clientSecret,
101+
grant_type: 'client_credentials',
102+
}))
109103
}
110104

111105
this.logger.verbose(`Refreshing grant token`)
112106

113107
this.tokenSet = await this.issuerClient?.refresh(refresh_token)
114108

115-
if (this.tokenSet?.access_token) {
116-
this.client.setAccessToken(this.tokenSet.access_token)
117-
}
118-
119109
return this.tokenSet
120110
}
121111
}

0 commit comments

Comments
 (0)