运行应用程序需要来自 OIDC (keycloak) 的刷新 token 才能获得访问资源的授权。但返回的 RefreshToken 似乎已过期或泄漏。
问题是我能够登录应用程序并调用 RefreshToken 并传递到我的同步网关方法,但响应始终为 401 无效。
不知道如何进一步调试。或者有什么方法可以尝试刷新 RefreshToken。
请参阅下面的代码。 [启动.cs]
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "Cookies",
AutomaticAuthenticate = true,
ExpireTimeSpan = TimeSpan.FromMinutes(60)
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
var oidcOptions = new OpenIdConnectOptions
{
AuthenticationScheme = "oidc",
SignInScheme = "Cookies",
Authority = Configuration["keycloak:authority"],
RequireHttpsMetadata = bool.Parse(Configuration["keycloak:httpMetadata"]),
PostLogoutRedirectUri = Configuration["keycloak:logoutUri"],
ClientId = Configuration["keycloak:clientId"],
ClientSecret = Configuration["keycloak:clientSecret"],
ResponseType = OpenIdConnectResponseType.Code,
GetClaimsFromUserInfoEndpoint = true,
SaveTokens = true,
CallbackPath = "/signin-oidc",
};
oidcOptions.Scope.Clear();
oidcOptions.Scope.Add("openid");
app.UseOpenIdConnectAuthentication(oidcOptions);
方法调用 RefreshToken
[HttpGet("getRec/{id}")]
public async Task<object> GetFileById(string id)
{
var refreshToken = await HttpContext.Authentication.GetTokenAsync("refresh_token");
//var authenticateInfo = await HttpContext.Authentication.GetAuthenticateInfoAsync("oidc");
//var refreshToken = authenticateInfo.Properties.Items[".Token.refresh_token"];
var token = HttpContext.Authentication.GetAuthenticateInfoAsync("refresh_token");
var val = await AppBal.GetFileById(refreshToken, id);
return val.Properties["files"];
}
最佳答案
据我了解,没有自动方法可以使用 OIDC 启动请求 token ... 这里的这些人在使用 cookie 验证器方面取得了很好的成绩: How to handle expired access token in asp.net core using refresh token with OpenId Connect
How to store the token received in AcquireTokenAsync with Active Directory
基本上,所有请求都可以验证 cookie 中的 token 。您可以检查过期的访问 token ,在这种情况下,向 keycloak 发送刷新请求...将提供访问 token ,您可以使用更新的访问 token 和刷新 token 来更新 cookie。
对于 keycloak,我会利用 Davids 的响应,而不是指向 Keycloak(而不是 Azure:
public class KeycloakRefreshTokenService
{
private const string HostUrl = "http://localhost:8080/";
private const string Realm = "TestRealm";
private string TokenUrl = $"/auth/realms/{Realm}/protocol/openid-connect/token";
private const string ContentType = "application/x-www-form-urlencoded";
和
public class KeycloakTokenResponse
{
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "token_type", Required = Required.Default)]
public string TokenType { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "expires_in", Required = Required.Default)]
public int ExpiresIn { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "refresh_expires_in", Required = Required.Default)]
public int RefreshExpiresIn { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "not-before-policy", Required = Required.Default)]
public string NotBeforePolicy { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "access_token", Required = Required.Default)]
public string AccessToken { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "refresh_token", Required = Required.Default)]
public string RefreshToken { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "id_token", Required = Required.Default)]
public string IdToken { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "session_state", Required = Required.Default)]
public string SessionState { get; set; }
}
否则代码应该可以正常工作(您可以查看错误响应 POCO
我还要注意的是,在设置过期时间时,使用的格式不正确(因为刷新一次后解析器不会解析它。所以我将 token 过期时间的更新更改为:
context.Properties.Items[".Token.expires_at"] =
DateTime.Now.AddSeconds(response.ExpiresIn).ToString("s", System.Globalization.CultureInfo.InvariantCulture);
关于c# - Keycloak刷新 token 未经授权的asp .net core,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46046075/