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

问题描述 投票:1回答:1

我实际上试图准确理解一切应该如何工作,实际上,身份验证的逻辑就是这个。

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的流程图

angular authentication cas
1个回答
0
投票

有点难以具体,但我会尝试给你一些如何在角度内处理身份验证的技巧。

我专注于这个主题的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令牌的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的规范示例。

应用程序初始化程序可以执行诸如分派登录操作之类的操作 - 或实际直接调用身份验证服务方法(我喜欢使用ngxs存储来处理这种事情):

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

在加载组件或App组件中有这样的东西:

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,拦截器......)但如果你认为有助于评论更多信息,请随意。提到的库非常强大,可以帮助您以不同的方式解决您的问题(或者可能最终只是开销 - 只是存储某些状态的服务和拦截器可能就足够了)。这不是非常具体,但我认为这是一套很好的提示,可以帮助您前进。

编辑:我忘记了路线守卫。他们还可以帮助角度内的身份验证。 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();
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.