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

时间:2019-04-12 08:35:59

标签: angular authentication cas

我实际上是在尝试确切地了解所有方法,实际上,身份验证的逻辑是这样。

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

2)如果用户使用URL中的服务票证登录cas重定向到有角度的应用程序,则应如下所示:my-angular-app.com/?ticket=ST-1232431

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

这种方法好吗?我应该如何从故障单中实现侦听器,应该检查重定向是否来自cas并检查URL,还是始终检查URL?

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

1 个答案:

答案 0 :(得分:0)

很难具体说明,但我将尝试为您提供一些有关如何在angular中处理身份验证的提示。

Angular附带的一些我专注于此主题的工具是:APP_INITIALIZERan article,因为文档稀疏),HttpInterceptor,LoadingComponent或只是典型的AppComponent。< / p>

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令牌注入了cookie名称。我发现它更清晰,并且坚持有角度的原则:

export const JWT_COOKIE_NAME = new InjectionToken<string>('ACTUAL_JWT_COOKIE_NAME');

在上述情况下,如果您通过Cookie(而非身份验证标头)传递JWT令牌。 如果您传递带有令牌的标头,则可以执行诸如拦截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初始化程序可以执行类似分派Login操作的操作-或实际上直接调用身份验证服务方法(我喜欢将ngxs存储用于此类工作):

export function appRun(store: Store) {
  return () =>
    store
      .dispatch(new Login())
      .pipe(finalize(() => true)) // let the app handle errors after bootstrapped
      .toPromise();
    }

在“加载组件”或“应用程序组件”中具有以下内容:

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附带了动作成功或动作错误的有用处理程序,可用于在某个地方进行路由(上面的路由在Enum中定义)。

因此,我在此响应中遗漏了很多步骤(例如声明状态,注册APP_INITIALIZER,Interceptor等),但是如果您认为它有助于评论更多信息,请放心。 提到的库非常强大,可以帮助您以不同的方式解决问题(或者可能最终只是开销-仅存储一些状态的服务和拦截器就足够了)。 这不是很具体,但是我认为这是使您前进的一组不错的技巧。

edit:我忘记了路线守卫。他们还可以帮助您进行角度认证。 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()))
);

}

您可以继承到守护服务中:

@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();
  }
}