最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

angular - KeycloakService.init() returns undefined - Stack Overflow

programmeradmin3浏览0评论

Whenever I add my Keycloak app initializer to my angular 17 project it returns undefined.

Keycloak is running in a docker container locally.

The administrator console is working and I have set up my realm and clients. It is also working with my backend for the application without issue.

But the implementation for the frontend seems to be tricky.

Specific versions:

  • Angular v17
  • Angular-Keycloak v17
  • Keycloak-js v23

Stack trace

ERROR undefined core.mjs:6531:22
    Angular 32
        handleError
        _callAndReportToErrorHandler
        invoke
        run
        runOutsideAngular
        _callAndReportToErrorHandler
        invoke
        onInvoke
        invoke
        run
        scheduleResolveOrReject
        invokeTask
        onInvokeTask
        invokeTask
        onInvokeTask
        invokeTask
        runTask
        drainMicroTaskQueue
        invokeTask
        invokeTask
        globalCallback
        globalZoneAwareCallback
    (Async: EventListener.handleEvent)
        customScheduleGlobal
        scheduleTask
        onScheduleTask
        scheduleTask
        onScheduleTask
        scheduleTask
        scheduleTask
        scheduleEventTask
        makeAddListener
        set
    processCallback keycloak.mjs:772
    processInit keycloak.mjs:261
    Angular 23
        invoke
        onInvoke
        invoke
        run
        scheduleResolveOrReject
        invokeTask
        onInvokeTask
        invokeTask
        onInvokeTask
        invokeTask
        runTask
        drainMicroTaskQueue
    (Async: promise callback)
        nativeScheduleMicroTask
        scheduleMicroTask
        scheduleTask
        onScheduleTask
        scheduleTask
        onScheduleTask
        scheduleTask
        scheduleTask
        scheduleMicroTask
        scheduleResolveOrReject
        then
    init keycloak.mjs:322
    Angular 5
        init
        __async
        ZoneAwarePromise
        __async
        init
    keycloakInitializer keycloak.initializer.ts:19
    ZoneAwarePromise Angular
    keycloakInitializer keycloak.initializer.ts:18
    Angular 11
        runInitializers
        internalCreateApplication
        _callAndReportToErrorHandler
        internalCreateApplication
        invoke
        onInvoke
        invoke
        run
        run
        internalCreateApplication
        bootstrapApplication
    <anonymous> main.ts:6

Keycloak instance

{
  "_keycloakEvents$": {
    "closed": false,
    "currentObservers": [],
    "observers": [],
    "isStopped": false,
    "hasError": false,
    "thrownError": null
  },
  "_enableBearerInterceptor": true,
  "_loadUserProfileAtStartUp": true,
  "_authorizationHeaderName": "Authorization",
  "_bearerPrefix": "Bearer ",
  "_excludedUrls": [
    {
      "urlPattern": {},
      "httpMethods": []
    }
  ],
  "_silentRefresh": false,
  "_updateMinValidity": 20,
  "_instance": {
    "didInitialize": true,
    "authenticated": false,
    "silentCheckSsoFallback": true,
    "enableLogging": false,
    "messageReceiveTimeout": 10000,
    "responseMode": "fragment",
    "responseType": "code",
    "flow": "standard",
    "clientId": "client-1",
    "authServerUrl": "https://localhost:8543",
    "realm": "realm-1",
    "endpoints": {},
    "timeSkew": 0,
    "tokenTimeoutHandle": null
  }
}

app.config.ts

import { APP_INITIALIZER, ApplicationConfig, importProvidersFrom, inject } from "@angular/core";
import {provideRouter, withComponentInputBinding, withRouterConfig} from '@angular/router';

import { routes } from './app.routes';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import {TranslateLoader, TranslateModule} from "@ngx-translate/core";
import {TranslateHttpLoader} from "@ngx-translate/http-loader";
import { HttpClient, provideHttpClient, withFetch, withInterceptors } from "@angular/common/http";
import {SystemLanguage} from "./core/enums/system-language.enum";
import { MAT_DATE_LOCALE } from "@angular/material/core";
import { KeycloakAngularModule, KeycloakBearerInterceptor, KeycloakService } from "keycloak-angular";
import { keycloakInitializer } from "@root/core/features/authentication/initializers/keycloak.initializer";

export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
  return new TranslateHttpLoader(http);
}

export const appConfig: ApplicationConfig = {
  providers: [
    { provide: MAT_DATE_LOCALE, useValue: 'da-DK' },
    provideRouter(routes, withComponentInputBinding(), withRouterConfig({ paramsInheritanceStrategy: "always" })),
    provideHttpClient(
      withFetch(),
      withInterceptors([
        (req, next) => {
          return inject(KeycloakBearerInterceptor).intercept(req, { handle: r => next(r) });
        }
      ]),
    ),
    {
      provide: APP_INITIALIZER,
      useFactory: keycloakInitializer,
      multi: true,
      deps: [KeycloakService]
    },
    KeycloakService,
    KeycloakAngularModule,
    importProvidersFrom(
      KeycloakService,
      KeycloakAngularModule,
      TranslateModule.forRoot({
        defaultLanguage: SystemLanguage.English,
        useDefaultLang: true,
        loader: {
          provide: TranslateLoader,
          useFactory: HttpLoaderFactory,
          deps: [HttpClient]
        }
      }),
    ),
    {
      provide: KeycloakBearerInterceptor,
      useClass: KeycloakBearerInterceptor
    },
    provideAnimationsAsync(),
  ]
};

