简体   繁体   中英

Why is my web request failing authorization, but the same request works in python and postman?

I have been having some issues with my internet recently. Looks to be at the modem, or before the modem (on my ISP's side). I want to record the logs and connection metrics. I quickly tested logging in using python and postman. Now I want to swap to c# since that is what I am comfortable with, but things aren't working.

In python and postman I have to send two requests for it to work. The first passes auth, and the second works. In python I had to swap to Session instead of Request because two consecutive requests would fail. So I'm thinking it has something to do with a cookie or something? However, postman shows no cookies being stored. I do not usually make web requests when working with c# so this may be a simple (dumb) issue. How can I emulate this session behavior in c#?

I call Get() twice, to mirror python and postman taking two requests to work, but both requests fail here. Below is my c# code and below that is the python code. Obviously these are dummy credentials.

public static class ModemMonitor
{
    public static string Get()
    {
        string result = "";

        Uri BaseUri = new Uri("http://192.168.100.1/");
        // I have tried all of the below auth strings and methods.
        // All give a 401 not authorized.
        string username = "admin";
        string password = "password";
        string auth = System.Convert.ToBase64String(Encoding.Default.GetBytes(username + ":" + password));
        string encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));

        try
        {
            var request = HttpWebRequest.CreateHttp(BaseUri);
            request.Headers.Add("authorization", auth);
            request.PreAuthenticate = true;
            request.Method = WebRequestMethods.Http.Get;
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            using(StreamReader reader = new StreamReader(response.GetResponseStream()))
            {
                result += reader.ReadToEnd();
            }
        }
        catch (WebException webEx) { result += webEx.Message; }
        catch (Exception ex) { result += ex.Message; }

        return result;
    }
}

Working python code.

import requests
from requests import Session

session = requests.Session()
session.auth = ('admin', 'password')
baseUrl = 'http://192.168.100.1/'

auth = session.get(baseUrl)
response = session.get(baseUrl + 'eventLog.htm')
print(response.text)

You said it yourself that postman need two calls. The first one to create the token and the second to make your request.

  1. Create the token
       public async Task<AuthenticateUser> Authenticate(string username, string password)
        {
            var data = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string,string>("grant_type","password"),
                new KeyValuePair<string,string>("username",username),
                new KeyValuePair<string,string>("password",password),
            });


            using (HttpResponseMessage response = await _ApiClient.PostAsync("/Token", data))
            {
                if (response.IsSuccessStatusCode)
                {
                    var result = await response.Content.ReadAsAsync<AuthenticateUser>();
                    return result;
                }
                else
                {
                    throw new Exception(response.ReasonPhrase);
                }
            }
        }

  1. Use the token to call the api
   public async Task GetLoggedInUserInfo(string token)
        {
            _ApiClient.DefaultRequestHeaders.Clear();
            _ApiClient.DefaultRequestHeaders.Accept.Clear();
            _ApiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            _ApiClient.DefaultRequestHeaders.Add("Authorization", $"Bearer { token}");

            using (HttpResponseMessage response = await _ApiClient.GetAsync("/api/user"))
            {
                if (response.IsSuccessStatusCode)
                {
                    var result = await response.Content.ReadAsAsync<LoggedInUserModel>();

                    
                   
                }
                else
                {
                    throw new Exception(response.ReasonPhrase);
                }
            }
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM