{"id":13806495,"url":"https://github.com/mauriciovigolo/keycloak-angular","last_synced_at":"2025-05-13T21:11:41.662Z","repository":{"id":37432339,"uuid":"102657858","full_name":"mauriciovigolo/keycloak-angular","owner":"mauriciovigolo","description":"Easy Keycloak integration for Angular applications.","archived":false,"fork":false,"pushed_at":"2025-02-02T01:48:00.000Z","size":5993,"stargazers_count":787,"open_issues_count":37,"forks_count":298,"subscribers_count":34,"default_branch":"main","last_synced_at":"2025-05-12T03:01:43.012Z","etag":null,"topics":["angular","keycloak","keycloak-adapter","keycloak-js"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mauriciovigolo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-09-06T21:00:42.000Z","updated_at":"2025-05-10T02:44:04.000Z","dependencies_parsed_at":"2023-10-16T11:40:04.475Z","dependency_job_id":"1add4be6-eb93-44d0-9555-ac34ea8e949f","html_url":"https://github.com/mauriciovigolo/keycloak-angular","commit_stats":{"total_commits":462,"total_committers":35,"mean_commits":13.2,"dds":"0.36796536796536794","last_synced_commit":"9a002d517a6e45c34c1730affe6fa10044bba6dc"},"previous_names":[],"tags_count":72,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mauriciovigolo%2Fkeycloak-angular","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mauriciovigolo%2Fkeycloak-angular/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mauriciovigolo%2Fkeycloak-angular/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mauriciovigolo%2Fkeycloak-angular/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mauriciovigolo","download_url":"https://codeload.github.com/mauriciovigolo/keycloak-angular/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254029004,"owners_count":22002283,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","keycloak","keycloak-adapter","keycloak-js"],"created_at":"2024-08-04T01:01:12.469Z","updated_at":"2025-05-13T21:11:36.645Z","avatar_url":"https://github.com/mauriciovigolo.png","language":"TypeScript","readme":"# Keycloak Angular\n\n\u003c!-- prettier-ignore-start --\u003e\n[![License: MIT][license-mit-badge]][license-mit]\n[![Build Status][build-badge]][build]\n[![Known Vulnerabilities][vulnerabilities-badge]][vulnerabilities]\n[![npm version][npm-version-badge]][npm]\n[![npm][npm-badge]][npm]\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003e Easy Keycloak integration for Angular applications.\n\n---\n\n- [About](#about)\n- [Installation](#installation)\n- [Setup](#setup)\n- [Example project](#example-project)\n- [Keycloak Angular Features](#Keycloak-angular-features)\n- [Guards](#guards)\n- [HttpClient Interceptors](#httpclient-interceptors)\n- [Directives](#directives)\n- [Keycloak Events Signal](#keycloak-events-signal)\n- [Contributors](#contributors)\n- [License](#license)\n\n---\n\n## About\n\n`Keycloak-Angular` is a library that makes it easier to use [keycloak-js](https://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter) in Angular applications. It provides the following features:\n\n- **Easy Initialization**: Use the `provideKeycloak` function to set up and initialize a Keycloak instance with `provideAppInitializer`. This simplifies the setup process.\n- **Angular DI Support**: The Keycloak client instance can be injected directly into Angular components, services, and other parts of your app. There’s no need to create a custom service to wrap the client.\n- **HTTP Interceptors**: Add the Bearer token to the `Authorization` header with built-in interceptors. These are modular and easy to configure using injection tokens. You can also create your own interceptors with provided helper functions.\n- **Keycloak Events as Signals**: Access Keycloak events easily using Angular Signals, provided through the `KEYCLOAK_EVENT_SIGNAL` injection token.\n- **Automatic Token Refresh**: Use the `withAutoRefreshToken` feature to automatically refresh tokens when they expire, considering the user activity and a sessionTimeout.\n- **Custom Route Guards**: Use the `createAuthGuard` factory to build guards for `CanActivate` and `CanActivateChild`, helping you secure routes with custom logic.\n- **Role-Based Rendering**: The `*kaHasRoles` directive lets you show or hide parts of the DOM based on the user’s resource or realm roles.\n\n## Installation\n\nRun the following command to install both Keycloak Angular and the official Keycloak client library:\n\n```sh\nnpm install keycloak-angular keycloak-js\n```\n\nNote that `keycloak-js` is a peer dependency of `keycloak-angular`. This allows greater flexibility of choosing the right version of the Keycloak client for your project.\n\n### Versions\n\n| Angular | keycloak-js | keycloak-angular |       Support       |\n| :-----: | :---------: | :--------------: | :-----------------: |\n|  19.x   |   18 - 26   |      19.x.x      | New Features / Bugs |\n|  18.x   |   18 - 26   |      16.x.x      |        Bugs         |\n|  17.x   |   18 - 25   |      15.x.x      |          -          |\n|  16.x   |   18 - 25   |      14.x.x      |          -          |\n|  15.x   |   18 - 21   |      13.x.x      |          -          |\n\n\u003e 1. Only the latest version of Angular listed in the table above is actively supported. This is because the compilation of Angular libraries can be [incompatible between major versions](https://angular.io/guide/creating-libraries#ensuring-library-version-compatibility).\n\u003e 2. Starting with Angular v19, Keycloak-Angular will adopt the same **major** version numbering as Angular, making it easier to identify the correct version to use.\n\n#### Choosing the right keycloak-js version\n\nThe Keycloak client documentation recommends to use the same version of your Keycloak server installation.\n\n## Setup\n\nTo initialize Keycloak, add `provideKeycloak` to the `providers` array in the `ApplicationConfig` object (e.g., in `app.config.ts`). If `initOptions` is included, `keycloak-angular` will automatically use `provideAppInitializer` to handle initialization, following the recommended approach for starting dependencies.\n\nUse the example code below as a guide for your application.\n\n```ts\nimport { provideRouter } from '@angular/router';\nimport { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';\nimport { provideKeycloak } from 'keycloak-angular';\n\nimport { routes } from './app.routes';\n\nexport const appConfig: ApplicationConfig = {\n  providers: [\n    provideKeycloak({\n      config: {\n        url: 'keycloak-server-url',\n        realm: 'realm-id',\n        clientId: 'client-id'\n      },\n      initOptions: {\n        onLoad: 'check-sso',\n        silentCheckSsoRedirectUri: window.location.origin + '/silent-check-sso.html'\n      }\n    }),\n    provideZoneChangeDetection({ eventCoalescing: true }),\n    provideRouter(routes)\n  ]\n};\n```\n\n\u003e **Important:**\n\u003e\n\u003e 1. You do not need to call `provideAppInitializer` if `initOptions` is provided. The library handles this automatically.\n\u003e 2. If you need to control when `keycloak.init` is called, do not pass the `initOptions` to the `provideKeycloak` function. In this case, you are responsible for calling `keycloak.init` manually.\n\u003e 3. For reference, Angular's `APP_INITIALIZER` is deprecated. The recommended approach is to use `provideAppInitializer`.\n\nIn the example, Keycloak is configured to use a silent `check-sso`. With this feature enabled, your browser avoids a full redirect to the Keycloak server and back to your application. Instead, this action is performed in a hidden iframe, allowing your application resources to be loaded and parsed only once during initialization, rather than reloading after a redirect.\n\nTo enable communication through the iframe, you need to serve a static HTML file from your application at the location specified in `silentCheckSsoRedirectUri`.\n\nCreate a file named `silent-check-sso.html` in the `public` or `assets` directory of your application and paste in the content shown below.\n\n```html\n\u003chtml\u003e\n  \u003cbody\u003e\n    \u003cscript\u003e\n      parent.postMessage(location.href, location.origin);\n    \u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\nIf you want to know more about these options and various other capabilities of the Keycloak client is recommended to read the [JavaScript Adapter documentation](https://www.keycloak.org/docs/latest/securing_apps/#_javascript_adapter).\n\n\u003e **Note About NgModules:**\n\u003e Since Keycloak-Angular v19, the KeycloakAngularModule, KeycloakService, KeycloakBearerInterceptor and KeycloakAuthGuard are deprecated.\n\u003e If your application relies on NgModules, the library still has support for it. See more information on how to configure a [NgModule the application](https://github.com/mauriciovigolo/keycloak-angular/docs/ngmodule.md).\n\n**Additional Resources**\nFor more details, refer to the [provideKeycloak](https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/provide.md) documentation.\n\n## Example project\n\nIf you want to see a complete overview a pre-configured client together with a working Keycloak server make sure to check out the [standalone example project](projects/examples/standalone/README.md) in this repository.\n\n## Keycloak Angular Features\n\nKeycloak Angular Features enhance the library's capabilities and make it more modular and composable. These features are executed during application initialization and have access to Angular's Dependency Injection (DI) context. While there is currently only one feature available, more features will be introduced over time to address new scenarios and expand functionality.\n\n### Usage\n\nThe example below adds the `withAutoRefreshToken` feature to Keycloak Angular. Note that this feature depends on two services provided by Keycloak Angular, which are: `AutoRefreshTokenService` and `UserActivityService`.\n\n```ts\nimport { provideKeycloak, withAutoRefreshToken, AutoRefreshTokenService, UserActivityService } from 'keycloak-angular';\n\nexport const provideKeycloakAngular = () =\u003e\n  provideKeycloak({\n    config: {\n      url: 'keycloak-server-url',\n      realm: 'realm-id',\n      clientId: 'client-id'\n    },\n    initOptions: {\n      onLoad: 'check-sso',\n      silentCheckSsoRedirectUri: window.location.origin + '/silent-check-sso.html'\n    },\n    features: [\n      withAutoRefreshToken({\n        onInactivityTimeout: 'logout',\n        sessionTimeout: 60000\n      })\n    ],\n    providers: [AutoRefreshTokenService, UserActivityService]\n  });\n\nexport const appConfig: ApplicationConfig = {\n  providers: [provideKeycloakAngular(), provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes)]\n};\n```\n\n## Guards\n\nThe `createAuthGuard` function is a higher-order function that simplifies the creation of guards relying on Keycloak data. It can be used to create `CanActivateFn` or `CanActivateChildFn` guards to protect the routes in your application.\n\n### Usage:\n\n```ts\nimport { ActivatedRouteSnapshot, CanActivateFn, Router, RouterStateSnapshot, UrlTree } from '@angular/router';\nimport { inject } from '@angular/core';\nimport { AuthGuardData, createAuthGuard } from 'keycloak-angular';\n\nconst isAccessAllowed = async (\n  route: ActivatedRouteSnapshot,\n  _: RouterStateSnapshot,\n  authData: AuthGuardData\n): Promise\u003cboolean | UrlTree\u003e =\u003e {\n  const { authenticated, grantedRoles } = authData;\n\n  const requiredRole = route.data['role'];\n  if (!requiredRole) {\n    return false;\n  }\n\n  const hasRequiredRole = (role: string): boolean =\u003e\n    Object.values(grantedRoles.resourceRoles).some((roles) =\u003e roles.includes(role));\n\n  if (authenticated \u0026\u0026 hasRequiredRole(requiredRole)) {\n    return true;\n  }\n\n  const router = inject(Router);\n  return router.parseUrl('/forbidden');\n};\n\nexport const canActivateAuthRole = createAuthGuard\u003cCanActivateFn\u003e(isAccessAllowed);\n```\n\nThe `canActivateAuthRole` can be used in the route configuration to protect specific routes.\n\n```ts\nimport { Routes } from '@angular/router';\n\nimport { HomeComponent } from './components/home/home.component';\nimport { BooksComponent } from './components/books/books.component';\nimport { canActivateAuthRole } from './guards/auth-role.guard';\n\nexport const routes: Routes = [\n  { path: '', component: HomeComponent },\n  {\n    path: 'books',\n    component: BooksComponent,\n    canActivate: [canActivateAuthRole],\n    data: { role: 'view-books' }\n  }\n];\n```\n\n## HttpClient Interceptors\n\nKeycloak Angular provides `HttpClient` interceptors for managing the Bearer Token in the HTTP request header.\n\n\u003e By default, the library **does not** add the Bearer token to requests. It is the application's responsibility to configure and use the appropriate interceptors.\n\u003e\n\u003e **Important:** This behavior is a significant change from previous versions of the library. The new approach is more declarative, secure, extendable and configurable. There are no services directly interacting with interceptors anymore. All configurations are handled within the interceptor itself.\n\n### Usage:\n\n```ts\nimport { provideRouter } from '@angular/router';\nimport { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';\nimport { provideHttpClient, withInterceptors } from '@angular/common/http';\nimport {\n  provideKeycloak,\n  createInterceptorCondition,\n  IncludeBearerTokenCondition,\n  INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG\n} from 'keycloak-angular';\n\nimport { routes } from './app.routes';\n\nconst urlCondition = createInterceptorCondition\u003cIncludeBearerTokenCondition\u003e({\n  urlPattern: /^(http:\\/\\/localhost:8181)(\\/.*)?$/i,\n  bearerPrefix: 'Bearer'\n});\n\nexport const appConfig: ApplicationConfig = {\n  providers: [\n    provideKeycloak({\n      config: {\n        url: 'keycloak-server-url',\n        realm: 'realm-id',\n        clientId: 'client-id'\n      },\n      initOptions: {\n        onLoad: 'check-sso',\n        silentCheckSsoRedirectUri: window.location.origin + '/silent-check-sso.html'\n      }\n    }),\n    {\n      provide: INCLUDE_BEARER_TOKEN_INTERCEPTOR_CONFIG,\n      useValue: [urlCondition] // \u003c-- Note that multiple conditions might be added.\n    },\n    provideZoneChangeDetection({ eventCoalescing: true }),\n    provideRouter(routes),\n    provideHttpClient(withInterceptors([includeBearerTokenInterceptor]))\n  ]\n};\n```\n\n**Additional Resources**\nFor more details on the available interceptors and their configurations, refer to the [Keycloak HttpClient Interceptors](https://github.com/mauriciovigolo/keycloak-angular/blob/main/docs/interceptors.md) documentation.\n\n## Directives\n\nThe library offers the `*kaHasRoles` structural directive to evaluate if the user has the required Realm or Resource Roles to render or not to render a DOM.\n\n### Usage\n\nIn the component, add the `HasRolesDirective` in the imports list.\n\n```ts\n@Component({\n  selector: 'app-menu',\n  imports: [RouterModule, HasRolesDirective],\n  templateUrl: './menu.component.html',\n  styleUrls: ['./menu.component.css']\n})\nexport class MenuComponent {}\n```\n\n```html\n\u003cnav class=\"menu\"\u003e\n  \u003cdiv class=\"developer-status\"\u003e\u003cstrong\u003eKeycloak Events:\u003c/strong\u003e {{ keycloakStatus }}\u003c/div\u003e\n\n  \u003cdiv class=\"actions\"\u003e\n    \u003ca routerLink=\"/\" class=\"action-item\"\u003eHome\u003c/a\u003e\n    \u003ca routerLink=\"/books\" class=\"action-item\" *kaHasRoles=\"['view-books']\"\u003eMy Books\u003c/a\u003e\n  \u003c/div\u003e\n\u003c/nav\u003e\n```\n\n\u003e **Note:**  \n\u003e If no resource is specified in `*kaHasRoles=\"['view-books']\"`, the default resource used will be the Keycloak application client ID.\n\n## Keycloak Events Signal\n\nKeycloak Angular provides a Signal that allows Angular applications to easily react to `keycloak-js` authorization and session events.\n\nThis Signal is created during the library's initialization and is available without any additional configuration. It can be accessed by injecting the `KEYCLOAK_EVENT_SIGNAL` injection token.\n\n### Usage\n\n```ts\n@Component({\n  selector: 'app-menu',\n  templateUrl: './menu.component.html',\n  styleUrls: ['./menu.component.css']\n})\nexport class MenuComponent {\n  authenticated = false;\n\n  constructor(private readonly keycloak: Keycloak) {\n    const keycloakSignal = inject(KEYCLOAK_EVENT_SIGNAL);\n\n    effect(() =\u003e {\n      const keycloakEvent = keycloakSignal();\n\n      if (keycloakEvent.type === KeycloakEventType.Ready) {\n        this.authenticated = typeEventArgs\u003cReadyArgs\u003e(keycloakEvent.args);\n      }\n\n      if (keycloakEvent.type === KeycloakEventType.AuthLogout) {\n        this.authenticated = false;\n      }\n    });\n  }\n}\n```\n\n## Contributors\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\n\u003c!-- prettier-ignore --\u003e\n | [\u003cimg src=\"https://avatars3.githubusercontent.com/u/676270?v=4\" width=\"89px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMauricio Vigolo\u003c/b\u003e\u003c/sub\u003e](https://github.com/mauriciovigolo)\u003cbr /\u003e | [\u003cimg src=\"https://avatars1.githubusercontent.com/u/695720?s=400\u0026v=4\" width=\"89px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eJon Koops\u003c/b\u003e\u003c/sub\u003e](https://github.com/https://github.com/jonkoops)\u003cbr /\u003e |\n | :--------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\nIf you want to contribute to the project, please check out the [contributing](CONTRIBUTING.md)\ndocument.\n\n## License\n\n**keycloak-angular** is licensed under the **[MIT license](LICENSE)**.\n\n\u003c!-- prettier-ignore-start --\u003e\n[license-mit-badge]: https://img.shields.io/badge/License-MIT-yellow\n[license-mit]: https://opensource.org/licenses/MIT\n[build-badge]: https://img.shields.io/github/actions/workflow/status/mauriciovigolo/keycloak-angular/main.yml?branch=main\u0026label=CI\u0026logo=github\n[build]: https://github.com/mauriciovigolo/keycloak-angular/actions/workflows/main.yml?query=branch%3Amain\n[vulnerabilities-badge]: https://snyk.io/test/github/mauriciovigolo/keycloak-angular/badge.svg\n[vulnerabilities]: https://snyk.io/test/github/mauriciovigolo/keycloak-angular\n[npm-version-badge]: https://img.shields.io/npm/v/keycloak-angular?logo=npm\u0026logoColor=fff\n[npm-badge]: https://img.shields.io/npm/dm/keycloak-angular?logo=npm\u0026logoColor=fff\n[npm]: https://www.npmjs.com/package/keycloak-angular\n[contributors-badge]: https://img.shields.io/badge/all_contributors-5-orange\n\u003c!-- prettier-ignore-end --\u003e\n","funding_links":[],"categories":["Security and Authentication"],"sub_categories":["Authentication"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmauriciovigolo%2Fkeycloak-angular","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmauriciovigolo%2Fkeycloak-angular","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmauriciovigolo%2Fkeycloak-angular/lists"}