如果我已正确理解整个概念,客户端首先需要具有“offline_access”范围,以便能够使用刷新令牌,这是启用短期访问令牌的最佳实践,并且能够撤销刷新令牌,从而阻止任何新的访问令牌发给客户.
我成功获得了访问令牌和刷新令牌,但是我应该如何处理MVC客户端中访问令牌的实际更新过程?
OpenId Connect(OIDC)中间件可以自动处理吗?或者我应该通过基本检查访问令牌是否已过期或将很快过期(即将到来的30秒)来检查访问令牌的到期时间,我通过基本检查访问令牌是否过期(即将到来的30秒)然后通过使用刷新令牌调用令牌端点来刷新访问令牌?
是否建议在我的Controller操作方法中使用IdentityModel2库TokenClient扩展方法RequestRefreshTokenAsync来调用令牌端点?
我见过OIDC中间件事件中的代码请求访问令牌并使用响应存储包含过期日期时间的声明.问题是我的OIDC已经以某种方式自动请求访问令牌,因此在收到第一个访问令牌后直接请求新的访问令牌感觉不太好.
没有访问令牌刷新逻辑的Controller操作方法示例:
public async Task<IActionResult> GetInvoices() { var token = await HttpContext.Authentication.GetTokenAsync("access_token"); var client = new HttpClient(); client.SetBearerToken(token); var response = await client.GetStringAsync("http://localhost:5001/api/getInvoices"); ViewBag.Json = JArray.Parse(response).ToString(); return View(); }
解决方法
只要cookie仍然有效,其他所有请求都不会涉及OIDC中间件.
所以你必须自己照顾好这个.您要考虑的另一件事是,无论何时刷新访问令牌,您都必须更新现有令牌,这样您就不会丢失它.如果您不这样做,会话cookie将始终包含相同的令牌 – 原始令牌 – 您每次都会刷新它.
我找到的解决方案是将其挂钩到Cookies中间件.
这是一般流程:
>在每个请求中,使用Cookies中间件事件来检查访问令牌
>如果它接近到期时间,请申请一个新的
>替换ClaimsIdentity中的新访问权限和刷新令牌
>指示Cookies中间件更新会话cookie,使其包含新令牌
我喜欢这种方法的是,在你的MVC代码中,你几乎可以保证总是有一个有效的访问令牌,除非引用令牌连续多次失败.
我不喜欢的是它与MVC非常相关 – 更具体地说是Cookie中间件 – 所以它不是真正的便携式.
你可以看看我放在一起的this GitHub repo.它确实使用IdentityModel,因为它可以处理所有事情并隐藏您必须对IdentityServer进行的HTTP调用的大部分复杂性.