2017-02-09 1 views
1

У меня возникла странная проблема в DocumentDb. Я создал пользователя и разрешил манипулировать определенной коллекцией. Затем я запросил токен ресурса с ограниченным сроком действия для этого пользователя. Я сделал это, установив ResourceTokenExpirySeconds, чтобы сказать 10 секунд. Чтобы проверить это, я подождал достаточно, чтобы истекший токен. Однако Azure принимала последующие запросы с использованием этого (предположительно истекшего) токена.Azure DocumentDB: токен ресурса по времени остается действительным по истечении срока действия

Учитывая следующий код, он ожидает, что эта линия не может, но это не делает:

UserPermissionExample.TestToken(10, 15); 

А вот UserPermissionExample реализация:

public class UserPermissionExample 
{ 
    const string endPoint = "https://[ENDPOINT].documents.azure.com"; 
    const string masterKey = "[PRIMARY-KEY]"; 
    const string dbName = "test-db"; 
    const string testUserId = "test-user"; 
    const string collName = "test-coll"; 

    public static async Task TestToken(int validity, int wait) 
    { 
     // Get a time-bound token 
     string token = await GetToken(validity /*seconds*/); 

     // Wait enough so the token gets expired 
     Thread.Sleep(TimeSpan.FromSeconds(wait)); 

     // Try to add a document with the expired token. It is expected to fail: 
     DocumentClient client = new DocumentClient(new Uri(endPoint), token); 
     await client.CreateDocumentAsync(
      UriFactory.CreateDocumentCollectionUri(dbName, collName), 
      new { name = "A test document" }); 
    } 

    static async Task<string> GetToken(int tokenValiditySeconds) 
    { 
     DocumentClient client = new DocumentClient(new Uri(endPoint), masterKey); 
     ResourceResponse<Database> db = await UpsertDb(client); 
     ResourceResponse<DocumentCollection> collection = await UpsertCollection(client, db); 

     var userUrl = UriFactory.CreateUserUri(dbName, "testuser"); 
     var user = await client.UpsertUserAsync(db.Resource.SelfLink, new User() { Id = testUserId }); 

     var permission = 
      await client.UpsertPermissionAsync(
       user.Resource.SelfLink, 
       new Permission() 
       { 
        Id = "PersmissionForTestUser", 
        PermissionMode = PermissionMode.All, 
        ResourceLink = collection.Resource.SelfLink, 
       }, 
       new RequestOptions() { ResourceTokenExpirySeconds = tokenValiditySeconds }); 

     permission = 
      await client.ReadPermissionAsync(
       permission.Resource.SelfLink, 
       new RequestOptions() { ResourceTokenExpirySeconds = tokenValiditySeconds }); 

     return permission.Resource.Token; 
    } 

    static async Task<ResourceResponse<DocumentCollection>> UpsertCollection(DocumentClient client, ResourceResponse<Database> db) 
    { 
     ResourceResponse<DocumentCollection> collection = null; 
     try 
     { 
      collection = await client.ReadDocumentCollectionAsync(UriFactory.CreateDocumentCollectionUri(dbName, collName)); 
     } 
     catch (DocumentClientException ex) 
     { 
      if (ex.StatusCode == System.Net.HttpStatusCode.NotFound) 
      { 
       collection = await client.CreateDocumentCollectionAsync(db.Resource.SelfLink, new DocumentCollection() { Id = collName }); 
      } 
     } 

     return collection; 
    } 

    static async Task<ResourceResponse<Database>> UpsertDb(DocumentClient client) 
    { 
     ResourceResponse<Database> db = null; 
     try 
     { 
      db = await client.ReadDatabaseAsync(UriFactory.CreateDatabaseUri(dbName)); 
     } 
     catch (DocumentClientException ex) 
     { 
      if (ex.StatusCode == System.Net.HttpStatusCode.NotFound) 
      { 
       db = await client.CreateDatabaseAsync(new Database() { Id = dbName }); 
      } 
     } 

     return db; 
    } 
} 

PS: Я использую Microsoft .Azure.DocumentDB version = "1.11.4".

Обновление: Я обнаружил, что Azure начинает проверку истечения срока действия токена через 5 минут после выпуска маркера! Затем он отклоняет токен. Таким образом, до этого периода, независимо от того, токен истек или нет, Azure принимает его!

+0

Поскольку вы выяснили проблему, разместите ее как правильный ответ, а не редактируйте свой вопрос. Таким образом, этот вопрос может быть правильно закрыт. –

+0

@DavidMakogon Это не ответ. Тем не менее у меня есть возражение относительно льготного периода. – Alireza

ответ

3

Причина этого заключается в том, что DocumentDB имеет некоторое ослабление в истечении срока действия токена, позволяя потенциальным перекосам синхронизации на клиенте или сервере. Из-за этого токены имеют «льготный период» после их реального времени истечения. Разрешенный перекос часов составляет 5 минут, поэтому вы видите поведение, которое вы делаете.

Есть ли конкретная причина, по которой вы создаете токен, который должен быть действителен только в течение 10 секунд?

Полное раскрытие информации: Я работаю в DocumentDB.

+0

Спасибо за ответ. Во-первых, подтверждается ли это поведение? Во-вторых, причина этого требования заключается в том, что я хочу делегировать обновление конкретного документа или коллекции другому приложению. – Alireza

+1

Это не только DocumentDB. Временной перекос настолько распространен, что, например, IoT Hubs имеют идентичный 5-минутный льготный период. – juunas

+0

@juunas я вижу. Кажется, что это перекос происходит из библиотеки JWT, используемой Azure. Знаете ли вы какую-либо документацию, в которой это конкретно указано? – Alireza