【问题标题】:Angular - oidc-client sends an /authorize request for each REST API callAngular - oidc-client 为每个 REST API 调用发送一个 /authorize 请求
【发布时间】:2020-04-29 22:29:47
【问题描述】:

我目前正在设置一个 身份服务器,其中包含一个 SPA 客户端和一些 REST 服务来使用数据。

似乎一切正常,但我目前很难理解,为什么每个带有有效 access_token 的 API 调用都会触发对身份服务器的 /authorize 端点的请求。


登录页面上的按钮


这个按钮只是通过来自@angular/common/httpHttpClient 实例调用我的REST API

这些按钮在我的/login 页面上。

来自身份服务器的回调设置为转到/login/callback


/authorize 端点的请求


每次单击按钮都会向/authorize 端点发送一个请求,结果会将我通过http 302 重定向到/login/callback 页面。

请求仍然通过,一切正常,但总是发生这种重定向。

我原以为如果access_token 有效,则不需要此请求?


AccessToken 拦截器


AccessTokenInterceptor 中,我确实调用了我的OidcService,它可以从oidc-client 库访问UserManager

由于某种原因,每个涉及UserManager 上的getUser() 的请求都会触发这个/authorize 请求作为响应——即使access_token 仍然有效。我在这里想念什么?

@Injectable()
export class AccessTokenInterceptor implements HttpInterceptor {

constructor(private oidcService: OidcService) { }

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

return this.oidcService.getUser()
  .mergeMap((user: User) => {

    if (user) {
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${user.access_token}`
        }
      });
    }

    return next.handle(request);
   });
  }
 }

感谢您在这方面的任何帮助,如果您需要更多代码示例,请告诉我。


更新 1


一旦我调用“Call Api”按钮,就会发出以下三个请求。

  1. OPTIONS 请求我的 REST API。
  2. /authorize 请求(最终返回一个 http 302 并执行我想避免的重定向)
  3. GET 请求这是我打算做的。


更新 2


Web 应用程序 - UserManagerSettings

{
    "authority": "https://localhost:44327",
    "client_id": "webClient",
    "response_type": "id_token token",
    "scope": "openid testclientapi testclientapi.read testclientapi.write",
    "redirect_uri": "http://localhost:4200/login/callback",
    "post_logout_redirect_uri": "http://localhost:4200/logout/callback",
    "silent_redirect_uri": "http://localhost:4200/login/silentLogin",
    "automaticSilentRenew": true,
    "monitorSession": true,
    "revokeAccessTokenOnSignout": true,
    "loadUserInfo": true
}

身份服务器 - 客户端配置

       new Client {
                    ClientId = "webClient",
                    ClientName = "myclient",
                    AllowedGrantTypes = GrantTypes.Implicit,

                    AccessTokenType = AccessTokenType.Reference,
                    AccessTokenLifetime = 60 * 60,
                    IdentityTokenLifetime = 30,
                    RequireConsent = false,
                    AllowOfflineAccess = true,
                    AllowAccessTokensViaBrowser = true,

                    ClientSecrets =
                    {
                        new Secret("XYZ)
                    },

                    AllowedCorsOrigins = new string[]
                    {
                        "http://localhost:4200",
                    },
                    RedirectUris =
                    {
                        "http://localhost:4200/login/callback",
                        "http://localhost:4200/login/silentLogin",
                        "http://localhost:4200/logout/callback",

                    },
                    PostLogoutRedirectUris =
                    {
                        "http://localhost:4200/logout/callback",                         
                    },

                    AllowedScopes =
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        "testclientapi",
                        "testclientapi.read",
                        "testclientapi.write"
                    }
                }
            };

更新 3


getUser() : Observable<User> {
    return Observable.fromPromise(this.userManager.getUser())
  }

【问题讨论】:

  • 您的登录回调组件是否正确调用了signinRedirectCallback() 方法?您的浏览器会话存储中是否有 oidc-client 存储的有效会话?应该有一个像oidc.user:https://yoururl.com这样的键
  • 我在登录过程中唯一调用的是signinRedirect(),作为初始登录过程的一部分。访问令牌的存储没有任何问题,我可以调用我的 REST API 服务。我只是好奇为什么/authorize 端点会为每个后续请求调用,即使我有一个完全有效的access_token
  • 好吧,这确实很奇怪。显然你的拦截器每次都会以某种方式触发登录你可以发布你的用户管理器配置(可以匿名 - 我不关心范围和 url),也许你的 getUser 实现(显然不仅仅是用户管理器在这里起作用)
  • 仍然没有什么异常。您可以尝试关闭silentRenew 和loadUserInfo 来测试puproses。你的 oidcService.getUser() 方法是做什么的?

标签: angular oauth-2.0 openid identityserver4 oidc-client-js


【解决方案1】:

我找到了解决此问题的临时解决方法。

一旦我没有从/login 路由而是从其他位置(例如/admin)触发 REST API 请求,它就像魔术一样工作。

最终不会向/authorize 端点发送任何请求。

一旦我弄清楚为什么会发生这种情况,我会更新这个答案。

更新 1

我现在在执行 /logout 请求时遇到了类似的问题 - 还必须将其移至另一条完整的路线...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-09
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    • 2019-03-01
    • 1970-01-01
    相关资源
    最近更新 更多