'c# riot RSO multifactor authentication

I'm following the authentication flow here, which works perfectly, but it doesn't include doing multifactor authentication, which riot added recently

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Web;

namespace APITestConsole
{
    // Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);
    public class Body2
    {
        public string type { get; set; }
        public Response response { get; set; }
        public string country { get; set; }
    }
public class Parameters2
{
    public string uri { get; set; }
}

public class Response2
{
    public string mode { get; set; }
    public Parameters parameters { get; set; }
}

public class RiotAuth2
{
    public HttpClientHandler handler = new HttpClientHandler { UseCookies = false };
    public HttpClient client;
    public String? access_token;
    public String? expires_in;
    public String? id_token;
    public string? entitlements_token;
    public string[]? cookies;
    public RiotAuth2()
    {
        client = new HttpClient(handler);
        //user agent is required to avoid triggering cloudflare
        //client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident / 6.0)");
        client.DefaultRequestHeaders.Add("User-Agent", "RiotClient/43.0.1.41953 86.4190634 rso-auth (Windows; 10;;Professional, x64)");
    }


    public void AuthCookies()
    {
        //get the auth cookie
        var request = new HttpRequestMessage
        {
            Method = HttpMethod.Post,
            RequestUri = new Uri("https://auth.riotgames.com/api/v1/authorization"),
            Content = new StringContent("{\"client_id\":\"play-valorant-web-prod\",\"nonce\":\"1\",\"redirect_uri\":\"https://playvalorant.com/opt_in\",\"response_type\":\"token id_token\"}")
            {
                Headers = { ContentType = new MediaTypeHeaderValue("application/json") }
            }
        };
        using (var response = client.SendAsync(request).Result)
        {
            response.EnsureSuccessStatusCode();
            cookies = response.Headers.GetValues("Set-Cookie").ToArray();
        }
    }

    public void AuthRequest(string UserName, string Pass)
    {
        var request = new HttpRequestMessage
        {
            Method = HttpMethod.Put,
            RequestUri = new Uri("https://auth.riotgames.com/api/v1/authorization"),
            Content = new StringContent($$"""{    "type": "auth",    "username": "{{UserName}}",    "password": "{{Pass}}",    "remember": true,    "language": "en_US"}""")
            {
                Headers = { ContentType = new MediaTypeHeaderValue("application/json") }
            }
        };

        //set cookies
        request.Headers.Add("Cookie", String.Join("; ", cookies.Where(s => s.StartsWith("tdid") || s.StartsWith("asid"))));//we only need asid

        using (var response = client.SendAsync(request).Result)
        {
            response.EnsureSuccessStatusCode();
            var result = response.Content.ReadAsStringAsync().Result;


            var body = JsonSerializer.Deserialize<Body2>(result);

            if (body.type == "multifactor")
            {
                AuthRequestMFATest(UserName, Pass);
                goto TGF;
            }

            var Fragment = new Uri(body.response.parameters.uri).Query.Substring(1);
            access_token = HttpUtility.ParseQueryString(Fragment).Get("access_token");
            expires_in = HttpUtility.ParseQueryString(Fragment).Get("expires_in");
            id_token = HttpUtility.ParseQueryString(Fragment).Get("id_token");


        }

    TGF:
        Console.WriteLine("\n\nJust Debug\n\n");
    }

    public void AuthRequestMFATest(string UserName, string Pass)
    {
        Console.WriteLine("Code:");
        var code = Console.ReadLine();
        var request = new HttpRequestMessage
        {
            Method = HttpMethod.Put,
            RequestUri = new Uri("https://auth.riotgames.com/api/v1/authorization"),
            Content = new StringContent("{\"type\": \"multifactor\",\"code\": \"" + code + "\",\"rememberDevice\": true}")
            {
                Headers = { ContentType = new MediaTypeHeaderValue("application/json") }
            }
        };


        request.Headers.Add("Cookie", String.Join("; ", cookies/*.Where(s => s.StartsWith("tdid") || s.StartsWith("asid"))*/));//we only need asid



        using (var response = client.SendAsync(request).Result)
        {
            response.EnsureSuccessStatusCode();
            var result = response.Content.ReadAsStringAsync().Result;
            Console.WriteLine("\n\n\n{body :: " + result + "}\n\n\n");


            var body = JsonSerializer.Deserialize<Body2>(result);

            var Fragment = new Uri(body.response.parameters.uri).Query.Substring(1);
            access_token = HttpUtility.ParseQueryString(Fragment).Get("access_token");
            expires_in = HttpUtility.ParseQueryString(Fragment).Get("expires_in");
            id_token = HttpUtility.ParseQueryString(Fragment).Get("id_token");

        }
    }

   
}
}

but I keep getting error 400 bad request on the MFA part despite checking other codes like this or just investigating the requests made by the riot-id login website in the browser for an account with MFA enabled, using the developer tools, and this is the exact payload, and exact request url, what am I missing?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source