Как обработать новый токен обновления на стороне сервера? - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть два проекта.Одним из них является Identity Server 4, который обрабатывает пользователей и аутентификацию.Второй должен использовать первый для входа в систему и запросить токен для доступа к API.Когда мне нужно обновить токен, я не знаю, как обращаться с новым токеном доступа.Как я могу установить для аутентификации asp dot net core новый токен.Все процессы обновления выполняются на AuthorizationHandler.

Я пытался изменить претензии в отношении идентичности, но не работает.Я попытался сохранить токен доступа и обновить токен в своем собственном файле cookie, но у меня возникли проблемы, поскольку при обновлении токена я могу использовать их только при следующем запросе (мне не удалось изменить request.cookies только response.cookies.

public static async Task SetToken(TokenKind token,string value, HttpContext context)
{
    context.Response.Cookies.Append(GetTokenCookieName(token), value);
}


public static async Task<string> GetRefreshTokenAsync(HttpContext context)
{
    return await SearchToken(TokenKind.Refresh,context);
}


private static async Task<string> SearchToken(TokenKind token, HttpContext context)
{
    var tokenName = GetTokenName(token);
    var test = context.Request.Cookies;
    var apiToken = context.Request.Cookies.FirstOrDefault(x => x.Key == GetTokenCookieName(token)).Value;
    if (apiToken == null)
    {
        // Save token into cookie
        var tokenValue  = await context.GetTokenAsync(GetTokenName(TokenKind.Access));
        await SetToken(TokenKind.Access, tokenValue, context);

        var refreshTokenValue = await context.GetTokenAsync(GetTokenName(TokenKind.Refresh));
        await SetToken(TokenKind.Refresh, refreshTokenValue, context);

        switch (token)
        {
            case TokenKind.Access:
                return tokenValue;
            case TokenKind.Refresh:
                return refreshTokenValue;
            default:
                return null;
                break;
        }
    }
    else
    {
        return apiToken;
    }
}


private async Task<bool> RefreshToken(AuthorizationFilterContext mvcContext, HttpClient client)
{
    var refreshToken = await TokenUtils.GetRefreshTokenAsync(mvcContext.HttpContext);
    //await mvcContext.HttpContext.GetTokenAsync("refresh_token");

    var variables = new Dictionary<string, string>
            {
                { "grant_type", "refresh_token" },
                { "client_id", _configuration["ApplicationOptions:ClientId"] },
                { "client_secret", _configuration["ApplicationOptions:ClientSecret"] },
                { "refresh_token", refreshToken }
            };
    var content = new FormUrlEncodedContent(variables);

    var url = _configuration["ApplicationOptions:AuthorizeServer"] + "/connect/token";
    var response = await client.PostAsync(url, content);

    if (response.IsSuccessStatusCode == false)
    {
        var errorString = await response.Content.ReadAsStringAsync();
        var errorData = JsonConvert.DeserializeObject<dynamic>(errorString);
        return false;
    }

    var contentAsString = await response.Content.ReadAsStringAsync();
    var responseData = JsonConvert.DeserializeObject<dynamic>(contentAsString);
    var newAccessToken = (string)responseData.access_token;
    var newRefreshToken = (string)responseData.refresh_token;

    await TokenUtils.SetAccessToken(newAccessToken, mvcContext.HttpContext);
    await TokenUtils.SetRefreshToken(newRefreshToken, mvcContext.HttpContext);

    var result = await mvcContext.HttpContext.AuthenticateAsync();
    if (result.Succeeded)
    {
        result.Properties.StoreTokens(new List<AuthenticationToken>
                {
                    new AuthenticationToken
                    {
                        Name = OpenIdConnectParameterNames.AccessToken,
                        Value = newAccessToken
                    },
                    new AuthenticationToken
                    {
                        Name = OpenIdConnectParameterNames.RefreshToken,
                        Value = newRefreshToken
                    }
                });
        return true;
    }
    else
    {
        return false;
    }
}

Я хотел бы знать, что является хорошей практикой для хранения (или замены фактического токена доступа) аутентификацией ядра .net. Я уверен, что я делаю это неправильно.В конце я хочу правильно обработать мой токен и мой токен обновления, чтобы не просить пользователя снова войти в систему. Теперь с моим решением моему проекту будет отказано в доступе, когда ему необходимо обновить токен, и будет получен следующий запрос (потому что cookieнеобходимо отправить от пользователя).

1 Ответ

0 голосов
/ 07 февраля 2019

Спасибо Руарду ван Элбургу, я нашел решение (вот полный ответ ) И вот что я использовал для замены моих токенов:

// Save the information in the cookie
var info = await mvcContext.HttpContext.AuthenticateAsync("Cookies");

info.Properties.UpdateTokenValue("refresh_token", newRefreshToken);
info.Properties.UpdateTokenValue("access_token", newAccessToken);
info.Properties.UpdateTokenValue("expires_at", expiresAt.ToString("o", CultureInfo.InvariantCulture));

await mvcContext.HttpContext.SignInAsync("Cookies", info.Principal, info.Properties);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...