我有两个项目。一个是处理用户和身份验证的身份服务器 4。第二个需要使用第一个登录并请求 token 以访问 API。 当我需要刷新 token 时,我现在不知道如何处理新的访问 token 。如何将新 token 设置为 authentification asp dot net core。所有刷新过程都在 AuthorizationHandler 上进行。
我试图修改身份声明,但没有成功。我试图在我自己的 cookie 中存储访问 token 和刷新 token ,但我遇到了麻烦,因为当我刷新 token 时,我只能在下一个请求中使用它们(我没有实现仅修改 request.cookies 和 response.cookies。
public static async Task SetToken(TokenKind token,string value, HttpContext context)
{
context.Response.Cookies.Append(GetTokenCookieName(token), value);
}
public static async Task<string> GetRefreshTokenAsync(HttpContext context)
{
return await SearchToken(TokenKind.Refresh,context);
}
private static async Task<string> SearchToken(TokenKind token, HttpContext context)
{
var tokenName = GetTokenName(token);
var test = context.Request.Cookies;
var apiToken = context.Request.Cookies.FirstOrDefault(x => x.Key == GetTokenCookieName(token)).Value;
if (apiToken == null)
{
// Save token into cookie
var tokenValue = await context.GetTokenAsync(GetTokenName(TokenKind.Access));
await SetToken(TokenKind.Access, tokenValue, context);
var refreshTokenValue = await context.GetTokenAsync(GetTokenName(TokenKind.Refresh));
await SetToken(TokenKind.Refresh, refreshTokenValue, context);
switch (token)
{
case TokenKind.Access:
return tokenValue;
case TokenKind.Refresh:
return refreshTokenValue;
default:
return null;
break;
}
}
else
{
return apiToken;
}
}
private async Task<bool> RefreshToken(AuthorizationFilterContext mvcContext, HttpClient client)
{
var refreshToken = await TokenUtils.GetRefreshTokenAsync(mvcContext.HttpContext);
//await mvcContext.HttpContext.GetTokenAsync("refresh_token");
var variables = new Dictionary<string, string>
{
{ "grant_type", "refresh_token" },
{ "client_id", _configuration["ApplicationOptions:ClientId"] },
{ "client_secret", _configuration["ApplicationOptions:ClientSecret"] },
{ "refresh_token", refreshToken }
};
var content = new FormUrlEncodedContent(variables);
var url = _configuration["ApplicationOptions:AuthorizeServer"] + "/connect/token";
var response = await client.PostAsync(url, content);
if (response.IsSuccessStatusCode == false)
{
var errorString = await response.Content.ReadAsStringAsync();
var errorData = JsonConvert.DeserializeObject<dynamic>(errorString);
return false;
}
var contentAsString = await response.Content.ReadAsStringAsync();
var responseData = JsonConvert.DeserializeObject<dynamic>(contentAsString);
var newAccessToken = (string)responseData.access_token;
var newRefreshToken = (string)responseData.refresh_token;
await TokenUtils.SetAccessToken(newAccessToken, mvcContext.HttpContext);
await TokenUtils.SetRefreshToken(newRefreshToken, mvcContext.HttpContext);
var result = await mvcContext.HttpContext.AuthenticateAsync();
if (result.Succeeded)
{
result.Properties.StoreTokens(new List<AuthenticationToken>
{
new AuthenticationToken
{
Name = OpenIdConnectParameterNames.AccessToken,
Value = newAccessToken
},
new AuthenticationToken
{
Name = OpenIdConnectParameterNames.RefreshToken,
Value = newRefreshToken
}
});
return true;
}
else
{
return false;
}
}
我想知道用 .net 核心身份验证存储(或替换实际访问 token )的好习惯是什么。我确定我没有以正确的方式做这件事。最后我想正确处理我的 token 和我的刷新 token 不要求用户再次登录。现在使用我的解决方案,我的项目将在需要刷新 token 时拒绝访问,并且将授予下一个请求(因为需要从用户重新发送 cookie)。
最佳答案
感谢 Ruard van Elburg 我找到了解决方案(这里是 complete answer) 这就是我用来替换我的 token 的东西:
// Save the information in the cookie
var info = await mvcContext.HttpContext.AuthenticateAsync("Cookies");
info.Properties.UpdateTokenValue("refresh_token", newRefreshToken);
info.Properties.UpdateTokenValue("access_token", newAccessToken);
info.Properties.UpdateTokenValue("expires_at", expiresAt.ToString("o", CultureInfo.InvariantCulture));
await mvcContext.HttpContext.SignInAsync("Cookies", info.Principal, info.Properties);
关于c# - 如何在服务器端处理新的刷新 token ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54569182/