c# - Keycloak刷新 token 未经授权的asp .net core

标签 c# asp.net-core-mvc .net-core openid-connect keycloak

运行应用程序需要来自 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/

相关文章:

C# 流程 - 数据流、XML 和数据网格

c# - 将 ContentControl 绑定(bind)到将确定要查看哪个用户控件的 ApplicationViewModel?

c# - + 运算符如何用于组合委托(delegate)?

c# - 关于将net core app部署到heroku服务器

c# - 访问/写入 EventLog 时出现问题

asp.net - 从 ASP.NET Core 连接到 SQL Server 的最佳实践?

security - aspnetcore 是否有一个带有 Controller 的银河大小的安全漏洞,或者我错过了什么?

c# - .Net/SQL 在 datetime2 上插入和选择不匹配

c# - System.Random 的多个实例是否仍然在 .Net Core 中使用相同的种子?

html - 自闭 TagHelper 合并兄弟元素的 html 标记