keycloak-angular
Version:
Easy Keycloak integration for Angular applications.
1,189 lines (1,167 loc) • 61.9 kB
TypeScript
import { HttpRequest, HttpHeaders, HttpInterceptor, HttpHandler, HttpEvent, HttpHandlerFn } from '@angular/common/http';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, CanActivateFn, CanActivateChildFn } from '@angular/router';
import * as rxjs from 'rxjs';
import { Subject, Observable } from 'rxjs';
import * as Keycloak$1 from 'keycloak-js';
import Keycloak__default, { KeycloakError, KeycloakConfig, KeycloakInitOptions } from 'keycloak-js';
import * as i0 from '@angular/core';
import { InjectionToken, OnDestroy, Signal, Provider, EnvironmentProviders } from '@angular/core';
import * as i1 from '@angular/common';
/**
* @license
* Copyright Mauricio Gemelli Vigolo and contributors.
*
* Use of this source code is governed by a MIT-style license that can be
* found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md
*/
/**
* Keycloak event types, as described at the keycloak-js documentation:
* https://www.keycloak.org/docs/latest/securing_apps/index.html#callback-events
*
* @deprecated Keycloak Event based on the KeycloakService is deprecated and
* will be removed in future versions.
* Use the new `KEYCLOAK_EVENT_SIGNAL` injection token to listen for the keycloak
* events.
* More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md
*/
declare enum KeycloakEventTypeLegacy {
/**
* Called if there was an error during authentication.
*/
OnAuthError = 0,
/**
* Called if the user is logged out
* (will only be called if the session status iframe is enabled, or in Cordova mode).
*/
OnAuthLogout = 1,
/**
* Called if there was an error while trying to refresh the token.
*/
OnAuthRefreshError = 2,
/**
* Called when the token is refreshed.
*/
OnAuthRefreshSuccess = 3,
/**
* Called when a user is successfully authenticated.
*/
OnAuthSuccess = 4,
/**
* Called when the adapter is initialized.
*/
OnReady = 5,
/**
* Called when the access token is expired. If a refresh token is available the token
* can be refreshed with updateToken, or in cases where it is not (that is, with implicit flow)
* you can redirect to login screen to obtain a new access token.
*/
OnTokenExpired = 6,
/**
* Called when a AIA has been requested by the application.
*/
OnActionUpdate = 7
}
/**
* Structure of an event triggered by Keycloak, contains it's type
* and arguments (if any).
*
* @deprecated Keycloak Event based on the KeycloakService is deprecated and
* will be removed in future versions.
* Use the new `KEYCLOAK_EVENT_SIGNAL` injection token to listen for the keycloak
* events.
* More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md
*/
interface KeycloakEventLegacy {
/**
* Event type as described at {@link KeycloakEventTypeLegacy}.
*/
type: KeycloakEventTypeLegacy;
/**
* Arguments from the keycloak-js event function.
*/
args?: unknown;
}
/**
* @license
* Copyright Mauricio Gemelli Vigolo and contributors.
*
* Use of this source code is governed by a MIT-style license that can be
* found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md
*/
/**
* HTTP Methods
*
* @deprecated KeycloakBearerInterceptor is deprecated and will be removed in future versions.
* Use the new functional interceptor `includeBearerTokenInterceptor`.
* More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md
*/
type HttpMethodsLegacy = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH';
/**
* ExcludedUrl type may be used to specify the url and the HTTP method that
* should not be intercepted by the KeycloakBearerInterceptor.
*
* Example:
* const excludedUrl: ExcludedUrl[] = [
* {
* url: 'reports/public'
* httpMethods: ['GET']
* }
* ]
*
* In the example above for URL reports/public and HTTP Method GET the
* bearer will not be automatically added.
*
* If the url is informed but httpMethod is undefined, then the bearer
* will not be added for all HTTP Methods.
*
* @deprecated KeycloakBearerInterceptor is deprecated and will be removed in future versions.
* Use the new functional interceptor `includeBearerTokenInterceptor`.
* More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md
*/
interface ExcludedUrl {
url: string;
httpMethods?: HttpMethodsLegacy[];
}
/**
* Similar to ExcludedUrl, contains the HTTP methods and a regex to
* include the url patterns.
* This interface is used internally by the KeycloakService.
*
* @deprecated KeycloakBearerInterceptor is deprecated and will be removed in future versions.
* Use the new functional interceptor `includeBearerTokenInterceptor`.
* More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md
*/
interface ExcludedUrlRegex {
urlPattern: RegExp;
httpMethods?: HttpMethodsLegacy[];
}
/**
* keycloak-angular initialization options.
*
* @deprecated KeycloakService is deprecated and will be removed in future versions.
* Use the new `provideKeycloak` method to load Keycloak in an Angular application.
* More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md
*/
interface KeycloakOptions {
/**
* Configs to init the keycloak-js library. If undefined, will look for a keycloak.json file
* at root of the project.
* If not undefined, can be a string meaning the url to the keycloak.json file or an object
* of {@link Keycloak.KeycloakConfig}. Use this configuration if you want to specify the keycloak server,
* realm, clientId. This is usefull if you have different configurations for production, stage
* and development environments. Hint: Make use of Angular environment configuration.
*/
config?: string | Keycloak.KeycloakConfig;
/**
* Options to initialize the Keycloak adapter, matches the options as provided by Keycloak itself.
*/
initOptions?: Keycloak.KeycloakInitOptions;
/**
* By default all requests made by Angular HttpClient will be intercepted in order to
* add the bearer in the Authorization Http Header. However, if this is a not desired
* feature, the enableBearerInterceptor must be false.
*
* Briefly, if enableBearerInterceptor === false, the bearer will not be added
* to the authorization header.
*
* The default value is true.
*/
enableBearerInterceptor?: boolean;
/**
* Forces the execution of loadUserProfile after the keycloak initialization considering that the
* user logged in.
* This option is recommended if is desirable to have the user details at the beginning,
* so after the login, the loadUserProfile function will be called and its value cached.
*
* The default value is true.
*/
loadUserProfileAtStartUp?: boolean;
/**
* @deprecated
* String Array to exclude the urls that should not have the Authorization Header automatically
* added. This library makes use of Angular Http Interceptor, to automatically add the Bearer
* token to the request.
*/
bearerExcludedUrls?: (string | ExcludedUrl)[];
/**
* This value will be used as the Authorization Http Header name. The default value is
* **Authorization**. If the backend expects requests to have a token in a different header, you
* should change this value, i.e: **JWT-Authorization**. This will result in a Http Header
* Authorization as "JWT-Authorization: bearer <token>".
*/
authorizationHeaderName?: string;
/**
* This value will be included in the Authorization Http Header param. The default value is
* **Bearer**, which will result in a Http Header Authorization as "Authorization: Bearer <token>".
*
* If any other value is needed by the backend in the authorization header, you should change this
* value.
*
* Warning: this value must be in compliance with the keycloak server instance and the adapter.
*/
bearerPrefix?: string;
/**
* This value will be used to determine whether or not the token needs to be updated. If the token
* will expire is fewer seconds than the updateMinValidity value, then it will be updated.
*
* The default value is 20.
*/
updateMinValidity?: number;
/**
* A function that will tell the KeycloakBearerInterceptor whether to add the token to the request
* or to leave the request as it is. If the returned value is `true`, the request will have the token
* present on it. If it is `false`, the token will be left off the request.
*
* The default is a function that always returns `true`.
*/
shouldAddToken?: (request: HttpRequest<unknown>) => boolean;
/**
* A function that will tell the KeycloakBearerInterceptor if the token should be considered for
* updating as a part of the request being made. If the returned value is `true`, the request will
* check the token's expiry time and if it is less than the number of seconds configured by
* updateMinValidity then it will be updated before the request is made. If the returned value is
* false, the token will not be updated.
*
* The default is a function that always returns `true`.
*/
shouldUpdateToken?: (request: HttpRequest<unknown>) => boolean;
}
/**
* Service to expose existent methods from the Keycloak JS adapter, adding new
* functionalities to improve the use of keycloak in Angular v > 4.3 applications.
*
* This class should be injected in the application bootstrap, so the same instance will be used
* along the web application.
*
* @deprecated This service is deprecated and will be removed in future versions.
* Use the new `provideKeycloak` function to load Keycloak in an Angular application.
* More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md
*/
declare class KeycloakService {
/**
* Keycloak-js instance.
*/
private _instance;
/**
* User profile as KeycloakProfile interface.
*/
private _userProfile;
/**
* Flag to indicate if the bearer will not be added to the authorization header.
*/
private _enableBearerInterceptor;
/**
* When the implicit flow is choosen there must exist a silentRefresh, as there is
* no refresh token.
*/
private _silentRefresh;
/**
* Indicates that the user profile should be loaded at the keycloak initialization,
* just after the login.
*/
private _loadUserProfileAtStartUp;
/**
* The bearer prefix that will be appended to the Authorization Header.
*/
private _bearerPrefix;
/**
* Value that will be used as the Authorization Http Header name.
*/
private _authorizationHeaderName;
/**
* @deprecated
* The excluded urls patterns that must skip the KeycloakBearerInterceptor.
*/
private _excludedUrls;
/**
* Observer for the keycloak events
*/
private _keycloakEvents$;
/**
* The amount of required time remaining before expiry of the token before the token will be refreshed.
*/
private _updateMinValidity;
/**
* Returns true if the request should have the token added to the headers by the KeycloakBearerInterceptor.
*/
shouldAddToken: (request: HttpRequest<unknown>) => boolean;
/**
* Returns true if the request being made should potentially update the token.
*/
shouldUpdateToken: (request: HttpRequest<unknown>) => boolean;
/**
* Binds the keycloak-js events to the keycloakEvents Subject
* which is a good way to monitor for changes, if needed.
*
* The keycloakEvents returns the keycloak-js event type and any
* argument if the source function provides any.
*/
private bindsKeycloakEvents;
/**
* Loads all bearerExcludedUrl content in a uniform type: ExcludedUrl,
* so it becomes easier to handle.
*
* @param bearerExcludedUrls array of strings or ExcludedUrl that includes
* the url and HttpMethod.
*/
private loadExcludedUrls;
/**
* Handles the class values initialization.
*
* @param options
*/
private initServiceValues;
/**
* Keycloak initialization. It should be called to initialize the adapter.
* Options is an object with 2 main parameters: config and initOptions. The first one
* will be used to create the Keycloak instance. The second one are options to initialize the
* keycloak instance.
*
* @param options
* Config: may be a string representing the keycloak URI or an object with the
* following content:
* - url: Keycloak json URL
* - realm: realm name
* - clientId: client id
*
* initOptions:
* Options to initialize the Keycloak adapter, matches the options as provided by Keycloak itself.
*
* enableBearerInterceptor:
* Flag to indicate if the bearer will added to the authorization header.
*
* loadUserProfileInStartUp:
* Indicates that the user profile should be loaded at the keycloak initialization,
* just after the login.
*
* bearerExcludedUrls:
* String Array to exclude the urls that should not have the Authorization Header automatically
* added.
*
* authorizationHeaderName:
* This value will be used as the Authorization Http Header name.
*
* bearerPrefix:
* This value will be included in the Authorization Http Header param.
*
* tokenUpdateExcludedHeaders:
* Array of Http Header key/value maps that should not trigger the token to be updated.
*
* updateMinValidity:
* This value determines if the token will be refreshed based on its expiration time.
*
* @returns
* A Promise with a boolean indicating if the initialization was successful.
*/
init(options?: KeycloakOptions): Promise<boolean>;
/**
* Redirects to login form on (options is an optional object with redirectUri and/or
* prompt fields).
*
* @param options
* Object, where:
* - redirectUri: Specifies the uri to redirect to after login.
* - prompt:By default the login screen is displayed if the user is not logged-in to Keycloak.
* To only authenticate to the application if the user is already logged-in and not display the
* login page if the user is not logged-in, set this option to none. To always require
* re-authentication and ignore SSO, set this option to login .
* - maxAge: Used just if user is already authenticated. Specifies maximum time since the
* authentication of user happened. If user is already authenticated for longer time than
* maxAge, the SSO is ignored and he will need to re-authenticate again.
* - loginHint: Used to pre-fill the username/email field on the login form.
* - action: If value is 'register' then user is redirected to registration page, otherwise to
* login page.
* - locale: Specifies the desired locale for the UI.
* @returns
* A void Promise if the login is successful and after the user profile loading.
*/
login(options?: Keycloak.KeycloakLoginOptions): Promise<void>;
/**
* Redirects to logout.
*
* @param redirectUri
* Specifies the uri to redirect to after logout.
* @returns
* A void Promise if the logout was successful, cleaning also the userProfile.
*/
logout(redirectUri?: string): Promise<void>;
/**
* Redirects to registration form. Shortcut for login with option
* action = 'register'. Options are same as for the login method but 'action' is set to
* 'register'.
*
* @param options
* login options
* @returns
* A void Promise if the register flow was successful.
*/
register(options?: Keycloak.KeycloakLoginOptions): Promise<void>;
/**
* Check if the user has access to the specified role. It will look for roles in
* realm and the given resource, but will not check if the user is logged in for better performance.
*
* @param role
* role name
* @param resource
* resource name. If not specified, `clientId` is used
* @returns
* A boolean meaning if the user has the specified Role.
*/
isUserInRole(role: string, resource?: string): boolean;
/**
* Return the roles of the logged user. The realmRoles parameter, with default value
* true, will return the resource roles and realm roles associated with the logged user. If set to false
* it will only return the resource roles. The resource parameter, if specified, will return only resource roles
* associated with the given resource.
*
* @param realmRoles
* Set to false to exclude realm roles (only client roles)
* @param resource
* resource name If not specified, returns roles from all resources
* @returns
* Array of Roles associated with the logged user.
*/
getUserRoles(realmRoles?: boolean, resource?: string): string[];
/**
* Check if user is logged in.
*
* @returns
* A boolean that indicates if the user is logged in.
*/
isLoggedIn(): boolean;
/**
* Returns true if the token has less than minValidity seconds left before
* it expires.
*
* @param minValidity
* Seconds left. (minValidity) is optional. Default value is 0.
* @returns
* Boolean indicating if the token is expired.
*/
isTokenExpired(minValidity?: number): boolean;
/**
* If the token expires within _updateMinValidity seconds the token is refreshed. If the
* session status iframe is enabled, the session status is also checked.
* Returns a promise telling if the token was refreshed or not. If the session is not active
* anymore, the promise is rejected.
*
* @param minValidity
* Seconds left. (minValidity is optional, if not specified updateMinValidity - default 20 is used)
* @returns
* Promise with a boolean indicating if the token was succesfully updated.
*/
updateToken(minValidity?: number): Promise<boolean>;
/**
* Loads the user profile.
* Returns promise to set functions to be invoked if the profile was loaded
* successfully, or if the profile could not be loaded.
*
* @param forceReload
* If true will force the loadUserProfile even if its already loaded.
* @returns
* A promise with the KeycloakProfile data loaded.
*/
loadUserProfile(forceReload?: boolean): Promise<Keycloak$1.KeycloakProfile>;
/**
* Returns the authenticated token.
*/
getToken(): Promise<string>;
/**
* Returns the logged username.
*
* @returns
* The logged username.
*/
getUsername(): string;
/**
* Clear authentication state, including tokens. This can be useful if application
* has detected the session was expired, for example if updating token fails.
* Invoking this results in onAuthLogout callback listener being invoked.
*/
clearToken(): void;
/**
* Adds a valid token in header. The key & value format is:
* Authorization Bearer <token>.
* If the headers param is undefined it will create the Angular headers object.
*
* @param headers
* Updated header with Authorization and Keycloak token.
* @returns
* An observable with with the HTTP Authorization header and the current token.
*/
addTokenToHeader(headers?: HttpHeaders): rxjs.Observable<HttpHeaders>;
/**
* Returns the original Keycloak instance, if you need any customization that
* this Angular service does not support yet. Use with caution.
*
* @returns
* The KeycloakInstance from keycloak-js.
*/
getKeycloakInstance(): Keycloak.KeycloakInstance;
/**
* @deprecated
* Returns the excluded URLs that should not be considered by
* the http interceptor which automatically adds the authorization header in the Http Request.
*
* @returns
* The excluded urls that must not be intercepted by the KeycloakBearerInterceptor.
*/
get excludedUrls(): ExcludedUrlRegex[];
/**
* Flag to indicate if the bearer will be added to the authorization header.
*
* @returns
* Returns if the bearer interceptor was set to be disabled.
*/
get enableBearerInterceptor(): boolean;
/**
* Keycloak subject to monitor the events triggered by keycloak-js.
* The following events as available (as described at keycloak docs -
* https://www.keycloak.org/docs/latest/securing_apps/index.html#callback-events):
* - OnAuthError
* - OnAuthLogout
* - OnAuthRefreshError
* - OnAuthRefreshSuccess
* - OnAuthSuccess
* - OnReady
* - OnTokenExpire
* In each occurrence of any of these, this subject will return the event type,
* described at {@link KeycloakEventTypeLegacy} enum and the function args from the keycloak-js
* if provided any.
*
* @returns
* A subject with the {@link KeycloakEventLegacy} which describes the event type and attaches the
* function args.
*/
get keycloakEvents$(): Subject<KeycloakEventLegacy>;
static ɵfac: i0.ɵɵFactoryDeclaration<KeycloakService, never>;
static ɵprov: i0.ɵɵInjectableDeclaration<KeycloakService>;
}
/**
* @license
* Copyright Mauricio Gemelli Vigolo and contributors.
*
* Use of this source code is governed by a MIT-style license that can be
* found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md
*/
/**
* A simple guard implementation out of the box. This class should be inherited and
* implemented by the application. The only method that should be implemented is #isAccessAllowed.
* The reason for this is that the authorization flow is usually not unique, so in this way you will
* have more freedom to customize your authorization flow.
*
* @deprecated Class based guards are deprecated in Keycloak Angular and will be removed in future versions.
* Use the new `createAuthGuard` function to create a Guard for your application.
* More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md
*/
declare abstract class KeycloakAuthGuard implements CanActivate {
protected router: Router;
protected keycloakAngular: KeycloakService;
/**
* Indicates if the user is authenticated or not.
*/
protected authenticated: boolean;
/**
* Roles of the logged user. It contains the clientId and realm user roles.
*/
protected roles: string[];
constructor(router: Router, keycloakAngular: KeycloakService);
/**
* CanActivate checks if the user is logged in and get the full list of roles (REALM + CLIENT)
* of the logged user. This values are set to authenticated and roles params.
*
* @param route
* @param state
*/
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean | UrlTree>;
/**
* Create your own customized authorization flow in this method. From here you already known
* if the user is authenticated (this.authenticated) and the user roles (this.roles).
*
* Return a UrlTree if the user should be redirected to another route.
*
* @param route
* @param state
*/
abstract isAccessAllowed(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean | UrlTree>;
}
/**
* This interceptor includes the bearer by default in all HttpClient requests.
*
* If you need to exclude some URLs from adding the bearer, please, take a look
* at the {@link KeycloakOptions} bearerExcludedUrls property.
*
* @deprecated KeycloakBearerInterceptor is deprecated and will be removed in future versions.
* Use the new functional interceptor such as `includeBearerTokenInterceptor`.
* More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md
*/
declare class KeycloakBearerInterceptor implements HttpInterceptor {
private keycloak;
/**
* Calls to update the keycloak token if the request should update the token.
*
* @param req http request from @angular http module.
* @returns
* A promise boolean for the token update or noop result.
*/
private conditionallyUpdateToken;
/**
* @deprecated
* Checks if the url is excluded from having the Bearer Authorization
* header added.
*
* @param req http request from @angular http module.
* @param excludedUrlRegex contains the url pattern and the http methods,
* excluded from adding the bearer at the Http Request.
*/
private isUrlExcluded;
/**
* Intercept implementation that checks if the request url matches the excludedUrls.
* If not, adds the Authorization header to the request if the user is logged in.
*
* @param req
* @param next
*/
intercept(req: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>>;
/**
* Adds the token of the current user to the Authorization header
*
* @param req
* @param next
*/
private handleRequestWithTokenHeader;
static ɵfac: i0.ɵɵFactoryDeclaration<KeycloakBearerInterceptor, never>;
static ɵprov: i0.ɵɵInjectableDeclaration<KeycloakBearerInterceptor>;
}
/**
* @deprecated NgModules are deprecated in Keycloak Angular and will be removed in future versions.
* Use the new `provideKeycloak` function to load Keycloak in an Angular application.
* More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md
*/
declare class CoreModule {
static ɵfac: i0.ɵɵFactoryDeclaration<CoreModule, never>;
static ɵmod: i0.ɵɵNgModuleDeclaration<CoreModule, never, [typeof i1.CommonModule], never>;
static ɵinj: i0.ɵɵInjectorDeclaration<CoreModule>;
}
/**
* @deprecated NgModules are deprecated in Keycloak Angular and will be removed in future versions.
* Use the new `provideKeycloak` function to load Keycloak in an Angular application.
* More info: https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/migration-guides/v19.md
*/
declare class KeycloakAngularModule {
static ɵfac: i0.ɵɵFactoryDeclaration<KeycloakAngularModule, never>;
static ɵmod: i0.ɵɵNgModuleDeclaration<KeycloakAngularModule, never, [typeof CoreModule], never>;
static ɵinj: i0.ɵɵInjectorDeclaration<KeycloakAngularModule>;
}
/**
* Structural directive to conditionally display elements based on Keycloak user roles.
*
* This directive checks if the authenticated user has at least one of the specified roles.
* Roles can be validated against a specific **resource (client ID)** or the **realm**.
*
* ### Features:
* - Supports role checking in both **resources (client-level roles)** and the **realm**.
* - Accepts an array of roles to match.
* - Optional configuration to check realm-level roles.
*
* ### Inputs:
* - `kaHasRoles` (Required): Array of roles to validate.
* - `resource` (Optional): The client ID or resource name to validate resource-level roles.
* - `checkRealm` (Optional): A boolean flag to enable realm role validation (default is `false`).
*
* ### Requirements:
* - A Keycloak instance must be injected via Angular's dependency injection.
* - The user must be authenticated in Keycloak.
*
* @example
* #### Example 1: Check for Global Realm Roles
* Show the content only if the user has the `admin` or `editor` role in the realm.
* ```html
* <div *kaHasRoles="['admin', 'editor']; checkRealm:true">
* <p>This content is visible only to users with 'admin' or 'editor' realm roles.</p>
* </div>
* ```
*
* @example
* #### Example 2: Check for Resource Roles
* Show the content only if the user has the `read` or `write` role for a specific resource (`my-client`).
* ```html
* <div *kaHasRoles="['read', 'write']; resource:'my-client'">
* <p>This content is visible only to users with 'read' or 'write' roles for 'my-client'.</p>
* </div>
* ```
*
* @example
* #### Example 3: Check for Both Resource and Realm Roles
* Show the content if the user has the roles in either the realm or a resource.
* ```html
* <div *kaHasRoles="['admin', 'write']; resource:'my-client' checkRealm:true">
* <p>This content is visible to users with 'admin' in the realm or 'write' in 'my-client'.</p>
* </div>
* ```
*
* @example
* #### Example 4: Fallback Content When Roles Do Not Match
* Use an `<ng-template>` to display fallback content if the user lacks the required roles.
* ```html
* <div *kaHasRoles="['admin']; resource:'my-client'">
* <p>Welcome, Admin!</p>
* </div>
* <ng-template #noAccess>
* <p>Access Denied</p>
* </ng-template>
* ```
*/
declare class HasRolesDirective {
private templateRef;
private viewContainer;
private keycloak;
/**
* List of roles to validate against the resource or realm.
*/
roles: string[];
/**
* The resource (client ID) to validate roles against.
*/
resource?: string;
/**
* Flag to enable realm-level role validation.
*/
checkRealm: boolean;
constructor();
private render;
/**
* Checks if the user has at least one of the specified roles in the resource or realm.
* @returns True if the user has access, false otherwise.
*/
private checkUserRoles;
static ɵfac: i0.ɵɵFactoryDeclaration<HasRolesDirective, never>;
static ɵdir: i0.ɵɵDirectiveDeclaration<HasRolesDirective, "[kaHasRoles]", never, { "roles": { "alias": "kaHasRoles"; "required": false; }; "resource": { "alias": "kaHasRolesResource"; "required": false; }; "checkRealm": { "alias": "kaHasRolesCheckRealm"; "required": false; }; }, {}, never, never, true, never>;
}
/**
* @license
* Copyright Mauricio Gemelli Vigolo All Rights Reserved.
*
* Use of this source code is governed by a MIT-style license that can be
* found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md
*/
/**
* Represents a feature from keycloak-angular that can be configured during the library initialization.
*
* This type defines the structure of a feature that includes a `configure` method,
* which is responsible for setting up or initializing the feature's behavior or properties
* related to Keycloak.
*
* ### Usage:
* The `KeycloakFeature` type is typically used for defining modular, reusable Keycloak
* features that can be dynamically configured and integrated into an application.
*
* @property {() => void} configure - A method that initializes or configures the feature.
* This method is invoked to perform any setup or customization required for the feature.
*
* ### Example:
* ```typescript
* const withLoggingFeature: KeycloakFeature = {
* configure: () => {
* console.log('Configuring Keycloak logging feature');
* },
* };
*
* const withAnalyticsFeature: KeycloakFeature = {
* configure: () => {
* console.log('Configuring Keycloak analytics feature');
* },
* };
*
* // Configure and initialize features
* withLoggingFeature.configure();
* withAnalyticsFeature.configure();
* ```
*/
type KeycloakFeature = {
configure: () => void;
};
/**
* @license
* Copyright Mauricio Gemelli Vigolo All Rights Reserved.
*
* Use of this source code is governed by a MIT-style license that can be
* found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md
*/
/**
* Options for configuring the auto-refresh token feature.
*
* This type defines the configuration parameters for enabling auto-refresh
* of Keycloak tokens and handling session inactivity scenarios.
*/
type WithRefreshTokenOptions = {
/**
* The session timeout duration in milliseconds. This specifies the time
* of inactivity after which the session is considered expired.
*
* Default value: `300000` milliseconds (5 minutes).
*/
sessionTimeout?: number;
/**
* Action to take when the session timeout due to inactivity occurs.
*
* - `'login'`: Execute the `keycloak.login` method.
* - `'logout'`: Logs the user out by calling the `keycloak.logout` method.
* - `'none'`: Takes no action on session timeout.
*
* Default value: `'logout'`.
*/
onInactivityTimeout?: 'login' | 'logout' | 'none';
};
/**
* Enables automatic token refresh and session inactivity handling for a
* Keycloak-enabled Angular application.
*
* This function initializes a service that tracks user interactions, such as
* mouse movements, touches, key presses, clicks, and scrolls. If user activity
* is detected, it periodically calls `Keycloak.updateToken` to ensure the bearer
* token remains valid and does not expire.
*
* If the session remains inactive beyond the defined `sessionTimeout`, the
* specified action (`logout`, `login`, or `none`) will be executed. By default,
* the service will call `keycloak.logout` upon inactivity timeout.
*
* Event tracking uses RxJS observables with a debounce of 300 milliseconds to
* monitor user interactions. When the Keycloak `OnTokenExpired` event occurs,
* the service checks the user's last activity timestamp. If the user has been
* active within the session timeout period, it refreshes the token using `updateToken`.
*
*
* @param options - Configuration options for the auto-refresh token feature.
* - `sessionTimeout` (optional): The duration in milliseconds after which
* the session is considered inactive. Defaults to `300000` (5 minutes).
* - `onInactivityTimeout` (optional): The action to take when session inactivity
* exceeds the specified timeout. Defaults to `'logout'`.
* - `'login'`: Execute `keycloak.login` function.
* - `'logout'`: Logs the user out by calling `keycloak.logout`.
* - `'none'`: No action is taken.
*
* @returns A `KeycloakFeature` instance that configures and enables the
* auto-refresh token functionality.
*/
declare function withAutoRefreshToken(options?: WithRefreshTokenOptions): KeycloakFeature;
/**
* @license
* Copyright Mauricio Gemelli Vigolo All Rights Reserved.
*
* Use of this source code is governed by a MIT-style license that can be
* found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md
*/
/**
* Type representing the roles granted to a user, including both realm and resource-level roles.
*/
type Roles = {
/**
* Roles assigned at the realm level.
*/
realmRoles: string[];
/**
* Roles assigned at the resource level, organized by resource name.
*/
resourceRoles: {
[resource: string]: string[];
};
};
/**
* Data structure passed to the custom authorization guard to determine access.
*/
type AuthGuardData = {
/**
* Indicates whether the user is currently authenticated.
*/
authenticated: boolean;
/**
* A collection of roles granted to the user, including both realm and resource roles.
*/
grantedRoles: Roles;
/**
* The Keycloak instance managing the user's session and access.
*/
keycloak: Keycloak__default;
};
/**
* Creates a custom authorization guard for Angular routes, enabling fine-grained access control.
*
* This guard invokes the provided `isAccessAllowed` function to determine if access is permitted
* based on the current route, router state, and user's authentication and roles data.
*
* @template T - The type of the guard function (`CanActivateFn` or `CanActivateChildFn`).
* @param isAccessAllowed - A callback function that evaluates access conditions. The function receives:
* - `route`: The current `ActivatedRouteSnapshot` for the route being accessed.
* - `state`: The current `RouterStateSnapshot` representing the router's state.
* - `authData`: An `AuthGuardData` object containing the user's authentication status, roles, and Keycloak instance.
* @returns A guard function of type `T` that can be used as a route `canActivate` or `canActivateChild` guard.
*
* @example
* ```ts
* import { createAuthGuard } from './auth-guard';
* import { Routes } from '@angular/router';
*
* const isUserAllowed = async (route, state, authData) => {
* const { authenticated, grantedRoles } = authData;
* return authenticated && grantedRoles.realmRoles.includes('admin');
* };
*
* const routes: Routes = [
* {
* path: 'admin',
* canActivate: [createAuthGuard(isUserAllowed)],
* component: AdminComponent,
* },
* ];
* ```
*/
declare const createAuthGuard: <T extends CanActivateFn | CanActivateChildFn>(isAccessAllowed: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot, authData: AuthGuardData) => Promise<boolean | UrlTree>) => T;
/**
* @license
* Copyright Mauricio Gemelli Vigolo All Rights Reserved.
*
* Use of this source code is governed by a MIT-style license that can be
* found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md
*/
/**
* Represents the HTTP methods supported by the interceptor for authorization purposes.
*/
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH';
/**
* Common attributes for the Auth Bearer interceptor that can be reused in other interceptor implementations.
*/
type BearerTokenCondition = {
/**
* Prefix to be used in the Authorization header. Default is "Bearer".
* This will result in a header formatted as: `Authorization: Bearer <token>`.
*
* Adjust this value if your backend expects a different prefix in the Authorization header.
*/
bearerPrefix?: string;
/**
* Name of the HTTP header used for authorization. Default is "Authorization".
* Customize this value if your backend expects a different header, e.g., "JWT-Authorization".
*/
authorizationHeaderName?: string;
/**
* Function to determine whether the token should be updated before a request. Default is a function returning true.
* If the function returns `true`, the token's validity will be checked and updated if needed.
* If it returns `false`, the token update process will be skipped for that request.
*
* @param request - The current `HttpRequest` object being intercepted.
* @returns A boolean indicating whether to update the token.
*/
shouldUpdateToken?: (request: HttpRequest<unknown>) => boolean;
};
/**
* Generic factory function to create an interceptor condition with default values.
*
* This utility allows you to define custom interceptor conditions while ensuring that
* default values are applied to any missing fields. By using generics, you can enforce
* strong typing when creating the fields for the interceptor condition, enhancing type safety.
*
* @template T - A type that extends `AuthBearerCondition`.
* @param value - An object of type `T` (extending `AuthBearerCondition`) to be enhanced with default values.
* @returns A new object of type `T` with default values assigned to any undefined properties.
*/
declare const createInterceptorCondition: <T extends BearerTokenCondition>(value: T) => T;
/**
* Conditionally updates the Keycloak token based on the provided request and conditions.
*
* @param req - The `HttpRequest` object being processed.
* @param keycloak - The Keycloak instance managing authentication.
* @param condition - An `AuthBearerCondition` object with the `shouldUpdateToken` function.
* @returns A `Promise<boolean>` indicating whether the token was successfully updated.
*/
declare const conditionallyUpdateToken: (req: HttpRequest<unknown>, keycloak: Keycloak__default, { shouldUpdateToken }: BearerTokenCondition) => Promise<boolean>;
/**
* Adds the Authorization header to an HTTP request and forwards it to the next handler.
*
* @param req - The original `HttpRequest` object.
* @param next - The `HttpHandlerFn` function for forwarding the HTTP request.
* @param keycloak - The Keycloak instance providing the authentication token.
* @param condition - An `AuthBearerCondition` object specifying header configuration.
* @returns An `Observable<HttpEvent<unknown>>` representing the HTTP response.
*/
declare const addAuthorizationHeader: (req: HttpRequest<unknown>, next: HttpHandlerFn, keycloak: Keycloak__default, condition: BearerTokenCondition) => Observable<HttpEvent<unknown>>;
/**
* @license
* Copyright Mauricio Gemelli Vigolo All Rights Reserved.
*
* Use of this source code is governed by a MIT-style license that can be
* found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md
*/
/**
* Defines a custom condition for determining whether a Bearer token should be included
* in the `Authorization` header of an outgoing HTTP request.
*
* This type extends the `BearerTokenCondition` type and adds a dynamic function
* (`shouldAddToken`) that evaluates whether the token should be added based on the
* request, handler, and Keycloak state.
*/
type CustomBearerTokenCondition = Partial<BearerTokenCondition> & {
/**
* A function that dynamically determines whether the Bearer token should be included
* in the `Authorization` header for a given request.
*
* This function is asynchronous and receives the following arguments:
* - `req`: The `HttpRequest` object representing the current outgoing HTTP request.
* - `next`: The `HttpHandlerFn` for forwarding the request to the next handler in the chain.
* - `keycloak`: The `Keycloak` instance representing the authentication context.
*/
shouldAddToken: (req: HttpRequest<unknown>, next: HttpHandlerFn, keycloak: Keycloak__default) => Promise<boolean>;
};
/**
* Injection token for configuring the `customBearerTokenInterceptor`.
*
* This injection token holds an array of `CustomBearerTokenCondition` objects, which define
* the conditions under which a Bearer token should be included in the `Authorization` header
* of outgoing HTTP requests. Each condition provides a `shouldAddToken` function that dynamically
* determines whether the token should be added based on the request, handler, and Keycloak state.
*/
declare const CUSTOM_BEARER_TOKEN_INTERCEPTOR_CONFIG: InjectionToken<CustomBearerTokenCondition[]>;
/**
* Custom HTTP Interceptor for dynamically adding a Bearer token to requests based on conditions.
*
* This interceptor uses a flexible approach where the decision to include a Bearer token in the
* `Authorization` HTTP header is determined by a user-provided function (`shouldAddToken`).
* This enables a dynamic and granular control over when tokens are added to HTTP requests.
*
* ### Key Features:
* 1. **Dynamic Token Inclusion**: Uses a condition function (`shouldAddToken`) to decide dynamically
* whether to add the token based on the request, Keycloak state, and other factors.
* 2. **Token Management**: Optionally refreshes the Keycloak token before adding it to the request.
* 3. **Controlled Authorization**: Adds the Bearer token only when the condition function allows
* and the user is authenticated in Keycloak.
*
* ### Configuration:
* The interceptor relies on `CUSTOM_BEARER_TOKEN_INTERCEPTOR_CONFIG`, an injection token that contains
* an array of `CustomBearerTokenCondition` objects. Each condition specifies a `shouldAddToken` function
* that determines whether to add the Bearer token for a given request.
*
* ### Workflow:
* 1. Reads the conditions from the `CUSTOM_BEARER_TOKEN_INTERCEPTOR_CONFIG` injection token.
* 2. Iterates through the conditions and evaluates the `shouldAddToken` function for the request.
* 3. If a condition matches:
* - Optionally refreshes the Keycloak token if needed.
* - Adds the Bearer token to the request's `Authorization` header if the user is authenticated.
* 4. If no conditions match, the request proceeds unchanged.
*
* ### Parameters:
* @param req - The `HttpRequest` object representing the outgoing HTTP request.
* @param next - The `HttpHandlerFn` for passing the request to the next handler in the chain.
*
* @returns An `Observable<HttpEvent<unknown>>` representing the HTTP response.
*
* ### Usage Example:
* ```typescript
* // Define a custom condition to include the token
* const customCondition: CustomBearerTokenCondition = {
* shouldAddToken: async (req, next, keycloak) => {
* // Add token only for requests to the /api endpoint
* return req.url.startsWith('/api') && keycloak.authenticated;
* },
* };
*
* // Configure the interceptor with the custom condition
* export const appConfig: ApplicationConfig = {
* providers: [
* provideHttpClient(withInterceptors([customBearerTokenInterceptor])),
* {
* provide: CUSTOM_BEARER_TOKEN_INTERCEPTOR_CONFIG,
* useValue: [customCondition],
* },
* ],
* };
* ```
*/
declare const customBearerTokenInterceptor: (req: HttpRequest<unknown>, next: HttpHandlerFn) => Observable<HttpEvent<unknown>>;
/**
* @license
* Copyright Mauricio Gemelli Vigolo All Rights Reserved.
*
* Use of this source code is governed by a MIT-style license that can be
* found in the LICENSE file at https://github.com/mauriciovigolo/keycloak-angular/blob/main/LICENSE.md
*/
/**
* Defines the conditions for including the Bearer token in the Authorization HTTP header.
*/
type IncludeBearerTokenCondition = Partial<BearerTokenCondition> & {
/**
* A URL pattern (as a `RegExp`) used to determine whether the Bearer token should be added
* to the Authorization HTTP header for a given request. The Bearer token is only added if
* this pattern matches the request's URL.
*
* This EXPLICIT configuration is for security purposes, ensuring that internal tokens are not
* shared with unintended services.
*/
urlPattern: RegExp;
/**
* An optional array of HTTP methods (`HttpMethod[]`) to further refine the conditions under
* which the Bearer token is added. If not provided, the default behavior is to add the token
* for all HTTP methods matching the `urlPattern`.
*/
httpMethods?: HttpMethod[];
};
/**
* Injection token for configuring the `includeBearerTokenInterceptor`, allowing the specification
* of conditions under which the Bearer token should be included in HTTP request headers.
*
* This configuration supports multiple conditions, enabling customization for different URLs.
* It also provides options to tailor the Bearer prefix and the Authorization header name as needed.
*/
declare const INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG: InjectionToken<IncludeBearerTokenCondition[]>;
/**
* HTTP Interceptor to include a Bearer token in the Authorization header for specific HTTP requests.
*
* This interceptor ensures that a Bearer token is added to outgoing HTTP requests based on explicitly
* defined conditions. By default, the interceptor does not include the Bearer token unless the request
* matches the provided configuration (`IncludeBearerTokenCondition`). This approach enhances security
* by preventing sensitive tokens from being unintentionally sent to unauthorized services.
*
* ### Features:
* 1. **Explicit URL Matching**: The interceptor uses regular expressions to match URLs where the Bearer token should be included.
* 2. **HTTP Method Filtering**: Optional filtering by HTTP methods (e.g., `GET`, `POST`, `PUT`) to refine the conditions for adding the token.
* 3. **Token Management**: Ensures the Keycloak token is valid by optionally refreshing it before attaching it to the request.
* 4. **Controlled Authorization**: Sends the token only for requests where the user is authenticated, and the conditions match.
*
* ### Workflow:
* - Reads conditions from `INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG`, which specifies when the Bearer token should be included.
* - If a request matches the conditions:
* 1. The Keycloak token is refreshed if needed.
* 2. The Bearer token is added to the Authorization header.
* 3. The modified request is passed to the next handler.
* - If no conditions match, the request proceeds unchanged.
*
* ### Security:
* By explicitly defining URL patterns and optional HTTP methods, this interceptor prevents the leakage of tokens
* to unintended endpoints, such as third-party APIs or external services. This is especially critical for applications
* that interact with both internal and external services.
*
* @param req - The `HttpRequest` object representing the outgoing HTTP request.
* @param next - The `HttpHandlerFn` for passing the request to the next handler in the chain.
* @returns An `Observable<HttpEvent<unknown>>` representing the asynchronous HTTP response.
*
* ### Configuration:
* The interceptor relies on `INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG`, an injection token that holds
* an array of `IncludeBearerTokenCondition` objects. Each object defines the conditions for including
* the Bearer token in the request.
*
* #### Example Configuration:
* ```typescript
* provideHttpClient(
* withInterceptors([includeBearerTokenInterceptor]),
* {
* provide: INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG,
* useValue: [
* {
* urlPattern: /^https:\/\/api\.internal\.myapp\.com\/.*\/,
* httpMethods: ['GET', 'POST'], // Add the token only for GET and POST methods
* },
* ],
* }
* );
* ```
*
* ### Example Usage: