Keycloak Refresh Token未授权的asp .net核心

时间:2017-09-05 02:12:07

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

使用应用程序需要来自OIDC(keycloak)的刷新令牌才能获得访问资源的授权。但似乎返回的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"];
    }

1 个答案:

答案 0 :(得分:3)

根据我的理解,没有使用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);
相关问题