keycloak.initializer.ts

import { KeycloakOptions, KeycloakService } from "keycloak-angular";

export function keycloakInitializer(keycloak: KeycloakService) {
  console.log(keycloak);
  const options: KeycloakOptions = {
    config: {
      realm: "realm-1",
      url: "https://localhost:8543",
      clientId: "client-1"
    },
    loadUserProfileAtStartUp: true,
    initOptions: {
      onLoad: "check-sso",
      checkLoginIframe: false,
    },
    enableBearerInterceptor: true,
    bearerExcludedUrls: [".readonly"],
  };
  return () => {
    return new Promise<boolean>((resolve, reject) => {
      keycloak.init(options).then((value) => {
        console.log(value);
        resolve(true);
      }).catch((error) => {
        console.log(error);
        reject(error);
      });
    })
  };
}

I have tried a bunch of different ways of importing and providing keycloak-angular and its services.

There was no change, still undefined.

Whenever I add my Keycloak app initializer to my angular 17 project it returns undefined.

Keycloak is running in a docker container locally.

The administrator console is working and I have set up my realm and clients. It is also working with my backend for the application without issue.

But the implementation for the frontend seems to be tricky.

Specific versions:

  • Angular v17
  • Angular-Keycloak v17
  • Keycloak-js v23

Stack trace

ERROR undefined core.mjs:6531:22
    Angular 32
        handleError
        _callAndReportToErrorHandler
        invoke
        run
        runOutsideAngular
        _callAndReportToErrorHandler
        invoke
        onInvoke
        invoke
        run
        scheduleResolveOrReject
        invokeTask
        onInvokeTask
        invokeTask
        onInvokeTask
        invokeTask
        runTask
        drainMicroTaskQueue
        invokeTask
        invokeTask
        globalCallback
        globalZoneAwareCallback
    (Async: EventListener.handleEvent)
        customScheduleGlobal
        scheduleTask
        onScheduleTask
        scheduleTask
        onScheduleTask
        scheduleTask
        scheduleTask
        scheduleEventTask
        makeAddListener
        set
    processCallback keycloak.mjs:772
    processInit keycloak.mjs:261
    Angular 23
        invoke
        onInvoke
        invoke
        run
        scheduleResolveOrReject
        invokeTask
        onInvokeTask
        invokeTask
        onInvokeTask
        invokeTask
        runTask
        drainMicroTaskQueue
    (Async: promise callback)
        nativeScheduleMicroTask
        scheduleMicroTask
        scheduleTask
        onScheduleTask
        scheduleTask
        onScheduleTask
        scheduleTask
        scheduleTask
        scheduleMicroTask
        scheduleResolveOrReject
        then
    init keycloak.mjs:322
    Angular 5
        init
        __async
        ZoneAwarePromise
        __async
        init
    keycloakInitializer keycloak.initializer.ts:19
    ZoneAwarePromise Angular
    keycloakInitializer keycloak.initializer.ts:18
    Angular 11
        runInitializers
        internalCreateApplication
        _callAndReportToErrorHandler
        internalCreateApplication
        invoke
        onInvoke
        invoke
        run
        run
        internalCreateApplication
        bootstrapApplication
    <anonymous> main.ts:6

Keycloak instance

{
  "_keycloakEvents$": {
    "closed": false,
    "currentObservers": [],
    "observers": [],
    "isStopped": false,
    "hasError": false,
    "thrownError": null
  },
  "_enableBearerInterceptor": true,
  "_loadUserProfileAtStartUp": true,
  "_authorizationHeaderName": "Authorization",
  "_bearerPrefix": "Bearer ",
  "_excludedUrls": [
    {
      "urlPattern": {},
      "httpMethods": []
    }
  ],
  "_silentRefresh": false,
  "_updateMinValidity": 20,
  "_instance": {
    "didInitialize": true,
    "authenticated": false,
    "silentCheckSsoFallback": true,
    "enableLogging": false,
    "messageReceiveTimeout": 10000,
    "responseMode": "fragment",
    "responseType": "code",
    "flow": "standard",
    "clientId": "client-1",
    "authServerUrl": "https://localhost:8543",
    "realm": "realm-1",
    "endpoints": {},
    "timeSkew": 0,
    "tokenTimeoutHandle": null
  }
}

app.config.ts

import { APP_INITIALIZER, ApplicationConfig, importProvidersFrom, inject } from "@angular/core";
import {provideRouter, withComponentInputBinding, withRouterConfig} from '@angular/router';

