【发布时间】:2020-04-29 22:29:47
【问题描述】:
我目前正在设置一个 身份服务器,其中包含一个 SPA 客户端和一些 REST 服务来使用数据。
似乎一切正常,但我目前很难理解,为什么每个带有有效 access_token 的 API 调用都会触发对身份服务器的 /authorize 端点的请求。
登录页面上的按钮
这个按钮只是通过来自@angular/common/http 的HttpClient 实例调用我的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”按钮,就会发出以下三个请求。
-
OPTIONS请求我的 REST API。 -
/authorize请求(最终返回一个 http302并执行我想避免的重定向) -
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