Как мне обменять токен обновления на новый токен доступа? - PullRequest
2 голосов
/ 08 апреля 2019

До окончания авторизации я хочу получить новый токен доступа в обмен на мой токен обновления.

Сейчас я получаю печенье, которое, по моему мнению, содержит все токены, которые я запрашивал (я не знаю, как проверить содержимое этого файла cookie).

Мой клиент может войти в систему и вызвать мой REST API с помощью ajax, однако, когда истекает время первой авторизации, вызовы API больше не работают.

У меня есть веб-приложение .NET, которое использует собственный REST API. API является частью одного и того же проекта. У него нет собственной конфигурации запуска.

Вот идея того, как это выглядит:

  • MyProject
    • MyApiFolder
      • FirstController.cs
      • SecondController.cs
      • ...
    • AppStartFolder
      • Startup.cs
      • RouteConfig.cs
      • ...
    • Просмотры
      • ...
    • Контроллеры
      • ...
    • Сценарии
      • ...
    • Web.config
    • ...

Я использую Identity Server 4 с промежуточным программным обеспечением Owin. Мой MVC-клиент может войти в систему и взаимодействовать с этим API до истечения срока авторизации.

Вот мой клиент гибридного потока:

using IdentityModel.Client;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;
using System;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Net;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;

namespace Cts.HomeService.Web.App_Start
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            var identityServerSection = (IdentityServerSectionHandler)System.Configuration.ConfigurationManager.GetSection("identityserversection");

            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = "Cookies",
                CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebChunkingCookieManager()
            });


            app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
            {
                ClientId = "localTestClient",
                Authority = "http://localhost:5000",
                RedirectUri = identityServerSection.Identity.RedirectUri,
                Scope = "openid profile offline_access",
                ResponseType = "code id_token",
                RequireHttpsMetadata = false,
                PostLogoutRedirectUri = identityServerSection.Identity.RedirectUri,

                TokenValidationParameters = new TokenValidationParameters
                {
                    NameClaimType = "name",
                    RoleClaimType = "role",
                },
                SignInAsAuthenticationType = "Cookies",
                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    AuthorizationCodeReceived = async n =>
                    {
                        var tokenClient = new TokenClient(
                            "http://localhost:5000/connect/token",
                            "localTestClient",
                            "");

                        var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(
                            n.Code, n.RedirectUri);

                        if (tokenResponse.IsError)
                        {
                            throw new Exception(tokenResponse.Error);
                        }

                        // use the access token to retrieve claims from userinfo
                        var userInfoClient = new UserInfoClient(
                            "http://localhost:5000/connect/userinfo");

                        var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken);

                        // create new identity
                        var id = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType);
                        id.AddClaims(userInfoResponse.Claims);

                        id.AddClaim(new Claim("access_token", tokenResponse.AccessToken));
                        id.AddClaim(new Claim("expires_at", DateTime.Now.AddSeconds(tokenResponse.ExpiresIn).ToLocalTime().ToString()));
                        id.AddClaim(new Claim("refresh_token", tokenResponse.RefreshToken));
                        id.AddClaim(new Claim("id_token", tokenResponse.IdentityToken));
                        id.AddClaim(new Claim("sid", n.AuthenticationTicket.Identity.FindFirst("sid").Value));

                        n.AuthenticationTicket = new AuthenticationTicket(
                            new ClaimsIdentity(id.Claims, n.AuthenticationTicket.Identity.AuthenticationType, "name", "role"),
                            n.AuthenticationTicket.Properties);
                    },

                    RedirectToIdentityProvider = n =>
                    {
                        {
                            // if signing out, add the id_token_hint
                            if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
                            {
                                var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");

                                if (idTokenHint != null)
                                {
                                    n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
                                }
                            }
                            return Task.FromResult(0);
                        }
                    }
                }
            });
        }
    }
}
  1. Как заставить клиента обменять свой токен доступа на токен обновления?
  2. Как узнать, что хранится в моем ASP.NET Cookie?

1 Ответ

1 голос
/ 08 апреля 2019

Получить токен обновления из файла cookie, используя методы расширения, определенные в Microsoft.AspNetCore.Authentication :

var refreshToken = await HttpContext.GetTokenAsync("refresh_token");

Используйте IdentityModel для обмена токена обновления на токен доступа:

var client = new HttpClient();

var response = await client.RequestRefreshTokenAsync(new RefreshTokenRequest
{
    Address = "http://localhost:5000/connect/token",

    ClientId = "localTestClient",
    ClientSecret = "secret",

    RefreshToken = refreshToken
});

var accessToken = response.AccessToken
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...