首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在登录oidc-client后保持在同一页面上。

在登录oidc-client后保持在同一页面上。
EN

Stack Overflow用户
提问于 2020-03-18 19:44:17
回答 1查看 883关注 0票数 1

我正在使用ASP.NET 9开发我的第一个SPA核心web应用程序。这是我第一次使用Range9,我一直在学习Pluralsight的教程。但是在登录后,我一直很难保持在同一个页面上。我使用IdentityServer4,ASP.NET标识和oidc客户端作为我的角度位.

因此,我在"https://localhost:44392/“启动应用程序。所以,一开始,这很好。例如,当我转到"https://localhost:44392/search“时,问题就出现了。如果我通过有routerLink=“/search‘”的导航条,就没有问题了。但是,如果我只是在浏览器的地址栏中写"https://localhost:44392/search“,它会触发另一个登录(虽然它不要求凭据,因为我的id_token通常仍然有效)。但是在签名之后,它会返回到主页(又名"https://localhost:44392/")。

此行为仅在添加oidc客户端和guardService后才开始。我试着在网上搜索,但我想我错过了什么,因为我无法让事情与指控的答案一起工作。

这是我的课

代码语言:javascript
复制
import { Injectable } from '@angular/core';
import {UserManager, User} from 'oidc-client';
import { environment } from 'src/environments/environment';
import { ReplaySubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class OpenIdConnectService {

  private userManager: UserManager = new UserManager(environment.openIdConnectSettings);
  private currentUser: User;

  userLoaded$ = new ReplaySubject<boolean>(1);

  get userAvailable(): boolean {
    return this.currentUser != null;
  }

  get user(): User {
    return this.currentUser;
  }

  constructor() { 
    this.userManager.clearStaleState();

    this.userManager.events.addUserLoaded(user => {
      if (!environment.production) {
        console.log('User loaded: ', user);
      }
      this.currentUser = user;
      this.userLoaded$.next(true);
    });

    this.userManager.events.addUserUnloaded(() => {
      if (!environment.production) {
        console.log('User unloaded.');
      }
      this.currentUser = null;
      this.userLoaded$.next(false);
    });
  }

  triggerSignIn(url: string){ //originally without the parameter url
    this.userManager.signinRedirect().then(function () {
      if (!environment.production) {
        console.log('Redirection to signin triggered.');
      }
      data: {redirect_url: url} //I added this because I saw it in a reply in SO, but doesn't work.
    });
  }

  handleCallBack(){
    this.userManager.signinRedirectCallback().then(function (user){
      if (!environment.production) {
        console.log('Callback after signin handled.', user);
      }
    });
  }

  triggerSignOut() {
    this.userManager.signoutRedirect().then(function (resp) {
      if (!environment.production) {
        console.log('Redirection to sign out triggered.', resp);
      }
    });
  }
}
代码语言:javascript
复制
import { Component, OnInit } from '@angular/core';
import { OpenIdConnectService } from '../shared/open-id-connect.service';
import { Router } from '@angular/router';
import { environment } from 'src/environments/environment';

@Component({
  selector: 'app-signin-oidc',
  templateUrl: './signin-oidc.component.html',
  styleUrls: ['./signin-oidc.component.scss']
})
export class SigninOidcComponent implements OnInit {

  constructor(private openIdConnectService: OpenIdConnectService, 
    private router: Router) { }

  ngOnInit() {
    this.openIdConnectService.userLoaded$.subscribe((userLoaded) => {
      if (userLoaded) {
        this.router.navigate(['./']);
      }
      else {
        if (!environment.production) {
          console.log("An error happened: user wasn't loaded.");
        }
      }
    });

    this.openIdConnectService.handleCallBack();
  }

}
代码语言:javascript
复制
import { Injectable } from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { OpenIdConnectService } from './open-id-connect.service';

@Injectable({
  providedIn: 'root'
})
export class RequireAuthenticatedUserRouteGuardService implements CanActivate {

  constructor(private openIdConnectService: OpenIdConnectService,
    private router: Router) { }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {//route and state were not part of the original example. I just added it in an attempt to pass is as param to triggerSignIn
    if (this.openIdConnectService.userAvailable) {
      return true;
    }
    else
    {
      //trigger signin
      this.openIdConnectService.triggerSignIn(state.url);
      return false;
    }
  }
}

app.module.ts

代码语言:javascript
复制
//Lots of other imports
import { NgModule } from '@angular/core';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { RouterModule } from '@angular/router';

import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { ComponentsModule } from "./components/components.module";
import { ProfileComponent } from './profile/profile.component';
import { SearchComponent } from './search/search.component';
import { MonitoringComponent } from './monitoring/monitoring.component';
import { OpenIdConnectService } from './shared/open-id-connect.service';
import { SigninOidcComponent } from './signin-oidc/signin-oidc.component';
import { RequireAuthenticatedUserRouteGuardService } from './shared/require-authenticated-user-route-guard.service';
import { AddAuthorizationHeaderInterceptor } from './shared/add-authorization-header-interceptor';

@NgModule({
  declarations: [
    //there are other components but deleted for brevity
    AppComponent,
    HomeComponent,
    ProfileComponent,
    SearchComponent,
    MonitoringComponent,
    SigninOidcComponent
  ],
  imports: [
    HttpClientModule,
    ComponentsModule,
    RouterModule.forRoot([
        { path: '', component: HomeComponent, pathMatch: 'full', canActivate: [RequireAuthenticatedUserRouteGuardService] },
        { path: 'profile/:ytChannelId', component: ProfileComponent, canActivate: [RequireAuthenticatedUserRouteGuardService] },
        { path: 'search', component: SearchComponent, canActivate: [RequireAuthenticatedUserRouteGuardService] },
        { path: 'monitoring', component: MonitoringComponent, canActivate: [RequireAuthenticatedUserRouteGuardService] },
        { path: 'monitoring/:ytVideoId', component: MonitoringComponent, canActivate: [RequireAuthenticatedUserRouteGuardService] },
        { path: 'signin-oidc', component: SigninOidcComponent },
    ]),
//there are more things deleted for brevity
  ],
  providers: [
    {
      provide: PERFECT_SCROLLBAR_CONFIG,
      useValue: DEFAULT_PERFECT_SCROLLBAR_CONFIG
    },
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AddAuthorizationHeaderInterceptor,
      multi: true
    },
    OpenIdConnectService,
    RequireAuthenticatedUserRouteGuardService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
代码语言:javascript
复制
import { Injectable } from "@angular/core";
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from "@angular/common/http";
import { OpenIdConnectService } from "./open-id-connect.service";
import { Observable } from "rxjs";

@Injectable()
export class AddAuthorizationHeaderInterceptor implements HttpInterceptor {
    constructor (private openIdConnectService: OpenIdConnectService) {}

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        //add the access token as bearer token
        request = request.clone(
            { setHeaders: {Authorization: this.openIdConnectService.user.token_type
                + " " + this.openIdConnectService.user.access_token}}
        );
        return next.handle(request);
    }
}

最后我的environment.ts

代码语言:javascript
复制
export const environment = {
  production: false,
  apiUrl: 'https://localhost:44392/api/v1/',
  openIdConnectSettings: {
    authority: 'https://localhost:44350/',
    client_id: 'peraClient',
    redirect_uri: 'https://localhost:44392/signin-oidc',
    scope: 'openid profile roles peraAPI',
    response_type: 'id_token token',
    post_logout_redirect_uri: 'https://localhost:44392/',
    automaticSilentRenew: true,
    silent_redirect_uri: 'https://localhost:44392/redirect-silentrenew'
  },
  pageSize: 20
};

我怀疑问题出在警卫身上,但我想我只是不知道更多。任何洞察力都是非常感谢的。

谢谢

更新:所以,我终于发现了导致重定向的原因。这是signin-oidc.component.ts中的this.router.navigate(['./']);行,但我不知道该放在哪里才能让它转到触发登录的URL。

请记住,只有当我直接在浏览器的地址栏中写一个url时,才会发生这种情况,而在我的应用程序中使用导航栏时就不会发生这种情况。有什么办法解决这个问题吗?我试着编写this.router.navigate([this.location.back()]);,但是这会使用signin-oidc创建一个循环,而不是将我发送到触发登录的页面(例如https://localhost:44392/search)。

EN

回答 1

Stack Overflow用户

发布于 2020-03-18 20:42:29

尝试实现刷新令牌登录以避免重定向到oidc,否则您需要保存页面状态以在登录后进行重定向。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60746535

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档