【问题标题】:OData V4 Client Code Generator and handling a 401 responseOData V4 客户端代码生成器和处理 401 响应
【发布时间】:2016-03-06 19:16:18
【问题描述】:

我有一个使用自定义身份验证机制的带有 OData V4 服务的 WebAPI 2.2。基本上,它类似于 OAuth 的 Bearer 身份验证,即使用用户名和密码向特定端点发出请求并返回令牌。然后,该令牌将包含在所有后续请求的 Authorization 标头中。 我正在使用 OData V4 客户端代码生成器 (2.3.0) 并使用 DataServiceContext 的 BuildingRequest 事件手动添加授权标头,如下所示...

private void GetData() {
    var context = new DataAccess.Default.Container(new Uri("http://myserver/API/"));

    context.BuildingRequest += onBuildingRequest;
    var data = context.Computers.ToList();
}
void onBuildingRequest(object sender, Microsoft.OData.Client.BuildingRequestEventArgs e)
{
    if (_token == null)
        _token = GetToken();
    e.Headers.Add("Authorization", "MyToken " + _token);
}

我遇到的问题是令牌在一定时间后过期,所以一段时间后我会开始收到 401 响应,这会导致在上下文中的 IQueryables 获取时引发异常他们的 GetEnumerator 被调用(上面代码中的 ToList 调用)。我可以包装我枚举端点的每一个地方,但这并不理想。 我发现我可以在 DataServiceContext 的 ReceivingResponse 事件中检测到 401 并标记令牌已过期,但这并不能阻止调用失败,它只会使后续调用正常工作。

void context_ReceivingResponse(object sender, ReceivingResponseEventArgs e)
{
    if (e.ResponseMessage.StatusCode == 401)
    {
        _token = null;
    }
}

因此,在这一点上,我试图找出一种方法来处理 401,而不需要将每个调用(通常在枚举 IQueryable 时)都包装在 try/catch 中。我试图找出一种方法让 Web 请求以类似于处理基本身份验证的方式处理我的自定义身份验证(如果服务器以 401 和 WWW-Authenticate 标头响应,并且已为基本身份验证指定凭据另一个请求将使用所需的身份验证标头自动发送)但没有运气。

任何帮助/建议将不胜感激。

【问题讨论】:

    标签: c# authentication odata odata-v4


    【解决方案1】:

    解决方案在AuthenticaionManager 类中。通过通过 Register 方法注册您自己的 IAuthenticationModule 实现,您将能够做您正在寻找的事情。

    您可能还需要另一个实现ICredentials 并处理您的身份验证参数(如令牌端点url 等)的类,然后将其传递给您的DataServiceContext。您甚至可以使用它来缓存您的最后一个令牌及其到期时间。

    到目前为止,我发现处理过期令牌的唯一方法是在从授权服务器获取令牌的同时存储过期时间并如果它即将过期则刷新它"close" 我的意思是它是否会在 n 秒内过期。我更喜欢这个阈值作为我检索令牌的网络超时。如果它已过期甚至即将过期,我将从服务器获得一个新令牌,甚至不尝试最后一个。在本节中随意使用您喜欢的任何测量值。 ;) 但是没有办法多次响应您的授权服务器的挑战,它不会永远挑战您。

    查看here 以获取有关上述类和接口的示例。

    顺便说一句,在Portable Class Library 中使用它你可能有点不走运。 pcl 中没有AuthenticaionManagerIAuthenticationModule 的迹象。使用某种抽象可能会有所帮助。

    【讨论】:

      【解决方案2】:

      也许您忘记在您的 GetData 中挂钩 context_ReceivingResponse? (我没看到) 否则在发送和接收事件中记录 http-headers 以确保。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-06
        相关资源
        最近更新 更多