如何使用 Keycloak 和 Angular 避免 "timeout when waiting for 3rd party check iframe message"

How to avoid "timeout when waiting for 3rd party check iframe message" with Keycloak and Angular

我正在尝试使用 Keycloak 服务器保护 Angular 应用程序。为此,我遵循了一些提供或多或少相同说明的教程,但我遇到了以下错误:

Timeout when waiting for 3rd party check iframe message.

我使用以下 docker-compose 配置启动我的 keycloak 服务器:

auth:
  container_name: nerthus-tech-auth
  image: quay.io/keycloak/keycloak:17.0.1
  command: start-dev
  environment:
    KEYCLOAK_ADMIN: admin
    KEYCLOAK_ADMIN_PASSWORD: admin
    KC_DB: postgres
    KC_DB_URL: jdbc:postgresql://database:5432/keycloak
    KC_DB_USERNAME: keycloak
    KC_DB_PASSWORD: str0ngP@ssword
  ports:
    - 10010:8080

我创建了一个 public 领域 (nerthus) 和一个客户端 (blog),并具有以下配置:

在 Angular 应用端,我安装了 keycloak-angular 和 keycloak-js 依赖项:

"keycloak-angular": "^9.1.0",
"keycloak-js": "^16.1.1"

我还为 Keycloak 注册了一个初始化程序:

providers: [
  {
    provide: APP_INITIALIZER,
    useFactory: initializeKeycloak,
    multi: true,
    deps: [KeycloakService]
  }
]
function initializeKeycloak(keycloakService: KeycloakService) {
  return () => keycloakService.init({
                                      config: {
                                        url: 'http://localhost:10010',
                                        realm: 'nerthus',
                                        clientId: 'blog'
                                      }
                                    });
}

为此,我还尝试使用 initOptions.onLoad(使用“需要登录”和“check-sso”),但这会导致应用程序需要身份验证才能访问任何页面,这不是预期的行为。

我只希望受保护的页面需要身份验证。因此我设置了守卫:

@Injectable({
  providedIn: 'root'
})
export class AuthGuard extends KeycloakAuthGuard {
  constructor(protected override readonly router: Router,
              protected override readonly keycloakAngular: KeycloakService) {
    super(router, keycloakAngular);
  }

  async isAccessAllowed(route: ActivatedRouteSnapshot,
                        state: RouterStateSnapshot): Promise<boolean | UrlTree> {
    if (!this.authenticated) {
      await this.keycloakAngular.login({ redirectUri: window.location.origin + state.url });
    }

    return this.authenticated;
  }
}

我当然遗漏了什么,但我无法让它发挥作用。我尽量简洁,所以如果缺少一些重要信息,请问我。

我的解决方案是将 checkLoginIframe 设置为 false。以下是我的配置:

 keycloak.init({
  config: {
      url: 'http://localhost:10010',
      realm: 'nerthus',
      clientId: 'blog'
  },
  initOptions: {
    
    pkceMethod: 'S256', 
    // must match to the configured value in keycloak
    redirectUri: 'http://localhost:4200/your_url',   
    // this will solved the error 
    checkLoginIframe: false
  }});

希望对您有所帮助。 =)