c# - 我应该如何将我的刷新令牌换成新的访问令牌?
问题描述
在授权到期之前,我想获得一个新的访问令牌以换取我的刷新令牌。
现在我得到一个 cookie,我相信它包含我要求的所有令牌(我不知道如何检查这个 cookie 的内容)。
我的客户端能够使用 ajax 登录并调用我的 REST API,但是当第一次授权到期时,API 调用自然不再起作用。
我有一个使用自己的 REST API 的 .NET Web 应用程序。API 是同一个项目的一部分。它没有自己的启动配置。
这是它的样子:
- 我的项目
- 我的 API 文件夹
- 第一控制器.cs
- SecondController.cs
- ...
- 应用开始文件夹
- 启动.cs
- 路由配置.cs
- ...
- 意见
- ...
- 控制器
- ...
- 脚本
- ...
- 网页配置
- ...
- 我的 API 文件夹
我正在使用带有 Owin 中间件的 Identity Server 4。我的 MVC 客户端能够登录,并能够与此 API 通信,直到授权到期。
这是我的混合流客户端:
using IdentityModel.Client;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;
using System;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Net;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
namespace Cts.HomeService.Web.App_Start
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
var identityServerSection = (IdentityServerSectionHandler)System.Configuration.ConfigurationManager.GetSection("identityserversection");
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies",
CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebChunkingCookieManager()
});
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
ClientId = "localTestClient",
Authority = "http://localhost:5000",
RedirectUri = identityServerSection.Identity.RedirectUri,
Scope = "openid profile offline_access",
ResponseType = "code id_token",
RequireHttpsMetadata = false,
PostLogoutRedirectUri = identityServerSection.Identity.RedirectUri,
TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role",
},
SignInAsAuthenticationType = "Cookies",
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthorizationCodeReceived = async n =>
{
var tokenClient = new TokenClient(
"http://localhost:5000/connect/token",
"localTestClient",
"");
var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(
n.Code, n.RedirectUri);
if (tokenResponse.IsError)
{
throw new Exception(tokenResponse.Error);
}
// use the access token to retrieve claims from userinfo
var userInfoClient = new UserInfoClient(
"http://localhost:5000/connect/userinfo");
var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken);
// create new identity
var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType);
id.AddClaims(userInfoResponse.Claims);
id.AddClaim(new Claim("access_token", tokenResponse.AccessToken));
id.AddClaim(new Claim("expires_at", DateTime.Now.AddSeconds(tokenResponse.ExpiresIn).ToLocalTime().ToString()));
id.AddClaim(new Claim("refresh_token", tokenResponse.RefreshToken));
id.AddClaim(new Claim("id_token", tokenResponse.IdentityToken));
id.AddClaim(new Claim("sid", n.AuthenticationTicket.Identity.FindFirst("sid").Value));
n.AuthenticationTicket = new AuthenticationTicket(
new ClaimsIdentity(id.Claims, n.AuthenticationTicket.Identity.AuthenticationType, "name", "role"),
n.AuthenticationTicket.Properties);
},
RedirectToIdentityProvider = n =>
{
{
// if signing out, add the id_token_hint
if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
{
var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");
if (idTokenHint != null)
{
n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
}
}
return Task.FromResult(0);
}
}
}
});
}
}
}
- 如何让客户端用他的访问令牌交换刷新令牌?
- 我如何知道我的 ASP.NET Cookie 中存储了什么?
解决方案
使用Microsoft.AspNetCore.Authentication中定义的扩展方法从 cookie 中获取刷新令牌:
var refreshToken = await HttpContext.GetTokenAsync("refresh_token");
用于IdentityModel
将刷新令牌交换为访问令牌:
var client = new HttpClient();
var response = await client.RequestRefreshTokenAsync(new RefreshTokenRequest
{
Address = "http://localhost:5000/connect/token",
ClientId = "localTestClient",
ClientSecret = "secret",
RefreshToken = refreshToken
});
var accessToken = response.AccessToken
推荐阅读
- javascript - 检查数据是否等于 Firebase 上的某个值
- binary - 这是下溢的情况吗?
- sql - 在 R 中查询撇号
- swift - 围绕特定节点环绕 Scenekit 摄像机
- npm - 在 CentOS 7 上运行大炮(使用 npm)失败
- javascript - 在javascript中比较一维数组和多维数组
- css - css后台在服务器中找不到文件
- angular - 运行“ng build --prod”时出现“./src/polyfills.ts 中的错误”
- php - Facebook InsightsPresets 未找到
- java - 从 Activity 向 Fragment 发送数据:NPE