I am writing tests for an API client in C# (i.e. the client is not a web browser). The API server (which I am also in control of) can accept the access token in either the HTTP body or via a cookie. I want to be able to test submitting the access token via either the body or a cookie for any given endpoint. I could do all the cookie tests first, then reauthenticate and do all the access-token-in-body tests (I have gotten this working with slightly different code to what is below) but I prefer not to have to run the tests in a specific order. So my plan is:
- make a request to the authentication endpoint and tell it that the access token is to be returned in the message body only (no cookie response)
- create a cookie on the client side using the access token
- for the cookie tests, make requests to endpoints using the cookie created in 2
- for the access-token-in-body tests, make requests to endpoint without sending a cookie
However when I do step 3 and inspect the Request.Cookies object at the server side, no cookie is being received (.Count == 0).
Is my code wrong, or is what I am trying to do here not allowed by the spec?
E.g. maybe the spec only allows cookies to be received if they were created by the server?
The endpoint for step 3 above is a standard System.Web.MVC.Controller method and I use an attribute to validate the access token like so (simplified to only show relevant code):
namespace myServerProject.Controllers
{
public class myController : Controller
{
[AcceptVerbs(HttpVerbs.Options | HttpVerbs.Post)]
[Route("myEndpoint")]
[myTokenFilter]
public ActionResult MyEndpoint()
{
// do stuff and return result
}
}
}
namespace myServerProject.Filters
{
public class myTokenFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
string accessToken = HttpContext.Current.Request.Cookies["accessToken"].Value;
// do stuff and add accessToken to filterContext
}
}
}
But HttpContext.Current.Request.Cookies is coming up empty at the server end.
Client side code:
public CookieContainer Post(
string url,
CookieContainer cookies // System.Net
)
{
// new connection each time
CookieContainer cookieContainer = new CookieContainer();
HttpClientHandler handler = new HttpClientHandler() // System.Net.Http
{
CookieContainer = cookieContainer
};
HttpClient httpClient = new HttpClient(handler); // System.Net.Http
cookieContainer = cookies;
response = httpClient.PostAsync(url, null).Result;
string resultString = response.Content.ReadAsStringAsync().Result;
return GetAllCookiesFromHeader(response.Headers, "myHostname");
}
Note: GetAllCookiesFromHeader() is defined here and gets the cookies out of the response, ready to be passed back in as a Post() parameter on the next call.