【问题标题】:Keycloak Refresh Token Unauthorized asp .net coreKeycloak刷新令牌未经授权的asp .net核心
【发布时间】:2018-02-13 05:23:10
【问题描述】:

运行应用程序需要来自 OIDC (keycloak) 的 Refresh Token 以获得访问资源的授权。但似乎返回的 RefreshToken 似乎已过期或泄漏。

问题是我能够登录到应用程序并调用 RefreshToken 并传递给我的同步网关方法,但响应总是 401 无效。

不确定如何进一步调试。或者有没有办法可以尝试刷新 RefreshToken。

见下面的代码。 [startup.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"];
    }

【问题讨论】:

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


    【解决方案1】:

    据我了解,没有自动方法可以使用 OIDC 触发请求令牌... 这里的这些人在实现使用 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 中的令牌。您可以检查是否有过期的访问令牌,在这种情况下向 keycloak 发送刷新请求...将提供访问令牌,您可以使用更新的访问令牌和刷新令牌更新 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

    我还要注意,在设置到期时,使用的格式不正确(因为解析器在刷新一次后不会解析它。所以我会将令牌到期的更新更改为:

    context.Properties.Items[".Token.expires_at"] =
                       DateTime.Now.AddSeconds(response.ExpiresIn).ToString("s", System.Globalization.CultureInfo.InvariantCulture);
    

    【讨论】:

      猜你喜欢
      • 2020-03-06
      • 2021-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-05
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      相关资源
      最近更新 更多