keycloak angular adapter

 

keycloak官网并未提供 angular 应用的 adapter,

但是有第三方提供了,地址:

https://github.com/mauriciovigolo/keycloak-angular

 

Easy Keycloak setup for Angular applications (v>4.3)

 

About

This library helps you to use keycloak-js in Angular > v4.3 applications providing the following features:

  • Keycloak Service which wraps the keycloak-js methods to be used in Angular, giving extra functionalities to the original functions and adding new methods to make it easier to be consumed by Angular applications.
  • Generic AuthGuard implementation, so you can customize your own AuthGuard logic inheriting the authentication logic and the roles load.
  • HttpClient interceptor that adds the authorization header to all HttpClient requests. It is also possible to exclude routes from having the authorization header.
  • This documentation also assists you to configure the keycloak in the Angular applications and with the client setup in the admin console of your keycloak installation.

Install

Warning: This library will work only with versions higher or equal than 4.3.0 of Angular. The reason for this is that we are using Interceptor from @angular/common/http package.

In your angular application directory:

With npm:

npm install --save keycloak-angular

With yarn:

yarn add keycloak-angular

Setup

Angular

The KeycloakService should be initialized during the application loading, using the APP_INITIALIZER token.

AppModule

import { NgModule, APP_INITIALIZER } from '@angular/core';
import { KeycloakService, KeycloakAngularModule } from 'keycloak-angular';
import { initializer } from './utils/app-init';

@NgModule({
  imports: [KeycloakAngularModule],
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: initializer,
      multi: true,
      deps: [KeycloakService]
    }
  ]
})
export class AppModule {}
  • Notice that the KeycloakAngularModule was imported by the AppModule. For this reason you don't need to insert the KeycloakService in the AppModule providers array.

initializer Function

This function can be named and placed in the way you think is most appropriate. In the underneath example it was placed in a separate file app-init.ts and the function was called initializer.

import { KeycloakService } from 'keycloak-angular';

export function initializer(keycloak: KeycloakService): () => Promise<any> {
  return (): Promise<any> => {
    return new Promise(async (resolve, reject) => {
      try {
        await keycloak.init();
        resolve();
      } catch (error) {
        reject(error);
      }
    });
  };
}

AuthGuard

A generic AuthGuard, KeycloakAuthGuard, was created to help you bootstrap your security configuration and avoid duplicate code. This class already checks if the user is logged in and get the list of roles from the authenticated user, provided by the keycloak instance. In your implementation you just need to implement the desired security logic.

Example:

import { Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { KeycloakService, KeycloakAuthGuard } from 'keycloak-angular';

@Injectable()
export class AppAuthGuard extends KeycloakAuthGuard {
  constructor(protected router: Router, protected keycloakAngular: KeycloakService) {
    super(router, keycloakAngular);
  }

  isAccessAllowed(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
    return new Promise(async (resolve, reject) => {
      if (!this.authenticated) {
        this.keycloakAngular.login();
        return;
      }

      const requiredRoles = route.data.roles;
      if (!requiredRoles || requiredRoles.length === 0) {
        return resolve(true);
      } else {
        if (!this.roles || this.roles.length === 0) {
          resolve(false);
        }
        let granted: boolean = false;
        for (const requiredRole of requiredRoles) {
          if (this.roles.indexOf(requiredRole) > -1) {
            granted = true;
            break;
          }
        }
        resolve(granted);
      }
    });
  }
}

HttpClient Interceptor

By default all HttpClient requests will add the Authorization header in the format of: Authorization: Bearer TOKEN.

There is also the possibility to exclude a list of URLs that should not have the authorization header. The excluded list must be informed in the keycloak initialization. For example:

 try {
  await keycloak.init({
    config: {
      url: 'http://localhost:8080/auth',
      realm: 'your-realm',
      clientId: 'client-id'
    },
    initOptions: {
      onLoad: 'login-required',
      checkLoginIframe: false
    },
    bearerExcludedUrls: [
      '/assets',
      '/clients/public'
    ],
  });
  resolve();
} catch (error) {}

 

 

 ----------------以下自己笔记--------------------------

 安装:cmd 命令行,进入angular应用

E:\git\iot-hub\src\main\angular>npm install --save keycloak-angular

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules\fsevents):

npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ [email protected]

added 2 packages in 26.373s

执行完成后,在package.json文件中,会发现多出了依赖:

"dependencies": {

    ********************

    ********************

    "keycloak-angular": "^1.3.0",

     ******************

     ******************

  },

在app.module.ts中添加:

 

 
 

与app.module.js同级目录新建文件:app-init.ts,内容如下:

import { KeycloakService } from 'keycloak-angular';

 export function initializer(keycloak: KeycloakService): () => Promise<any> {

  return (): Promise<any> => {

    return new Promise(async (resolve, reject) => {

      try {

        await keycloak.init(

 {

   config: {

     url: 'http://10.110.20.19/auth',

     realm: 'hqq',

     clientId: 'iot-web'

   },

   initOptions: {

     onLoad: 'login-required',

     checkLoginIframe: true

   },

   bearerExcludedUrls: [

     '/assets',

     '/clients/public'

   ],

  }

        );

        resolve();

      } catch (error) {

        reject(error);

      }

    });

  };

}

说明:实际上app-init.ts存放位置可自定义,只要保证app.module.ts文件中,对app-init.ts的引用路径正确就可以。

import { initializer } from './app-init';

 

猜你喜欢

转载自huangqiqing123.iteye.com/blog/2422281