在客户端处理AuthenticationFailureResult

时间:2017-11-04 21:08:04

标签: asp.net-web-api oauth-2.0 asp.net-web-api2 jwt access-token

我正在使用this方法来保护我们的api与令牌。不确定,如何在客户端处理令牌到期响应。我在api方面看到了两个选项 -

  1. 挑战
  2. WWW-Authenticate标题
  3. 假设我的客户正在请求联系人列表,但他们的令牌已于30分钟前发布(我们当前的令牌年龄)。我们现在做什么?

    1. 如果我们再次申请资格证书不是很好的经历
    2. 使用do-while循环,直到我们成功响应。我们的客户端是一个插件,因此我们可以将用户的凭据存储在db。
    3. try \ catch也可能是一种可能性
    4. 此时实现IdentityServer和刷新令牌对我们来说太过分了。

1 个答案:

答案 0 :(得分:0)

有几种方法可以在它们到期后获得新的令牌。每次令牌过期时都要求凭据,这不是一个好的经验。实现此目的的一些方法是使用MemoryCache或文本文件来存储令牌,然后继续读取它。令牌过期后,获得一个新的并替换您之前存储的那个。下面的示例代码

public async Task<string> GetToken(HttpClient client)
{

    Token token;

    MemoryCache memCache = MemoryCache.Default;

    var resource = memCache.Get(Settings.TokenKey);

    if (resource.IsNotNull())
    {

        token = (Token)resource;

        if (token != null && token.Expires < DateTime.Now)
        {
            token = await RequestNewToken(client);
            return token.AccessToken;
        }
    }

    token = await RequestNewToken(client);
    return token.AccessToken;

}

private async Task<Token> RequestNewToken(HttpClient client)
{
    var tokenRequestContent = GetTokenRequestContent();

    var tokenResponse = client.PostAsync(Settings.TokenUrl, tokenRequestContent).Result;

    Token token = null;

    MemoryCache memCache = MemoryCache.Default;

    if (tokenResponse.IsSuccessStatusCode)
    {
        token = await tokenResponse.Content.ReadAsAsync<Token>();
        memCache.Add(Settings.TokenKey, token, DateTimeOffset.UtcNow.AddHours(2));
    }
    else
    {
        var error = await tokenResponse.Content.ReadAsStringAsync();
        Console.WriteLine(error);
    }

    if (token == null) throw new NullReferenceException("Token is null");

    return token;
}

private FormUrlEncodedContent GetTokenRequestContent()
{
    var credentials = new List<KeyValuePair<string, string>>
    {
        new KeyValuePair<string, string>("grant_type", Settings.Password),
        new KeyValuePair<string, string>("userName", Settings.Username),
        new KeyValuePair<string, string>("password", Settings.UserPassword)
    };

    return new FormUrlEncodedContent(credentials);
}

设置只是一个保存常量的静态类。