angular - Angular 7 和 CAS 身份验证的提示?

标签 angular authentication cas

我实际上是在尝试准确了解所有应该如何工作,实际上,身份验证的逻辑是这样的。

1)用户转到 Angular 应用程序,单击登录并重定向到可以使用这样的URL模式登录,我的 Angular 应用程序作为参数:
cas-example.com/login?service=my-angular-app

2)如果用户在 URL 中使用服务票证登录 cas 重定向到 Angular 应用程序,应该是这样的:my-angular-app.com/?ticket=ST-1232431

3)我应该将票发送到我的后端并且如果票有效,则后端向我发送一个jwt,我可以在其中登录用户

这种方法好吗?我应该如何从票证中实现监听器,我应该检查重定向是否来自 cas 并检查 URL,还是总是检查 URL?

这是cas的流程图:
enter image description here

最佳答案

具体来说有点困难,但我会尝试为您提供一些关于如何在 Angular 中处理身份验证的提示。

Angular 附带的一些我关注这个主题的工具是:APP_INITIALIZER (an article 上 - 因为文档很少),HttpInterceptor , LoadingComponent 或只是典型的 AppComponent。

在此过程中也对我有帮助的一些依赖项是 ngx-storengxs store .尽管名称相似,但它们是不同的工具。

我不会给你一个完整的回答你的问题,但一些提示:

例如,在身份验证服务中,您可以注册回调以监听正在修改的某个 cookie(感谢 ngx -store)。像这样的东西:

constructor(public cookiesStorageService: CookiesStorageService,
          @Inject(JWT_COOKIE_NAME) private _JWT_COOKIE_NAME: string) {
this.cookiesStorageService
  .observe(this._JWT_COOKIE_NAME)
  .subscribe((cookie: NgxStorageEvent) => this.checkIfNewToken(cookie.newValue));

}

请注意,上面为 JWT token 注入(inject)了 cookie 名称。我发现它更清晰并坚持 Angular 原则:
export const JWT_COOKIE_NAME = new InjectionToken<string>('ACTUAL_JWT_COOKIE_NAME');

在上述情况下,如果您通过 cookie(不是身份验证 header )传递 JWT token 。
如果您确实传递了带有 token 的 header ,则可以执行诸如拦截 HTTP 请求之类的操作。就像是 :
@Injectable()
export class AuthenticationInterceptor implements HttpInterceptor {

    constructor(private tokenExtractor: HttpXsrfTokenExtractor,
          private authService: AuthenticationService,
          @Inject(API_ENDPOINT) private _API_ENDPOINT: string) {
    }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    if (req.url.match(this._API_ENDPOINT)) {
        // this.authService.intercept$.next(req);

        const XSRFTokenHeaderName = 'X-XSRF-TOKEN';
        const XSRFToken = this.tokenExtractor.getToken() as string;
        if (XSRFToken !== null && !req.headers.has(XSRFTokenHeaderName)) {
          req = req.clone({headers: req.headers.set(XSRFTokenHeaderName, XSRFToken)});
        }

        req = req.clone();

        return next.handle(req);
      } else {
        return next.handle(req).map(event => {
          if (event instanceof HttpResponse) {
              // do something with response like sending it to an authentication service
          }         
          return event;
      });
      }
    }
  }

我留下了处理 X-XSRF-TOKEN 的规范示例。

App 初始化程序可以执行诸如分派(dispatch)登录操作之类的操作 - 或者实际上直接调用身份验证服务方法(我喜欢使用 ngxs 商店来处理此类事情):
export function appRun(store: Store) {
  return () =>
    store
      .dispatch(new Login())
      .pipe(finalize(() => true)) // let the app handle errors after bootstrapped
      .toPromise();
    }

在 Loading Component 或 App Component 中有这样的东西:
constructor(
    private router: Router,
    private actions$: Actions
) {}

ngOnInit() {

    this.actions$
      .pipe(ofActionErrored(Login))
      .subscribe(() => this.router.navigate([Routes.PUBLIC]));

    this.actions$
      .pipe(ofActionSuccessful(Logout))
      .subscribe(() => this.router.navigate([Routes.PUBLIC]));
 }

NGXS 附带了有用的操作成功或操作错误的处理程序,您可以使用它们来路由到某个地方(上面的路由在枚举中定义)。

因此,我在此响应中留下了许多步骤(例如声明状态、注册 APP_INITIALIZER、拦截器……),但如果您认为评论有助于了解更多信息,请随意。
提到的库非常强大,可以帮助您以不同的方式解决问题(或者最终可能只是开销 - 只是一个存储某些状态的服务和一个拦截器可能就足够了)。
这不是很具体,但我认为这是一套很好的提示,可以让你继续前进。

编辑:我忘记了路线守卫。它们还可以帮助在 Angular 中进行身份验证。 CanLoad(用于延迟加载的模块)和 CanActivate 尤其是守卫。就像是 :
canActivateRead(): Observable<boolean> | boolean {
    const perm = this.store.selectSnapshot(state => state.module.acl);
    if (perm) {
      return this.canRead(perm);
    } else {
      return this.fetchACLAndTestPermission('READ');
    }
}

private fetchACLAndTestPermission(perm: 'READ' | 'CREATE' | 'UPDATE'): Observable<boolean> {
    return this.authService.getPermissionForACL('ACL').pipe(
      tap(permission => this.store.dispatch(new SetMainACL({ permission }))),
      map(perm => this.canRead(perm)),
      tap(isPermitted => (isPermitted ? isPermitted : this.feedback.notAllowed()))
);

}

你可以继承一个 guard 服务:
@Injectable({
  providedIn: 'root'
})
export class ParameterBaseGuard extends ParameterGuards implements CanLoad {
  constructor(public authService: AuthenticationService, public feedback: FeedbackService, public store: Store) {
    super(authService, feedback, store);
  }
  canLoad(): Observable<boolean> | Promise<boolean> | boolean {
    return this.fetchACLAndTestPermission('READ');
  }
  canActivate(): Observable<boolean> | Promise<boolean> | boolean {
    return this.canActivateRead();
  }
}

关于angular - Angular 7 和 CAS 身份验证的提示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55647589/

相关文章:

javascript - AngularJS 2 和网络组件、模拟和 polyfill

angular - canActivate 保护方法中的错误

运行 npm install 时出现 Angular 应用程序错误 - 无法解析依赖项

java - 错误 :Failed to execute goal com. mycila.maven-license-plugin :1. 9.0

javascript - 在其他函数中访问时,响应订阅中设置的 Angular 4 值为空

php - 登录php时重置密码不起作用

android - 在移动应用程序中管理登录工作流程的最佳方式

c - 用C实现简单的登录功能

tomcat - Tomcat 8 或 9 的 CAS 客户端

java - CAS 单点登录过滤器