You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Alfresco ADF v6.9.1与ACS v23.x中处理JWT会话过期?

在Alfresco ADF v6.9.1中实现JWT令牌自动刷新方案

针对你遇到的JWT令牌过期需手动重登的问题,ADF本身提供了内置的令牌自动刷新机制,也支持自定义扩展,以下是具体实现步骤:

一、使用ADF内置静默刷新机制

ADF的AuthModule原生支持基于OpenID Connect的静默令牌刷新,无需手动处理大部分逻辑,只需完成以下配置:

1. 配置认证参数

在环境配置文件(如src/environments/environment.ts)中添加或完善auth配置项:

export const environment = {
  production: false,
  auth: {
    issuer: 'https://你的ACS认证域名/auth/realms/alfresco', // ACS的Keycloak issuer地址
    clientId: '你的ADF客户端ID', // 在Keycloak中创建的客户端ID
    scope: 'openid profile email',
    redirectUri: window.location.origin + '/auth/callback',
    silentRefreshRedirectUri: window.location.origin + '/silent-refresh.html', // 静默刷新回调页
    silentRefreshTimeout: 5000, // 刷新超时时间
    timeoutFactor: 0.75, // 在令牌过期前75%的时间触发刷新
    sessionChecksEnabled: true // 开启会话状态检查
  }
};

2. 创建静默刷新回调页

在项目根目录(或src/assets)创建silent-refresh.html文件,用于处理静默刷新的回调,避免页面跳转:

<!DOCTYPE html>
<html>
  <body>
    <script>
      window.onload = function () {
        parent.postMessage(location.hash, location.origin);
      };
    </script>
  </body>
</html>

3. 导入并配置AuthModule

在AppModule中导入AuthModule并传入上述配置:

import { AuthModule } from '@alfresco/adf-core';
import { environment } from '../environments/environment';

@NgModule({
  imports: [
    // 其他模块...
    AuthModule.forRoot(environment.auth)
  ]
})
export class AppModule { }

二、自定义令牌刷新逻辑(内置机制不满足时)

如果需要更灵活的控制(比如自定义错误处理、刷新时机),可以通过Angular拦截器扩展:

1. 实现自定义拦截器

创建token-refresh.interceptor.ts文件,捕获401错误并尝试刷新令牌:

import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpErrorResponse } from '@angular/common/http';
import { AuthService } from '@alfresco/adf-core';
import { Observable, throwError } from 'rxjs';
import { catchError, switchMap } from 'rxjs/operators';

@Injectable()
export class TokenRefreshInterceptor implements HttpInterceptor {
  private isRefreshing = false; // 防止重复触发刷新

  constructor(private authService: AuthService) { }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<any> {
    // 已登录时为请求添加令牌
    if (this.authService.isLoggedIn()) {
      request = this.addTokenToRequest(request);
    }

    return next.handle(request).pipe(
      catchError((error: HttpErrorResponse) => {
        // 捕获401且未在刷新时,触发令牌刷新
        if (error.status === 401 && !this.isRefreshing) {
          this.isRefreshing = true;

          return this.authService.refreshToken().pipe(
            switchMap(() => {
              this.isRefreshing = false;
              // 刷新成功后重新发起原请求
              return next.handle(this.addTokenToRequest(request));
            }),
            catchError(() => {
              this.isRefreshing = false;
              // 刷新失败则强制登出
              this.authService.logout();
              return throwError(() => new Error('令牌刷新失败,请重新登录'));
            })
          );
        }
        return throwError(() => error);
      })
    );
  }

  private addTokenToRequest(request: HttpRequest<any>): HttpRequest<any> {
    const token = this.authService.getToken();
    return request.clone({
      setHeaders: {
        Authorization: `Bearer ${token}`
      }
    });
  }
}

2. 注册拦截器

在AppModule的providers中注册该拦截器:

import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { TokenRefreshInterceptor } from './interceptors/token-refresh.interceptor';

@NgModule({
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: TokenRefreshInterceptor,
      multi: true
    }
  ]
})
export class AppModule { }

三、关键注意事项

  • 认证服务器配置:确保ACS的Keycloak客户端允许静默刷新,需将silent-refresh.html添加到Valid Redirect URIs列表,客户端Access Type设为public或confidential。
  • 令牌有效期设置:合理配置令牌的expires_in时间,结合timeoutFactor确保刷新操作在令牌过期前触发。
  • 测试验证:临时缩短令牌有效期(如5分钟),模拟用户闲置场景,验证自动刷新是否生效。

内容的提问来源于stack exchange,提问作者Varshil Shah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 12:12:26