关于身份验证:Keycloak Angular 2-检查身份验证状态Keycloak对象

Keycloak Angular 2 - Check authenticated status Keycloak object

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

验证用户身份并注销似乎有效。我现在正试图保护一些路线。我现在有一个正在工作的AuthGuard。
要检查用户是否已登录(在AuthGuard中),服务中有一个isAuthenticated()方法。
这是服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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()方法仍返回false。原因如下:

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

Keycloak object after login redirect

登录重定向后的Keycloak对象

Same Keycloak object after login redirect (but expanded)

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

首先,经过身份验证的属性为false。扩展后,身份验证属性为true。

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

咨询来源

  • https://keycloak.gitbooks.io/securing-client-applications-guide/content/v/2.5/topics/oidc/javascript-adapter.html
  • https://github.com/keycloak/keycloak/tree/master/examples/demo-template/angular2-product-app/src/main/webapp/app

和别的


根据社区在keycloak的github中提供的Angular2示例,您可以发现与keycloak js适配器交互的一些区别。
主要是对已验证(可能还有用户名)的实际检查是对从init返回的承诺进行的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  static init(): Promise {
    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适配器的文档也将promise用于身份验证的检查。

1
2
3
4
5
6
7
8
9
10
11
<head>
    <script src="keycloak.js">
   
        var keycloak = Keycloak();
        keycloak.init().success(function(authenticated) {
            alert(authenticated ? 'authenticated' : 'not authenticated');
        }).error(function() {
            alert('failed to initialize');
        });
   
</head>


  • 如果将check-sso用作初始化函数的参数,则如果用户未登录并且浏览器仍未通过身份验证,浏览器将被路由回应用程序。您应使用login-required来解决此问题。

  • 如果您不想为完整的App验证用户身份,则应分离创建适配器的逻辑,以在拥有多个受保护组件的情况下简化工作。例如,您可以创建一个HOC。

  • PS:在下面的示例中,我正在使用Reactjs,希望您可以找到一种类似的方式来执行此操作:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    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 />;
      };
    };

  • 您可以在这里找到有用的资源