我有一个使用自定义身份验证机制的带有 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 标头响应,并且已为基本身份验证指定凭据另一个请求将使用所需的身份验证标头自动发送)但没有运气。
任何帮助/建议将不胜感激。