如何在当前路由上使用angular-oauth2-oidc进行认证后创建路由



我有一个堆栈Angular 13与Angular - OAuth2 -oidc-jwks: 13.0.1和Angular - OAuth2 -oidc-jwks: 13.0.1。

我试图在重定向登录URI之前将用户重定向到当前路由。

现在我在隐式流中,我想在身份验证之前保存路由,以便在收到令牌后将其重定向到初始调用url。

和我目前的问题,不能保存正确的URL之前认证


@Injectable({
providedIn: "root",
})
export class InitialAuthService {
private jwtHelper: JwtHelperService = new JwtHelperService();
private isAuthenticatedSubject = new BehaviorSubject<boolean>(false);
private isAuthenticated = this.isAuthenticatedSubject.asObservable();
// tslint:disable-next-line:variable-name
private _decodedAccessToken: any;
// tslint:disable-next-line:variable-name
private _decodedIDToken: any;
get decodedAccessToken() {
return this._decodedAccessToken;
}
get decodedIDToken() {
return this._decodedIDToken;
}
get profile() {
return this.oauthService.loadUserProfile();
}
constructor(
private oauthService: OAuthService,
private authConfig: AuthConfig,
public router: Router,
public activeRoute: ActivatedRoute,
private authService: AuthService,
) {
}
async initAuth(): Promise<any> {

const currenturl = this.activeRoute.snapshot.url;
return new Promise<void>((resolveFn, rejectFn) => {
this.oauthService.configure(this.authConfig);
this.oauthService.setStorage(localStorage);
this.oauthService.tokenValidationHandler = new JwksValidationHandler();
// subscribe to token events
this.oauthService.events
.pipe(filter((e: OAuthEvent) => e.type === "token_received"))
.subscribe(({ type }) => {
console.debug("token_received");
this.handleNewToken();
console.debug("before");
console.debug(currenturl);
this.router.navigate([currenturl]);
console.debug("after");
});
this.oauthService.events
.pipe(filter((e: any) => e.type === "token_expires"))
.subscribe(({ type }) => {
console.debug("token_expires");
this.logoutSession();
});
this.oauthService.events
.pipe(filter((e: any) => e.type === "token_error"))
.subscribe(({ type }) => {
console.debug("token_error");
this.logoutSession();
});
this.oauthService.events
.subscribe(_ => {
this.isAuthenticatedSubject.next(this.oauthService.hasValidAccessToken());
});

this.oauthService.loadDiscoveryDocumentAndLogin().then(
(isLoggedIn) => {
if (isLoggedIn) {
resolveFn();
} else {
console.debug("initImplicitFlow");
this.oauthService.initImplicitFlow();
rejectFn();
}
},
(error: { status: number; }) => {
console.log({ error });
if (error.status === 400) {
location.reload();
}
}
);
});
});
}

private handleNewToken() {
this._decodedAccessToken = this.jwtHelper.decodeToken(
this.oauthService.getAccessToken()
);
this._decodedIDToken = this.jwtHelper.decodeToken(
this.oauthService.getIdToken()
);
this.authService.login();
}
logoutSession() {
console.debug("logout");
this.oauthService.logOut();
this.authService.logout();
}

isLogin(): Observable<boolean> {
return this.isAuthenticated;
}
}

好消息:OpenID协议对此有内置支持,并且库也支持它。您可以克隆我的示例存储库,或者更具体地检查两个移动部分:

  • 通过库(使用OpenID的state参数)将路由发送到IDP的位置;
  • IDP使用库从重定向中读取预期路由的位置;

下面是两部分代码的要点:

// Guard that passes the "intended" route to the library and thus the IDP via 'state'
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
): Observable<boolean> {
return this.authService.isDoneLoading$.pipe(
filter(isDone => isDone),
switchMap(_ => this.authService.isAuthenticated$),
tap(isAuthenticated => isAuthenticated || this.authService.login(state.url)), // << !!
);
}
// when booting the library and trying to login:
this.oauthService.loadDiscoveryDocumentAndTryLogin()
// more logic here?
.then(() => {
if (this.oauthService.state && this.oauthService.state !== 'undefined' && this.oauthService.state !== 'null') {
let stateUrl = this.oauthService.state;
if (stateUrl.startsWith('/') === false) {
stateUrl = decodeURIComponent(stateUrl);
}
console.log(`There was state of ${this.oauthService.state}, so we are sending you to: ${stateUrl}`);
this.router.navigateByUrl(stateUrl);
}
})

同样,您可以克隆示例存储库并启动以查看所有这些操作。

相关内容

  • 没有找到相关文章

最新更新