gpt4 book ai didi

authentication - IdentityServer4 客户端 - 在 CookieAuthenticationEvents 上刷新访问 token

转载 作者:行者123 更新时间:2023-12-01 11:20:06 27 4
gpt4 key购买 nike

我正在尝试在访问 token 过期时使用刷新 token 。回答了类似的问题 here .和 a sample code to renew token通过一个 Action

我最终在 startup.cs 中得到以下代码

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "Cookies",
//ExpireTimeSpan = TimeSpan.FromSeconds(100),
AutomaticAuthenticate = true,
AutomaticChallenge = true,
Events = new CookieAuthenticationEvents()
{
OnValidatePrincipal = async x =>
{
if (x.Properties?.Items[".Token.expires_at"] == null) return;

var logger = loggerFactory.CreateLogger(this.GetType());

var now = DateTimeOffset.UtcNow;
var tokenExpireTime = DateTime.Parse(x.Properties.Items[".Token.expires_at"]).ToUniversalTime();
var timeElapsed = now.Subtract(x.Properties.IssuedUtc.Value);
var timeRemaining = tokenExpireTime.Subtract(now.DateTime);

if (timeElapsed > timeRemaining)
{
var httpContextAuthentication = x.HttpContext.Authentication;//Donot use the HttpContext.Authentication to retrieve anything, this cause recursive call to this event
var oldAccessToken = await httpContextAuthentication.GetTokenAsync("access_token");
var oldRefreshToken = await httpContextAuthentication.GetTokenAsync("refresh_token");
logger.LogInformation($"Refresh token :{oldRefreshToken}, old access token:{oldAccessToken}");


var disco = await DiscoveryClient.GetAsync(AuthorityServer);
if (disco.IsError) throw new Exception(disco.Error);

var tokenClient = new TokenClient(disco.TokenEndpoint, ApplicationId, "secret");
var tokenResult = await tokenClient.RequestRefreshTokenAsync(oldRefreshToken);
logger.LogInformation("Refresh token requested. " + tokenResult.ErrorDescription);


if (!tokenResult.IsError)
{

var oldIdToken = await httpContextAuthentication.GetTokenAsync("id_token");
var newAccessToken = tokenResult.AccessToken;
var newRefreshToken = tokenResult.RefreshToken;

var tokens = new List<AuthenticationToken>
{
new AuthenticationToken {Name = OpenIdConnectParameterNames.IdToken, Value = oldIdToken},
new AuthenticationToken {Name = OpenIdConnectParameterNames.AccessToken, Value = newAccessToken},
new AuthenticationToken {Name = OpenIdConnectParameterNames.RefreshToken, Value = newRefreshToken}
};

var expiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResult.ExpiresIn);
tokens.Add(new AuthenticationToken { Name = "expires_at", Value = expiresAt.ToString("o", CultureInfo.InvariantCulture) });

var info = await httpContextAuthentication.GetAuthenticateInfoAsync("Cookies");
info.Properties.StoreTokens(tokens);
await httpContextAuthentication.SignInAsync("Cookies", info.Principal, info.Properties);

}
x.ShouldRenew = true;
}
else
{
logger.LogInformation("Not expired");
}
}

}
});

客户端设置如下
AllowAccessTokensViaBrowser = true,
RefreshTokenUsage = TokenUsage.ReUse,
RefreshTokenExpiration = TokenExpiration.Sliding,
AbsoluteRefreshTokenLifetime = 86400,
AccessTokenLifetime = 10,
AllowOfflineAccess = true,
AccessTokenType = AccessTokenType.Reference

成功登录后,我收到每个其他请求的 401。日志说

[Identity Server]2017-07-04 10:15:58.819 +01:00 [Debug] "TjpIkvHQi../cfivu6Nql5ADJJlZRuoJV1QI=" found in database: True

[Identity Server]2017-07-04 10:15:58.820 +01:00 [Debug] "reference_token" grant with value: "..9e64c1235c6675fcef617914911846fecd72f7b372" found in store, but has expired.

[Identity Server]2017-07-04 10:15:58.821 +01:00 [Error] Invalid reference token. "{ \"ValidateLifetime\": true,
\"AccessTokenType\": \"Reference\", \"TokenHandle\": \"..9e64c1235c6675fcef617914911846fecd72f7b372\" }"

[Identity Server]2017-07-04 10:15:58.822 +01:00 [Debug] Token is invalid.

[Identity Server]2017-07-04 10:15:58.822 +01:00 [Debug] Creating introspection response for inactive token.

[Identity Server]2017-07-04 10:15:58.822 +01:00 [Information] Success token introspection. Token status: "inactive", for API name: "api1"



任何帮助都会受到高度赞赏

更新 :

基本上,当 token 过期时,我会收到 System.StackOverflowException在下一行
var tokenExpireTime = DateTime.Parse(x.Properties.Items[".Token.expires_at"]).ToUniversalTime();

更新 2 :
不要使用 HttpContext.Authentication 来检索任何东西。检查下面的答案以找到工作的实现

最佳答案

我过去两天一直在研究这个,但无法完成这项工作。有趣的是,在这里发布问题后,我在 2 小时内就让它工作了:)

Events = new CookieAuthenticationEvents()
{
OnValidatePrincipal = async x =>
{
if (x.Properties?.Items[".Token.expires_at"] == null) return;
var now = DateTimeOffset.UtcNow;

var tokenExpireTime = DateTime.Parse(x.Properties.Items[".Token.expires_at"]).ToUniversalTime();
var timeElapsed = now.Subtract(x.Properties.IssuedUtc.Value);
var timeRemaining = tokenExpireTime.Subtract(now.DateTime);
WriteMessage($"{timeRemaining} and elapsed at {timeElapsed}");
if (timeElapsed > timeRemaining)
{
var oldAccessToken = x.Properties.Items[".Token.access_token"];

var oldRefreshToken = x.Properties.Items[".Token.refresh_token"];
WriteMessage($"Refresh token :{oldRefreshToken}, old access token {oldAccessToken}");

var disco = await DiscoveryClient.GetAsync(AuthorityServer);
if (disco.IsError) throw new Exception(disco.Error);

var tokenClient = new TokenClient(disco.TokenEndpoint, ApplicationId, "secret");
var tokenResult = await tokenClient.RequestRefreshTokenAsync(oldRefreshToken);

if (!tokenResult.IsError)
{
var oldIdToken = x.Properties.Items[".Token.id_token"];//tokenResult.IdentityToken

var newAccessToken = tokenResult.AccessToken;
var newRefreshToken = tokenResult.RefreshToken;

var tokens = new List<AuthenticationToken>
{
new AuthenticationToken {Name = OpenIdConnectParameterNames.IdToken, Value = oldIdToken},
new AuthenticationToken {Name = OpenIdConnectParameterNames.AccessToken, Value = newAccessToken},
new AuthenticationToken {Name = OpenIdConnectParameterNames.RefreshToken, Value = newRefreshToken}
};

var expiresAt = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResult.ExpiresIn);
tokens.Add(new AuthenticationToken { Name = "expires_at", Value = expiresAt.ToString("o", CultureInfo.InvariantCulture) });

x.Properties.StoreTokens(tokens);

WriteMessage($"oldAccessToken: {oldAccessToken}{Environment.NewLine} and new access token {newAccessToken}");

}
x.ShouldRenew = true;
}
}
}

基本上 httpContextAuthentication.GetTokenAsync出于这个原因,使这个递归 StackOverflowException发生。

如果此实现有任何问题,请告诉我

关于authentication - IdentityServer4 客户端 - 在 CookieAuthenticationEvents 上刷新访问 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44902031/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com