Подтвердить что ты не робот

Как обновить токены доступа Owin с помощью токенов обновления без создания нового токена обновления?

Мне удалось получить простой примерный код, который может создать токен-носитель, а также запросить новые, обновив токен, прочитав другие форумы здесь, в stackoverflow.

Класс запуска выглядит следующим образом:

public class Startup
{
    public static void Configuration(IAppBuilder app)
    {
        app.UseOAuthBearerAuthentication(
                      new OAuthBearerAuthenticationOptions());

        app.UseOAuthAuthorizationServer(
                      new OAuthAuthorizationServerOptions
                      {
                          TokenEndpointPath = new PathString("/Token"),
                          Provider = new OAuthAuthorizationServerProvider()
                          {
                              OnValidateClientAuthentication = async c =>
                              {
                                  c.Validated();
                              },
                              OnGrantResourceOwnerCredentials = async c =>
                              {
                                  if (c.UserName == "alice" && c.Password == "supersecret")
                                  {
                                      Claim claim1 = new Claim(ClaimTypes.Name, c.UserName);
                                      Claim[] claims = new Claim[] { claim1 };
                                      ClaimsIdentity claimsIdentity =
                                          new ClaimsIdentity(
                                             claims, OAuthDefaults.AuthenticationType);
                                      c.Validated(claimsIdentity);
                                  }
                              }
                          },
                          AccessTokenExpireTimeSpan = TimeSpan.FromSeconds(40),
                          AllowInsecureHttp = true,
                          RefreshTokenProvider = new ApplicationRefreshTokenProvider()
                      });
    }
}

И у меня также есть класс для токенов обновления, которые выглядят следующим образом:

public class ApplicationRefreshTokenProvider : AuthenticationTokenProvider
{
    public override void Create(AuthenticationTokenCreateContext context)
    {
        // Expiration time in seconds
        int expire = 2 * 60;
        context.Ticket.Properties.ExpiresUtc = new DateTimeOffset(DateTime.Now.AddSeconds(expire));
        context.SetToken(context.SerializeTicket());
    }

    public override void Receive(AuthenticationTokenReceiveContext context)
    {
        context.DeserializeTicket(context.Token);
    }
}

Я понимаю, что, предлагая токен refresh, вы должны получить новый токен доступа . Однако то, что происходит в этом коде, заключается в том, что когда я предоставляю токен refresh, новый и обновляемый токен создается и возвращается. Я хочу, чтобы он создавал как доступ, так и токен обновления при первом появлении имени пользователя/пароля, но не кажется правильным создание новых токенов обновления каждый раз, когда запрос на новый токен доступа выполняется с помощью токена обновления?

Если я, например, задал свой код, имеет 20-минутный промежуток времени на токене доступа и две недели на токенах обновления , новые токены доступа может быть создано каждые 20 минут, что хорошо, однако новые токены обновления также будут создаваться каждые 20 минут, но последние 2 недели. Тогда будет создано, но не будет использовано токены обновления.

Вопрос:

Я только начал читать/узнавать об этом несколько часов назад, поэтому я совершенно не уверен, но это правильное поведение, или я должен каким-то образом подделать свой код, чтобы создавать и возвращать новый токен доступа , когда предоставляется токен обновления, а не создание и возврат нового токена обновления . Любая помощь или ввод высоко оценены, спасибо!

4b9b3361

Ответ 1

Поскольку никто еще не ответил, я собираюсь предоставить то, что я сделал, и что делает то, что я искал. Поэтому я собираюсь принять этот ответ на данный момент.

public class Startup
{
public static void Configuration(IAppBuilder app)
{
    app.UseOAuthBearerAuthentication(
                  new OAuthBearerAuthenticationOptions());

    app.UseOAuthAuthorizationServer(
                  new OAuthAuthorizationServerOptions
                  {
                      TokenEndpointPath = new PathString("/Token"),
                      Provider = new OAuthAuthorizationServerProvider()
                      {
                          OnValidateClientAuthentication = async c =>
                          {
                              c.Validated();
                          },
                          OnGrantResourceOwnerCredentials = async c =>
                          {
                           //Add a string with the current date
                            string dateNow = DateTime.UtcNow.ToString();

                              if (c.UserName == "alice" && c.Password == "supersecret")
                              {
                                  Claim claim1 = new Claim(ClaimTypes.Name, c.UserName);
                                  Claim[] claims = new Claim[] { claim1 };
                                  ClaimsIdentity claimsIdentity =
                                      new ClaimsIdentity(
                                         claims, OAuthDefaults.AuthenticationType);

                                  //Add a claim with the creationdate of the token
                                  claimsIdentity.AddClaim(new Claim("creationDate", dateNow));

                                  c.Validated(claimsIdentity);
                              }
                          }
                      },
                      AccessTokenExpireTimeSpan = TimeSpan.FromSeconds(40),
                      AllowInsecureHttp = true,
                      RefreshTokenProvider = new ApplicationRefreshTokenProvider()
                  });
}
}

И в ApplicationRefreshTokenProvider я сделал те изменения

public class ApplicationRefreshTokenProvider : AuthenticationTokenProvider
{
    public override void Create(AuthenticationTokenCreateContext context)
    {
    //Get the claim which holds creation date
     DateTime creationDate = Convert.ToDateTime(clientid.Claims.Where(c => c.Type == "creationDate").Single().Value);
     //Create a variable holding current time minus 30 seconds(This is how long time you can create new refresh tokens by providing your original refresh token)
     DateTime now = DateTime.UtcNow.AddSeconds(-30);


    //If the time has passed more than 30 seconds from the time you got your original access and refresh token by providing credentials
    //you may not create and return new refresh tokens(Obviously the 30  seconds could be changed to something less or more aswell)
    if(now < ceationDate)
    {
    // Expiration time in seconds
    int expire = 2 * 60;
    context.Ticket.Properties.ExpiresUtc = new DateTimeOffset(DateTime.Now.AddSeconds(expire));
    context.SetToken(context.SerializeTicket());
    }
}

    public override void Receive(AuthenticationTokenReceiveContext context)
    {
    context.DeserializeTicket(context.Token);
    }
}