问题描述
我正在尝试在我的 Angular SPA 中以静默方式刷新访问令牌。 ADFS 认证完成。它工作正常,配置如下:
oauthService.configure({
redirectUri:
window.location.origin + '/login',requireHttps: true,scope: 'openid profile email',responseType: 'id_token token',oidc: true,clientId: environment.adfsClientId,loginUrl: environment.adfsUrl + '/oauth2/authorize',issuer: environment.adfsUrl,logoutUrl:
environment.adfsUrl +
'/ls/?wa=wsignoutcleanup1.0&wreply=' +
location.protocol +
'//' +
location.hostname + '/login',postlogoutRedirectUri:
window.location.origin + '/login',});
this.oauthService.tokenValidationHandler = new JwksValidationHandler();
this.oauthService.setStorage(localStorage);
this.oauthService.timeoutFactor = 0.03; // for faster testing
this.oauthService.silentRefreshredirectUri = window.location.origin + '/search';
this.oauthService.setupAutomaticSilentRefresh();
为了刷新令牌,iframe 被添加到当前页面。一切看起来都不错。并且我已将以下代码添加到 index.html 文件中。
<script>
parent.postMessage(location.hash,location.origin);
</script>
此事件在 silentRefreshPostMessageEventListener 中的 angular-oauth2-oidc.js 中被捕获。 但问题是我在那个列表中得到的信息是,
MSIS9621:无法在未获得用户输入的情况下处理 OAuth 授权请求。
的https:// [ADFS域] / ADFS /的oauth2 /授权/ RESPONSE_TYPE = id_token%20token&CLIENT_ID = af0e4d79-ae9d-4fda-86b3-265d1e86a61e&状态= UmtkeUJfNDBCUU1VWkZyeWcubFlldlo3ZHFFbFRuVDI3TnNZUU5FVXJxTXpX&REDIRECT_URI = HTTP%3A%2F%2Flocalhost%3A4200%2Fsearch&范围= OpenID的%20profile%20email&nonce=UmtkeUJfNDBCUU1VWkZyeWcubFlldlo3ZHFFbFRuVDI3TnNZUU5FVXJxTXpX&prompt=none
如果我在新标签页中打开这个 URL,我会在 Uri 中获得一个新的访问令牌。
谁能告诉我我在这里做错了什么?
更新
谢谢加里·阿彻的回答。
我通过在 PowerShell 中执行此代码在 ADFS 中进行了更改,
Set-AdfsResponseHeaders -RemoveHeaders "x-frame-options"
什么都没有改变。然后我设置了下面的命令来解决这个问题。
Set-AdfsResponseHeaders -SetHeaderName "Content-Security-Policy" -SetHeaderValue "frame-ancestors"
解决方法
看起来 ADFS 正在阻止 iframe 请求并发送 X-Frame-Oprions=DENY 标头。根据 this post,它可以在 ADFS 2019 中解决。
一种可行的选择是改用刷新令牌,但不建议在 2021 年将其用于生产 SPA,因为不应将刷新令牌存储在浏览器中的任何位置。
值得记住的是,2021 年也不真正推荐基于静默 iframe 的更新,因为攻击者可能会在自己隐藏的 iframe 上利用它并获得令牌。
2021 年的首选方案是 Back End for Front End 方法,其中 API 处理 SPA 的令牌续订。