4

Scenario:

I have a solution, in which, i have both WebAPI and Asp.Net Core MVC Project. I have implemented Cookies based authentication in WebAPI. It's working great while testing using Postman. But when i consume the WebAPI Service from my MVC project, authentication seems to be broken.

Here's my code:

WebAPI:

Startup.cs

app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
    AuthenticationScheme = "ApiAuth",
    AutomaticAuthenticate = true,
    AutomaticChallenge = false
});

AccountController.cs

[HttpPost]
[Route("authenticate")]
public IActionResult Authenticate([FromBody]LoginModel login)
{
    if (_accountManager.Authenticate(login))
    {
        var identity = new ClaimsIdentity("password");
        identity.AddClaim(new Claim(ClaimTypes.Role, "User"));
        HttpContext.Authentication.SignInAsync("ApiAuth", new ClaimsPrincipal(identity)).Wait();
    }
    else
    {
        return Unauthorized();
    }
    return Ok(_accountManager.Authenticate(login));
}

All Controllers have this attribute [Authorize(Roles = "User")]

MVC App:

AccountController.cs

public async Task<IActionResult> Login(LoginModel loginModel)
{
    var loginFlag = false;
    HttpResponseMessage response = await ServiceCall<LoginModel>.postData(URLPREFIX + "/authenticate", loginModel);
    if (response.IsSuccessStatusCode)
    {
        loginFlag = await response.Content.ReadAsAsync<bool>();
    }
    if (loginFlag)
    {
        return RedirectToAction("Index", "Home");
    }
    else
    {
        return View();
    }
}

ServiceCall.cs:

public static class ServiceCall<T>
    {
        static HttpClient client = new HttpClient();
        const string HTTP_BASE = "http://localhost:13359/";

        public static async Task<HttpResponseMessage> postData(string Url, T data)
        {
            HttpResponseMessage response = null;
            StringContent content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json");
            client.BaseAddress = new Uri(HTTP_BASE);
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            response = await client.PostAsync(Url, content);
            return response;
        }
    }

Here is my Screenshot:

enter image description here

The login function in both WebAPI and MVC is executing correctly, but when navigating to home page, i could not consume the service. Any Advice would be helpful. Thanks.

Update #1:

Here is my project repo with the issue. Please take a look. Thanks

Ranjith Varatharajan
  • 1,596
  • 1
  • 33
  • 76

1 Answers1

1

i think problem is here:

 HttpResponseMessage response = await ServiceCall<LoginModel>.postData(URLPREFIX + "/authenticate", loginModel);
    if (response.IsSuccessStatusCode)
    {
        loginFlag = await response.Content.ReadAsAsync<bool>();
    }

you are using a new request authenticate, this authenticate write a cookie in the response, of course not working on your real browser request.
you need using browser request the authenticate directly, let cookie write back to client, then your client can request home index.

Bucketcode
  • 461
  • 2
  • 13
  • 1
    Thanks for the reply. Can you give me an example code? – Ranjith Varatharajan Dec 27 '16 at 07:28
  • i don't konw your client code, and if your webapi and mvc app in different server(if true you can't use api authenticate in app), many example you can google it yourself, you need understand it, not someone write for you. – Bucketcode Dec 27 '16 at 07:42
  • Thank you my friend. I have updated my question with my ServiceCall program. The only new request i'm using is `static HttpClient client = new HttpClient();`. Is there any way to use the same HttpClient without creating a new one? – Ranjith Varatharajan Dec 27 '16 at 07:58
  • Please take a look at my sample project https://github.com/darthranjith/Cookies-Based-Authentication – Ranjith Varatharajan Dec 27 '16 at 12:55
  • I can't open it because i don't install .net core. i check the code, problem is your request api with servicecall, it'll use new httpclient every time, so you authenticate cookie never store, how could that work. you need use single instance of httpclient, or store cookie somewhere post it with your new request. check this out http://stackoverflow.com/questions/12373738/how-do-i-set-a-cookie-on-httpclients-httprequestmessage – Bucketcode Dec 28 '16 at 02:53