Keycloak Angular 2 - 检查认证状态 Keycloak 对象

Keycloak Angular 2 - Check authenticated status Keycloak object

我正在我的 Angular 2 项目中实施 Keycloak 身份验证服务。 我使用服务进行登录、注销等。

验证用户并注销似乎可行。我现在正在尝试保护一些路线。我现在有一个可用的 AuthGuard。 为了检查用户是否登录(在 AuthGuard 中),我在服务中有一个 isAuthenticated() 方法。 这是服务:

import { Injectable } from '@angular/core';

declare let Keycloak: any;

@Injectable()
export class KeycloakService {
  private keycloak = new Keycloak('app/keycloak/keycloak.json');

  constructor() {
    this.keycloak.init({onload: 'check-sso'});
    console.log(this.keycloak);
  }

  public login() {
    this.keycloak.login();
  }

  public logout() {
    this.keycloak.logout();
  }

  public isAuthenticated() {
    return this.keycloak.authenticated;
  }
}

流程:用户登录,用户尝试访问受保护的路由,AuthGuard 检查用户是否通过 isAuthenticated() 登录。

注意:我不想对完整的 Angular 应用程序的用户进行身份验证。仅适用于部分路线。

问题

用户登录后,用户将被重定向到 Angular 应用程序。此后,isAuthenticated() 方法 returns 仍然为 false。原因如下:

我将 Keycloak 对象记录到控制台。我发现了一些我不明白的东西。

登录重定向后的 Keycloak 对象


登录重定向后的相同 Keycloak 对象(但已扩展)

首先认证的属性是假的。展开验证后 属性 为真。

问题

我尝试维护 Keycloak 对象的方式是否正确?

已咨询来源

其他

根据 keycloak's github 中社区提供的 Angular2 示例,您可以发现与 keycloak js 适配器交互的一些差异。 主要是对经过身份验证的(可能还有用户名)的实际检查是根据从 init 返回的承诺完成的。

  static init(): Promise<any> {
    let keycloakAuth: any = new Keycloak('keycloak.json');
    KeycloakService.auth.loggedIn = false;

      return new Promise((resolve, reject) => {
        keycloakAuth.init({ onLoad: 'login-required' })
          .success(() => {
            KeycloakService.auth.loggedIn = true;
            KeycloakService.auth.authz = keycloakAuth;
            KeycloakService.auth.logoutUrl = keycloakAuth.authServerUrl + "/realms/demo/protocol/openid-connect/logout?redirect_uri=/angular2-product/index.html";
            resolve();
          })
          .error(() => {
            reject();
          });
      });
}

官方也keycloak js adapter's documentation使用promise进行鉴权校验

<head>
    <script src="keycloak.js"></script>
    <script>
        var keycloak = Keycloak();
        keycloak.init().success(function(authenticated) {
            alert(authenticated ? 'authenticated' : 'not authenticated');
        }).error(function() {
            alert('failed to initialize');
        });
    </script>
</head>
  1. 如果您使用 check-sso 作为 init 函数的参数,如果用户未登录并且浏览器将被路由回应用程序将保留 unauthenticated.You 应该使用 login-required 来解决这个问题。

  2. 如果您不想对整个应用程序的用户进行身份验证,您应该分离创建适配器的逻辑,以便在您有多个安全组件时使事情变得更容易。例如,您可以创建一个 HOC.

PS : 在下面的示例中,我使用的是 Reactjs,希望您能在 angular:

中找到类似的方法来执行此操作
export default (WrappedComponent) => {
  return (props) => {
  const [isAutenticated, setIsAutenticated] = useState(false);
  const [keycloak, setKeycloak] = useState();

  const loadConfig = useCallback(() => {
    const keycloak = Keycloak("/keycloak.json"); //The configuration of the adapter in JSON format
    keycloak.init({ onLoad: "login-required" }).then((authenticated) => {
      setKeycloak(keycloak);
      setIsAutenticated(authenticated);
      });
  }, [Keycloak]);

  useEffect(() => {
    loadConfig();
  }, [loadConfig]);

  if (keycloak) {
    if (isAutenticated) {
      return <WrappedComponent {...props} keycloak={keycloak} />;
    } else return <AuthError message="Unable to authenticate" />;
  }
  return <Loader />;
  };
};
  1. 你可以找到有用的资源here