【问题标题】:Azure DocumentDB: Time-bound resource token remains valid after expiration timeAzure DocumentDB:有时限的资源令牌在过期时间后仍然有效
【发布时间】:2017-02-09 10:39:11
【问题描述】:

我在DocumentDb 中遇到了一个奇怪的问题。 我创建了一个用户和权限来操作特定的集合。然后我为该用户请求了一个具有有限有效性的资源令牌。我通过将ResourceTokenExpirySeconds 设置为 10 秒来做到这一点。为了测试它,我等待了足够长的时间以使令牌过期。但是,Azure 使用该(假定已过期)令牌接受了后续请求。

考虑到以下代码,预计此行会失败,但事实并非如此:

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 分钟开始检查令牌过期时间!然后它拒绝令牌。所以在此之前,无论token是否过期,Azure都会接受!

【问题讨论】:

  • 既然您发现了这个问题,请将其作为正确答案发布,而不是对您的问题进行编辑。这样,这个问题就可以正确地结束了。
  • @DavidMakogon 这不是答案。我仍然反对宽限期。

标签: azure azure-cosmosdb


【解决方案1】:

这样做的原因是 DocumentDB 在令牌过期方面有一些松弛,以允许客户端或服务器中潜在的时钟偏差。因此,代币在其实际到期时间之后有一个“宽限期”。允许的时钟偏差大约为 5 分钟,这就是您看到自己所做行为的原因。

您创建一个仅应在 10 秒内有效的令牌是否有特殊原因?

完全披露:我在 DocumentDB 工作。

【讨论】:

  • 感谢您的回答。首先,是否记录了这种行为?其次,这个要求的原因是我想将特定文档或集合的更新委托给另一个应用程序。
  • 不仅是 DocumentDB。时钟偏差非常普遍,例如 IoT 中心有相同的 5 分钟宽限期。
  • @juunas 我明白了。似乎这种偏差来自 Azure 使用的 JWT 库。你知道有什么文件专门说明这一点吗?
  • 如果我的移动设备时间错误(时差比实际时间多/少 5 分钟),cosmosDb 客户端将无法正常工作。还是可以解决吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-20
  • 1970-01-01
  • 2012-05-16
  • 2021-10-27
  • 2017-10-18
  • 2023-03-23
相关资源
最近更新 更多