4

I do have authorize attribute applied on my Web API. I am calling Web API from MVC4 application in which I am using standard cookie based authentication. I need to call Web API method on controllers from integration tests but because authorize attribute is applied I will always receive unauthorized exception.

What is the best way to solve this problem ? PS. I don't want (need) to use other methods of authentication such as APIKey,Token in Auth Header and similar...

tugberk
  • 57,477
  • 67
  • 243
  • 335
Radenko Zec
  • 7,659
  • 6
  • 35
  • 39

1 Answers1

0

First of all, one key element in order to answer this question is to know what kind of authentication mechanism you use. For example, if you use basic auth, you can send the credentials when you are integration testing:

[Fact]
public async Task FooTest() { 

    var username = "user";
    var password = "supersecret";

    // construct your config here as I do below.
    // RouteConfig and WebAPIConfig are my own classes
    var config = new HttpConfiguration();
    RouteConfig.RegisterRoutes(config);
    WebAPIConfig.Configure(config);

    var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/api/cars");
    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

    request.Headers.Authorization = new AuthenticationHeaderValue(
        "Basic", EncodeToBase64(string.Format("{0}:{1}", username, password)));

    using (var httpServer = new HttpServer(config))
    using (var client = new HttpClient(httpServer)) {

        var response = await client.SendAsync(request);
        var result = await response.Content.ReadAsAsync<Car>();

        // do you test now...
    }
}

private static string EncodeToBase64(string value) {

    byte[] toEncodeAsBytes = Encoding.UTF8.GetBytes(value);
    return Convert.ToBase64String(toEncodeAsBytes);
}

Of course, your handler which handles the authentication should be able to authenticate you with those credentials.

On the other hand, as you will be hosting the application in memory, setting an authenticated principal to the Thread.CurrentPrincipal would be another option but wouldn't be my favorite option here.

tugberk
  • 57,477
  • 67
  • 243
  • 335
  • Thanks for answer but I have already pointed out that I am using ASP.NET MVC 4 login functionality which means that I am logged in trough ASP.NET MVC 4 website and when I do request to WebAPI , Authorize attribute will grant me access because I am sending authorization cookie in that request. – Radenko Zec Nov 29 '12 at 20:16
  • All authentication for now is inside ASP.NET MVC 4 because it is in same project a WebAPI. I don't need custom basic authentication inside WebAPI for now. – Radenko Zec Nov 29 '12 at 20:23
  • 1
    @RadenkoZec I am assuming you are doing forms auth. So, remove the authorization header above on my example and put the forms auth cookie to the request. The idea is the same. My example just gives you a hint. – tugberk Nov 29 '12 at 22:24
  • I think idea to put auth cookie to the request must solve this issue. I will mark your answer as correct and open another question regarding how to do that : http://stackoverflow.com/questions/13642466/how-to-add-formsauthentication-cookie-to-httpclient-httprequestmessage – Radenko Zec Nov 30 '12 at 09:39
  • 1
    @tugberk This method throws exception while initializing WebApi config, when using WebApi 2. It says ` This method cannot be called during the application's pre-start initialization phase`. Do you by any chance have a similar solution for WebApi 2 tests? – Iravanchi Mar 02 '15 at 08:02