0

Hopefully I'm not misunderstanding something fundamental about ASP.NET Authentication, but here's what I'm trying to accomplish (and failing doing such):

I have a Xamarin.Forms app that needs to be able to go after ASP.NET web services. When I run the App itself, it works fine. The ASP.NET side of it uses Cookie Authentication and the App is capable of getting the Cookie from the Cookie Container -- and then serializing/storing it into secure storage:

For example:

        var baseUri = new Uri(url);
        baseUri = new Uri($"{baseUri.Scheme}://{baseUri.Host}");

        var cookieContainer = new CookieContainer();

        /*
        authenticationCookie is stored locally and de/serialized via Json from SecureStorage:

            var cookie = SecureStorage.GetAsync(AuthenticationCookieKey).Result;

            if (!string.IsNullOrEmpty(cookie))
            {
                authenticationCookie = JsonConvert.DeserializeObject<Cookie>(cookie);
            }
         */

        cookieContainer.Add(authenticationCookie);

        using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
        {
            using (var request = new HttpRequestMessage(HttpMethod.Post, url) { Content = new FormUrlEncodedContent(content) })
            {
                using (var client = new HttpClient(handler))
                {
                    return client.SendAsync(request).Result;
                }
            }
        }

When I make a Login, I do the following on "success":

                SetAuthenticationCookie(cookieContainer.GetCookies(baseUri)[0]);

This sets the local "authenticationCookie" in the class and then serializes it out to SecureStorage.

I've proven/checked that the authenticationCookie is correctly de/serializing and loads up when the Xamarin.Forms app does. I've attached it to my web request. However, when I make the calls, I get a Login request from the opposite end on ASP.NET Core.

The ASP.NET Core server itself works fine normally. If I have a browser instance, it never asks me to login and the browser "remembers" and applies the cookie from login correctly. However, it should seem that the Xamarin.Forms app does not.

What am I missing?

For the sake of argument, this is how I am setting up cookies via the Login method:

        //user has a User loaded from EF at this point

        var userPrincipal = new ClaimsPrincipal(
                new ClaimsIdentity(
                    new List<Claim>()
                    {
                        new Claim(ClaimTypes.Name, user.EmailAddress)
                    }, "Login"));

        var properties = new AuthenticationProperties()
        {
            IsPersistent = true
        };

        await httpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, userPrincipal, properties);
Locke
  • 1,133
  • 11
  • 32
  • I haven't found an answer, but for anyone else who sees this problem -- I'm noticing that the cookie isn't making it thru onto the request header on the ASP.NET end. Something is happening. I will try manually adding it to the header (not via CookieCollection) and see if that changes anything -- or if there is a reason that it isn't working by default. – Locke Aug 08 '19 at 14:00

1 Answers1

0

So, I was successful in using the answer UNDER the selected answer:

How do I set a cookie on HttpClient's HttpRequestMessage

Apparently setting the CookieContainer and then populating it with a Cookie and including that in the Message DID NOT WORK.

The solution was to manually add the Cookie doing the following:

    private HttpResponseMessage GetDataResponse(string url)
    {
        using (var handler = new HttpClientHandler { UseCookies = false })
        {
            using (var request = new HttpRequestMessage(HttpMethod.Get, url))
            {
                request.Headers.Add("Cookie", $"{MyCookie.Name}={MyCookie.Value}");

                using (var client = new HttpClient(handler))
                {
                    return client.SendAsync(request).Result;
                }
            }
        }
    }

This works exactly as we would expect!

Locke
  • 1,133
  • 11
  • 32