@slickteam/nestjs-keycloak 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +152 -28
- package/dist/index.d.ts +1 -1
- package/dist/index.js +15 -17
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,50 +1,174 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @slickteam/nestjs-keycloak
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Module NestJS pour intégrer facilement l'authentification Keycloak avec des guards pré-configurés.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@slickteam/nestjs-keycloak)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
## Fonctionnalités
|
|
9
|
+
|
|
10
|
+
- Configuration simplifiée via variables d'environnement
|
|
11
|
+
- Guards d'authentification et de rôles pré-configurés
|
|
12
|
+
- Décorateurs pour la gestion des accès (`@Public`, `@Roles`, `@Scopes`, `@Resource`)
|
|
13
|
+
- Interface TypeScript pour l'utilisateur Keycloak (`IKeycloakUser`)
|
|
14
|
+
- Support du mode de validation online/offline des tokens
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
8
17
|
|
|
9
18
|
```bash
|
|
10
|
-
npm
|
|
19
|
+
npm install @slickteam/nestjs-keycloak
|
|
11
20
|
```
|
|
12
21
|
|
|
13
|
-
|
|
22
|
+
## Configuration
|
|
23
|
+
|
|
24
|
+
### Variables d'environnement
|
|
25
|
+
|
|
26
|
+
Ajoutez ces variables dans votre fichier `.env` :
|
|
14
27
|
|
|
15
|
-
```
|
|
28
|
+
```env
|
|
29
|
+
# Obligatoires
|
|
16
30
|
KEYCLOAK_URL=http://localhost:8080
|
|
17
|
-
KEYCLOAK_REALM=
|
|
18
|
-
KEYCLOAK_CLIENT_ID=
|
|
19
|
-
KEYCLOAK_CLIENT_SECRET=
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
31
|
+
KEYCLOAK_REALM=my-realm
|
|
32
|
+
KEYCLOAK_CLIENT_ID=my-client
|
|
33
|
+
KEYCLOAK_CLIENT_SECRET=my-secret
|
|
34
|
+
|
|
35
|
+
# Optionnelles
|
|
36
|
+
KEYCLOAK_POLICY_ENFORCEMENT_MODE=permissive # permissive | enforcing
|
|
37
|
+
KEYCLOAK_TOKEN_VALIDATION=offline # online | offline | none
|
|
23
38
|
```
|
|
24
39
|
|
|
25
|
-
|
|
40
|
+
### Import du module
|
|
41
|
+
|
|
42
|
+
Importez `KeycloakModule` dans le module où vous souhaitez activer l'authentification :
|
|
26
43
|
|
|
27
|
-
```
|
|
44
|
+
```typescript
|
|
45
|
+
import { Module } from '@nestjs/common';
|
|
46
|
+
import { ConfigModule } from '@nestjs/config';
|
|
28
47
|
import { KeycloakModule } from '@slickteam/nestjs-keycloak';
|
|
29
48
|
|
|
30
49
|
@Module({
|
|
31
|
-
imports: [KeycloakModule],
|
|
32
|
-
controllers: [],
|
|
33
|
-
providers: [],
|
|
34
|
-
exports: [],
|
|
50
|
+
imports: [ConfigModule.forRoot(), KeycloakModule],
|
|
35
51
|
})
|
|
36
|
-
class
|
|
52
|
+
export class AppModule {}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
> **Note** : Le `ConfigModule` de NestJS doit être importé pour que les variables d'environnement soient accessibles.
|
|
56
|
+
|
|
57
|
+
## Utilisation
|
|
58
|
+
|
|
59
|
+
### Routes publiques
|
|
60
|
+
|
|
61
|
+
Par défaut, toutes les routes sont protégées. Utilisez le décorateur `@Public()` pour rendre une route accessible sans authentification :
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { Controller, Get } from '@nestjs/common';
|
|
65
|
+
import { Public } from '@slickteam/nestjs-keycloak';
|
|
66
|
+
|
|
67
|
+
@Controller('health')
|
|
68
|
+
export class HealthController {
|
|
69
|
+
@Get()
|
|
70
|
+
@Public()
|
|
71
|
+
check() {
|
|
72
|
+
return { status: 'ok' };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Restriction par rôles
|
|
78
|
+
|
|
79
|
+
Utilisez le décorateur `@Roles()` pour restreindre l'accès à certains rôles :
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { Controller, Get } from '@nestjs/common';
|
|
83
|
+
import { Roles } from '@slickteam/nestjs-keycloak';
|
|
84
|
+
|
|
85
|
+
@Controller('admin')
|
|
86
|
+
export class AdminController {
|
|
87
|
+
@Get()
|
|
88
|
+
@Roles({ roles: ['admin'] })
|
|
89
|
+
getAdminData() {
|
|
90
|
+
return { message: 'Admin only' };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Récupérer l'utilisateur connecté
|
|
96
|
+
|
|
97
|
+
Utilisez le décorateur `@KeycloakUser()` pour accéder aux informations de l'utilisateur :
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
import { Controller, Get } from '@nestjs/common';
|
|
101
|
+
import { IKeycloakUser, KeycloakUser } from '@slickteam/nestjs-keycloak';
|
|
102
|
+
|
|
103
|
+
@Controller('profile')
|
|
104
|
+
export class ProfileController {
|
|
105
|
+
@Get()
|
|
106
|
+
getProfile(@KeycloakUser() user: IKeycloakUser) {
|
|
107
|
+
return {
|
|
108
|
+
id: user.sub,
|
|
109
|
+
email: user.email,
|
|
110
|
+
name: user.name,
|
|
111
|
+
roles: user.realm_access.roles,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
37
115
|
```
|
|
38
116
|
|
|
39
|
-
##
|
|
117
|
+
## API
|
|
118
|
+
|
|
119
|
+
### Exports disponibles
|
|
120
|
+
|
|
121
|
+
| Export | Description |
|
|
122
|
+
| ----------------------- | ------------------------------------------- |
|
|
123
|
+
| `KeycloakModule` | Module principal à importer |
|
|
124
|
+
| `IKeycloakUser` | Interface TypeScript de l'utilisateur |
|
|
125
|
+
| `KeycloakUser` | Décorateur pour injecter l'utilisateur |
|
|
126
|
+
| `Public` | Décorateur pour les routes publiques |
|
|
127
|
+
| `Roles` | Décorateur pour restreindre par rôles |
|
|
128
|
+
| `Scopes` | Décorateur pour restreindre par scopes |
|
|
129
|
+
| `Resource` | Décorateur pour définir une ressource |
|
|
130
|
+
| `AuthGuard` | Guard d'authentification |
|
|
131
|
+
| `RoleGuard` | Guard de vérification des rôles |
|
|
132
|
+
| `ResourceGuard` | Guard de vérification des ressources |
|
|
133
|
+
| `PolicyEnforcementMode` | Enum des modes d'application des politiques |
|
|
134
|
+
| `TokenValidation` | Enum des modes de validation des tokens |
|
|
135
|
+
| `EnforcerOptions` | Options de configuration de l'enforcer |
|
|
136
|
+
|
|
137
|
+
### Interface `IKeycloakUser`
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
interface IKeycloakUser {
|
|
141
|
+
exp: number; // Timestamp d'expiration du token
|
|
142
|
+
iat: number; // Timestamp d'émission du token
|
|
143
|
+
auth_time: number; // Timestamp d'authentification de la session
|
|
144
|
+
iss: string; // URL de l'émetteur
|
|
145
|
+
sub: string; // ID utilisateur Keycloak
|
|
146
|
+
aud: string; // Audience
|
|
147
|
+
typ: string; // Type de token
|
|
148
|
+
realm_access: {
|
|
149
|
+
roles: string[]; // Rôles du realm
|
|
150
|
+
};
|
|
151
|
+
sid: string; // ID de session
|
|
152
|
+
scope: string; // Scopes accordés
|
|
153
|
+
email_verified: boolean; // Email vérifié
|
|
154
|
+
email: string; // Adresse email
|
|
155
|
+
name: string; // Nom complet
|
|
156
|
+
given_name: string; // Prénom
|
|
157
|
+
family_name: string; // Nom de famille
|
|
158
|
+
preferred_username: string; // Nom d'utilisateur
|
|
159
|
+
}
|
|
160
|
+
```
|
|
40
161
|
|
|
41
|
-
|
|
162
|
+
## Dépendances
|
|
42
163
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
164
|
+
| Package | Version |
|
|
165
|
+
| ----------------------- | -------------- |
|
|
166
|
+
| `@nestjs/common` | ^11.1 |
|
|
167
|
+
| `@nestjs/config` | ^4.0 |
|
|
168
|
+
| `@nestjs/core` | ^11.1 |
|
|
169
|
+
| `keycloak-connect` | ^26.1.1 |
|
|
170
|
+
| `nest-keycloak-connect` | ^2.0.0-alpha.2 |
|
|
46
171
|
|
|
47
|
-
|
|
172
|
+
## Licence
|
|
48
173
|
|
|
49
|
-
|
|
50
|
-
- `nest-keycloak-connect`: `^2.0.0-alpha.2`
|
|
174
|
+
[MIT](LICENSE) - Slickteam
|
package/dist/index.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ import { AuthGuard, EnforcerOptions, KeycloakUser, PolicyEnforcementMode, Public
|
|
|
2
2
|
import { IKeycloakUser } from './keycloak.interface';
|
|
3
3
|
declare class KeycloakModule {
|
|
4
4
|
}
|
|
5
|
-
export {
|
|
5
|
+
export { AuthGuard, EnforcerOptions, IKeycloakUser, KeycloakModule, KeycloakUser, PolicyEnforcementMode, Public, Resource, ResourceGuard, RoleGuard, Roles, Scopes, TokenValidation, };
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
7
|
};
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.
|
|
9
|
+
exports.TokenValidation = exports.Scopes = exports.Roles = exports.RoleGuard = exports.ResourceGuard = exports.Resource = exports.Public = exports.PolicyEnforcementMode = exports.KeycloakUser = exports.KeycloakModule = exports.EnforcerOptions = exports.AuthGuard = void 0;
|
|
10
10
|
const common_1 = require("@nestjs/common");
|
|
11
11
|
const config_1 = require("@nestjs/config");
|
|
12
12
|
const core_1 = require("@nestjs/core");
|
|
@@ -29,26 +29,24 @@ exports.KeycloakModule = KeycloakModule = __decorate([
|
|
|
29
29
|
(0, common_1.Module)({
|
|
30
30
|
imports: [
|
|
31
31
|
nest_keycloak_connect_1.KeycloakConnectModule.registerAsync({
|
|
32
|
-
useFactory: (configService) =>
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
useFactory: (configService) => {
|
|
33
|
+
const policyEnforcement = configService.get('KEYCLOAK_POLICY_ENFORCEMENT_MODE') ?? nest_keycloak_connect_1.PolicyEnforcementMode.PERMISSIVE;
|
|
34
|
+
const tokenValidation = configService.get('KEYCLOAK_TOKEN_VALIDATION') ?? nest_keycloak_connect_1.TokenValidation.OFFLINE;
|
|
35
|
+
return {
|
|
36
|
+
authServerUrl: configService.getOrThrow('KEYCLOAK_URL'),
|
|
37
|
+
realm: configService.getOrThrow('KEYCLOAK_REALM'),
|
|
38
|
+
clientId: configService.getOrThrow('KEYCLOAK_CLIENT_ID'),
|
|
39
|
+
secret: configService.getOrThrow('KEYCLOAK_CLIENT_SECRET'),
|
|
40
|
+
policyEnforcement,
|
|
41
|
+
tokenValidation,
|
|
42
|
+
};
|
|
43
|
+
},
|
|
40
44
|
inject: [config_1.ConfigService],
|
|
41
45
|
}),
|
|
42
46
|
],
|
|
43
47
|
providers: [
|
|
44
|
-
{
|
|
45
|
-
|
|
46
|
-
useClass: nest_keycloak_connect_1.AuthGuard,
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
provide: core_1.APP_GUARD,
|
|
50
|
-
useClass: nest_keycloak_connect_1.RoleGuard,
|
|
51
|
-
},
|
|
48
|
+
{ provide: core_1.APP_GUARD, useClass: nest_keycloak_connect_1.AuthGuard },
|
|
49
|
+
{ provide: core_1.APP_GUARD, useClass: nest_keycloak_connect_1.RoleGuard },
|
|
52
50
|
],
|
|
53
51
|
})
|
|
54
52
|
], KeycloakModule);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,2CAA+C;AAC/C,uCAAyC;AACzC,iEAa+B;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,2CAA+C;AAC/C,uCAAyC;AACzC,iEAa+B;AA+B7B,0FA3CA,iCAAS,OA2CA;AACT,gGA3CA,uCAAe,OA2CA;AAGf,6FA5CA,oCAAY,OA4CA;AACZ,sGA5CA,6CAAqB,OA4CA;AACrB,uFA5CA,8BAAM,OA4CA;AACN,yFA5CA,gCAAQ,OA4CA;AACR,8FA5CA,qCAAa,OA4CA;AACb,0FA5CA,iCAAS,OA4CA;AACT,sFA5CA,6BAAK,OA4CA;AACL,uFA5CA,8BAAM,OA4CA;AACN,gGA5CA,uCAAe,OA4CA;AAfjB,IAAM,cAAc,GAApB,MAAM,cAAc;CAAG,CAAA;AAMrB,wCAAc;yBANV,cAAc;IAxBnB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE;YACP,6CAAqB,CAAC,aAAa,CAAC;gBAClC,UAAU,EAAE,CAAC,aAA4B,EAAE,EAAE;oBAC3C,MAAM,iBAAiB,GAAG,aAAa,CAAC,GAAG,CAAC,kCAAkC,CAAC,IAAI,6CAAqB,CAAC,UAAU,CAAC;oBACpH,MAAM,eAAe,GAAG,aAAa,CAAC,GAAG,CAAC,2BAA2B,CAAC,IAAI,uCAAe,CAAC,OAAO,CAAC;oBAElG,OAAO;wBACL,aAAa,EAAE,aAAa,CAAC,UAAU,CAAC,cAAc,CAAC;wBACvD,KAAK,EAAE,aAAa,CAAC,UAAU,CAAC,gBAAgB,CAAC;wBACjD,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,oBAAoB,CAAC;wBACxD,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,wBAAwB,CAAC;wBAC1D,iBAAiB;wBACjB,eAAe;qBAChB,CAAC;gBACJ,CAAC;gBACD,MAAM,EAAE,CAAC,sBAAa,CAAC;aACxB,CAAC;SACH;QACD,SAAS,EAAE;YACT,EAAE,OAAO,EAAE,gBAAS,EAAE,QAAQ,EAAE,iCAAS,EAAE;YAC3C,EAAE,OAAO,EAAE,gBAAS,EAAE,QAAQ,EAAE,iCAAS,EAAE;SAC5C;KACF,CAAC;GACI,cAAc,CAAG"}
|