import { routes } from './app.routes';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import {TranslateLoader, TranslateModule} from "@ngx-translate/core";
import {TranslateHttpLoader} from "@ngx-translate/http-loader";
import { HttpClient, provideHttpClient, withFetch, withInterceptors } from "@angular/common/http";
import {SystemLanguage} from "./core/enums/system-language.enum";
import { MAT_DATE_LOCALE } from "@angular/material/core";
import { KeycloakAngularModule, KeycloakBearerInterceptor, KeycloakService } from "keycloak-angular";
import { keycloakInitializer } from "@root/core/features/authentication/initializers/keycloak.initializer";

export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
  return new TranslateHttpLoader(http);
}

export const appConfig: ApplicationConfig = {
  providers: [
    { provide: MAT_DATE_LOCALE, useValue: 'da-DK' },
    provideRouter(routes, withComponentInputBinding(), withRouterConfig({ paramsInheritanceStrategy: "always" })),
    provideHttpClient(
      withFetch(),
      withInterceptors([
        (req, next) => {
          return inject(KeycloakBearerInterceptor).intercept(req, { handle: r => next(r) });
        }
      ]),
    ),
    {
      provide: APP_INITIALIZER,
      useFactory: keycloakInitializer,
      multi: true,
      deps: [KeycloakService]
    },
    KeycloakService,
    KeycloakAngularModule,
    importProvidersFrom(
      KeycloakService,
      KeycloakAngularModule,
      TranslateModule.forRoot({
        defaultLanguage: SystemLanguage.English,
        useDefaultLang: true,
        loader: {
          provide: TranslateLoader,
          useFactory: HttpLoaderFactory,
          deps: [HttpClient]
        }
      }),
    ),
    {
      provide: KeycloakBearerInterceptor,
      useClass: KeycloakBearerInterceptor
    },
    provideAnimationsAsync(),
  ]
};

keycloak.initializer.ts

import { KeycloakOptions, KeycloakService } from "keycloak-angular";

export function keycloakInitializer(keycloak: KeycloakService) {
  console.log(keycloak);
  const options: KeycloakOptions = {
    config: {
      realm: "realm-1",
      url: "https://localhost:8543",
      clientId: "client-1"
    },
    loadUserProfileAtStartUp: true,
    initOptions: {
      onLoad: "check-sso",
      checkLoginIframe: false,
    },
    enableBearerInterceptor: true,
    bearerExcludedUrls: ["https://www.googleapis/auth/spreadsheets.readonly"],
  };
  return () => {
    return new Promise<boolean>((resolve, reject) => {
      keycloak.init(options).then((value) => {
        console.log(value);
        resolve(true);
      }).catch((error) => {
        console.log(error);
        reject(error);
      });
    })
  };
}

I have tried a bunch of different ways of importing and providing keycloak-angular and its services.

There was no change, still undefined.

Share Improve this question edited Mar 21 at 19:05 Alexander Vestergaard Eriksen asked Mar 17 at 20:58 Alexander Vestergaard EriksenAlexander Vestergaard Eriksen 1712 silver badges10 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

Wild guess, but could you do it exactly like how it is given in the docs.

import { KeycloakOptions, KeycloakService } from "keycloak-angular";

export function keycloakInitializer(keycloak: KeycloakService) {
  const options: KeycloakOptions = {
    config: {
      realm: "realm-1",
      url: "https://localhost:8543",
      clientId: "client-1"
    },
    loadUserProfileAtStartUp: true,
    initOptions: {
      onLoad: "check-sso",
      checkLoginIframe: false,
    },
    enableBearerInterceptor: true,
    bearerExcludedUrls: ["https://www.googleapis/auth/spreadsheets.readonly"],
  };
  return () => {
    return keycloak.init(options);
  };
}

Also please add a single provider KeycloakService to the configuration.

export const appConfig: ApplicationConfig = {
  providers: [
    { provide: MAT_DATE_LOCALE, useValue: 'da-DK' },
    provideRouter(routes, withComponentInputBinding(), withRouterConfig({ paramsInheritanceStrategy: "always" })),
    provideHttpClient(
      withFetch(),
      withInterceptors([
        (req, next) => {
          return inject(KeycloakBearerInterceptor).intercept(req, { handle: r => next(r) });
        }
      ]),
    ),
    {
      provide: APP_INITIALIZER,
      useFactory: keycloakInitializer,
      multi: true,
      deps: [KeycloakService]
    },
    KeycloakService, // <- notice!
    KeycloakBearerInterceptor,
    importProvidersFrom(
      TranslateModule.forRoot({
        defaultLanguage: SystemLanguage.English,
        useDefaultLang: true,
        loader: {
          provide: TranslateLoader,
          useFactory: HttpLoaderFactory,
          deps: [HttpClient]
        }
      }),
    ),
    {
        provide: HTTP_INTERCEPTORS,
        useClass: KeycloakBearerInterceptor,
        multi: true,
        deps: [KeycloakService]
    },
    provideAnimationsAsync(),
  ]
};
发布评论

评论列表(0)

  1. 暂无评论