1

I need to call an endpoint to perform and retrieve 3 cookies to call another application's endpoint, and I'm using flurl 3.0 to perform the call. The login is successful, but the cookie session is always empty. If I perform the call with Postman, I see the cookies and call the other endpoint. This is the code I'm using:

        var loginData = new
        {
            lt = GetLoginTicket(),
            username = _enConfig.Username,
            password = _enConfig.Password
        };


        using var session = new CookieSession(loginUrl);
        {
            var login = await session.Request(loginUrl).AllowAnyHttpStatus().PostUrlEncodedAsync(loginData);
            _jar = login.ResponseMessage.IsSuccessStatusCode ? session.Cookies : null;
        }

The documentation of the application says this:

The response code can be:

302, a redirection The authentication is successful. An SSO cookie (also named ######) is sent in the response header.

I get the 302 Status Code and in the body, I get the correct HTML page, but the cookies are always empty.

Am I missing something?

EDIT: I've modified the code as follows to have the Cookies. I almost solved my problem. Still, 1 cookie is missing after the post with the Url encoded body. The code is now:

  using var session = new CookieSession(_enConfig.PassportBaseEndpoint);
            {

                _logger.LogInformation("Getting login ticket");

                var ltData = new LoginTicket();
                var ltResponse = await session.Request("/login?action=get_auth_params").GetAsync();
                if (ltResponse.ResponseMessage.IsSuccessStatusCode)
                {

                    var ltString = await ltResponse.ResponseMessage.Content.ReadAsStringAsync();
                    ltData = JsonConvert.DeserializeObject<LoginTicket>(ltString);
                    
                    if (ltData == null || string.IsNullOrEmpty(ltData.Lt))
                        throw new Exception("Could not deserialize login token");  
                }
                else
                    throw new Exception("Could not get Login Ticket from enovia");

                var loginData = new
                {
                    lt = ltData.Lt,
                    username = _enConfig.Username,
                    password = _enConfig.Password
                };

                var login = await session.Request("/login/").AllowAnyHttpStatus().PostUrlEncodedAsync(loginData);
         
                _jar = login.ResponseMessage.IsSuccessStatusCode ? session.Cookies : null;
 
            }

After the first GET call to retrieve the login Ticket, I also get 2 cookies with a SessionID. When I perform the POST, I must also pass these cookies to have a successful login. In the response, I should get 1 more cookie with a token. The problem now is that the login is successful, but I don't get the third cookie in the session or the login response.

EDIT 2: Without Flurl I'm able to get the cookies with this code

        CookieContainer cookies = new CookieContainer();
        HttpClientHandler handler = new HttpClientHandler();
        handler.CookieContainer = cookies;
        handler.ServerCertificateCustomValidationCallback = (a, b, c, d) => true;
        var client = new HttpClient(handler);
        var response = client.GetAsync($"{_enConfig.PassportBaseEndpoint}/login?action=get_auth_params").Result;
        var loginTicket = JsonConvert.DeserializeObject<LoginTicket>(await response.Content.ReadAsStringAsync());
        var loginBody = new Dictionary<string, string>();
        loginBody.Add("lt", loginTicket.Lt);
        loginBody.Add("username", _enConfig.Username);
        loginBody.Add("password", _enConfig.Password);

        var encodedContent = new FormUrlEncodedContent(loginBody);
        response = await client.PostAsync($"{_enConfig.PassportBaseEndpoint}/login", encodedContent);

        _logger.LogInformation(await response.Content.ReadAsStringAsync());
        Uri uri = new Uri($"{_enConfig.PassportBaseEndpoint}/login");
        IEnumerable<Cookie> responseCookies = cookies.GetCookies(uri).Cast<Cookie>();
        foreach (Cookie cookie in responseCookies)
            Console.WriteLine(cookie.Name + ": " + cookie.Value);
Sethlans
  • 407
  • 1
  • 5
  • 20
  • Regarding "call another application's endpoint", are you saying it's doing a 302 redirect to a different domain? – Todd Menier Jan 08 '21 at 14:42
  • @ToddMenier the default redirect is by default to the profile of the user on the same application. Then the cookies should be used to perform operations on another application with a different domain – Sethlans Jan 08 '21 at 14:52
  • For debugging purposes, try adding adding this to your login call: `.WithAutoRedirect(false)`, then inspect the cookie jar to see if it looks right before the redirect. – Todd Menier Jan 08 '21 at 15:05
  • @ToddMenier added but nothing changed. I'm able to get the cookie with HttpClient and HttpClientHandler but not with Flurl. I don't know if is important or not but I have a Self Signed certificate so I had to add the ServerCertificateCustomValidationCallback – Sethlans Jan 08 '21 at 15:46
  • Are you using a [custom factory](https://flurl.dev/docs/configuration/#httpclientfactory) to create HttpClient/Handler instances for Flurl? – Todd Menier Jan 08 '21 at 16:43
  • @ToddMenier nope, the only custum stuff is the validator for the certificate – Sethlans Jan 11 '21 at 09:41
  • Keeping `WithAutoRedirect(false)` in place, check `login.Cookies` and `login.Headers` after the call and see if your cookies are in either or both. – Todd Menier Jan 11 '21 at 17:48
  • @ToddMenier with the code modified (see above) I'm able to get 2 out of 3 cookies. It's like the session cookies are not updated after the POST call for the login and so the third cookie with the login token is not added to the session – Sethlans Jan 13 '21 at 14:07
  • Now you're making 2 HTTP calls. What's in session.Cookies after the first call and before the second? – Todd Menier Jan 14 '21 at 13:44
  • @ToddMenier after the first called I have 2 cookies called afs and JSESSIONID. They are required to perform the second call for the real login (the first only gives to me a token) After the second call I still have only the 2 cookies but I need a third. Without flurl I'm able to get all the 3 cookies that I need – Sethlans Jan 14 '21 at 13:54
  • Please check `login.Cookies` and `login.Headers` at the end as suggested earlier. These should better tell you exactly what cookies the server sent in that specific response. If you still don't see the third cookie, try re-enabling the redirect - perhaps it's sent in the redirect response (though I doubt it). These are just troubleshooting steps - I don't know why they're not in Flurl's CookieJar but the raw response headers might offer some hints. – Todd Menier Jan 14 '21 at 16:22
  • @ToddMenier login.Cookies is empty and login.Headers contains some stuff like the Content-Type of the body returned but it doesn't contains any cookie – Sethlans Jan 15 '21 at 09:30

0 Answers0