C# ODataV4客户端代码生成器和处理401响应

C# ODataV4客户端代码生成器和处理401响应,c#,authentication,odata,odata-v4,C#,Authentication,Odata,Odata V4,我有一个WebAPI 2.2 w/OData V4服务,它使用自定义身份验证机制。基本上,它类似于OAuth的承载身份验证,即使用用户名和密码向特定端点发出请求,并返回令牌。然后,令牌将包含在所有后续请求的授权标头中。 我正在使用ODataV4客户机代码生成器(2.3.0),并使用DataServiceContext的BuildingRequest事件手动添加授权头,如下所示 private void GetData() { var context = new DataAccess.De

我有一个WebAPI 2.2 w/OData V4服务,它使用自定义身份验证机制。基本上,它类似于OAuth的承载身份验证,即使用用户名和密码向特定端点发出请求,并返回令牌。然后,令牌将包含在所有后续请求的授权标头中。 我正在使用ODataV4客户机代码生成器(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认证头进行响应,并且为基本认证指定了凭据,则会自动发送另一个请求,其中包含所需的认证头),但没有成功


如果您有任何帮助/建议,我们将不胜感激。

也许您忘记在GetData中挂接接收响应的上下文?(我看不到) 否则,请将http头记录在发送和接收事件中,以确保。

解决方案位于类中。通过其方法注册您自己的实现,您将能够完成所需的操作

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

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

请看一个关于所提到的类和接口的示例

顺便说一句,如果你把它用在电脑上,你可能会有点运气不好。pcl中没有和的迹象。使用某种抽象可能会有所帮助