I have a WebAPI 2.2 w/ OData V4 service that uses a custom authentication mechanism. Basically it's similar to OAuth's Bearer authentication such that a request is made to a specific endpoint with the username and password and a token is returned. The token is then included in the Authorization header of all subsequent requests. I'm using the OData V4 Client Code Generator (2.3.0) and adding the Authorization header manually using the DataServiceContext's BuildingRequest event like thus...
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);
}
The problem I'm having is the token expires after a certain amount of time, so after a while I'll start getting a 401 response, which causes an exception to be thrown at the point that the IQueryables from the context gets their GetEnumerator called (the ToList call in the above code). I could wrap every single place that I enumerate an endpoint but that is less than ideal. I've found that I can detect a 401 in the DataServiceContext's ReceivingResponse event and mark that the token has expired, however that doesn't prevent the call from failing it will just make subsequent calls work.
void context_ReceivingResponse(object sender, ReceivingResponseEventArgs e)
{
if (e.ResponseMessage.StatusCode == 401)
{
_token = null;
}
}
So at this point I'm trying to figure out a way to handle a 401 without requiring every call (which will often be when enumerating an IQueryable) to be wrapped in a try/catch. I tried to figure out a way to have the web requests handle my custom authentication in a manner similar to how it handles Basic authentication (if the server responds with a 401 and a WWW-Authenticate header, and a credential has been specified for Basic authentication another request will be sent automatically with the needed Authentication header) but have had no luck.
Any help/suggestions would be appreciated.