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

Posted

技术标签:

【中文标题】Keycloak Angular 2 - 检查身份验证状态 Keycloak 对象【英文标题】:Keycloak Angular 2 - Check authenticated status Keycloak object 【发布时间】:2017-05-09 21:14:11 【问题描述】:

我正在我的 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() 方法仍然返回 false。原因如下:

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

登录重定向后的Keycloak对象


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

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

问题

我尝试维护 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

其他

【问题讨论】:

【参考方案1】:

根据社区在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>

【讨论】:

感谢您的回答。现在最大的挑战是当页面刷新时,一个新的 Keycloak 对象被创建并且我的状态丢失了。 您好,我是否正确理解您的原始问题已得到回答?如果是这样,请接受提供的答案。至于你的下一个挑战,我会提出一个新问题。 您也可以查看github.com/atende/angular-spa 中的代码,它是一个集成了 Keycloak 并提供更完整功能集的 Angular 2 库。免责声明:我是作者,你可以给我反馈;-)【参考方案2】:

    如果您使用 check-sso 作为 init 函数的参数,如果用户未登录,浏览器将被路由回应用程序并保持未经身份验证。您应该使用 需要登录来解决这个问题。

    如果您不想对整个应用程序的用户进行身份验证,您应该分离创建适配器的逻辑,以便在您拥有多个安全组件时使事情变得更容易。例如,您可以创建一个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 />;
  ;
;
    你可以找到有用的资源here

【讨论】:

以上是关于Keycloak Angular 2 - 检查身份验证状态 Keycloak 对象的主要内容,如果未能解决你的问题,请参考以下文章

如何检查来自另一个 keycloak 实例 B 的身份验证 keycloak 实例 A 用户?

带有 Keycloak 的 Angular 和 Spring Boot REST API 的 CORS 问题

带有 Keycloak 的 Angular 和 Spring Boot REST API 的 CORS 问题

使用 Keycloak SSO 在 2 个应用程序之间保持身份验证

Keycloak Spring boot 后端和 Angular 前端,CORS 错误

如何使用 keycloak 保护 angular/spring 应用程序?