49

I am new to rest api's and calling them via .NET

I have an api: https://sub.domain.com/api/operations?param=value&param2=value

The notes for the api say that to authorize I need to use the basic access authentication - how do I do that?

I currently have this code:

        WebRequest req = WebRequest.Create(@"https://sub.domain.com/api/operations?param=value&param2=value");
        req.Method = "GET";
        //req.Credentials = new NetworkCredential("username", "password");
        HttpWebResponse resp = req.GetResponse() as HttpWebResponse;

However I get a 401 unauthorized error.

What am I missing, how do I form api calls using the basic access auth?

andrewb
  • 2,995
  • 7
  • 54
  • 95
  • Authentication type depends on the API. What is the API you are trying to call? 401 unauthorized means you were clearly passing invalid credentials and doesn't provide enough context for diagnosis. Is the API using OAuth? – Karan Ashar Aug 21 '13 at 00:39

3 Answers3

70

If the API says to use HTTP Basic authentication, then you need to add an Authorization header to your request. I'd alter your code to look like this:

    WebRequest req = WebRequest.Create(@"https://sub.domain.com/api/operations?param=value&param2=value");
    req.Method = "GET";
    req.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes("username:password"));
    //req.Credentials = new NetworkCredential("username", "password");
    HttpWebResponse resp = req.GetResponse() as HttpWebResponse;

Replacing "username" and "password" with the correct values, of course.

Adrian
  • 2,825
  • 1
  • 22
  • 32
  • @SHEKHARSHETE You might want to have a look at [HttpWebResponse.GetResponseStream()](http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.getresponsestream.aspx). Take special note of the Remarks note on closing the Stream once you're done with it. This is quite important. – Adrian Jun 17 '14 at 05:50
  • make sure that you uncomment req.Credentials.. line with your user name and password there. otherwise it keep remain unauthorized. – Gurusinghe Aug 24 '17 at 10:31
  • @Gurusinghe is hasn't done that any time I've used it before. This snippet crafts the Authorisation header which gets passed on to the owner server – Adrian Aug 24 '17 at 10:55
  • `WebRequest` is obsolete. Suggest changing this code to utilize `HttpClient` or `HttpWebRequest` instead. – Robert Harvey Mar 24 '22 at 13:03
  • @RobertHarvey I mean, this was written eight years ago. I'm not exactly going to keep coming back to it to correct the accepted answer depending on what the current paradigm happens to be or when things get obsoleted or leave lifetime support – Adrian Mar 26 '22 at 04:45
6

You can also use the RestSharp library for example

var userName = "myuser";
var password = "mypassword";
var host = "170.170.170.170:333";
var client = new RestClient("https://" + host + "/method1");            
client.Authenticator = new HttpBasicAuthenticator(userName, password);            
var request = new RestRequest(Method.POST); 
request.AddHeader("Accept", "application/json");
request.AddHeader("Cache-Control", "no-cache");
request.AddHeader("Content-Type", "application/json");            
request.AddParameter("application/json","{}",ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
orellabac
  • 2,077
  • 2
  • 26
  • 34
  • Well, in this case, how do i get to pass the current user default credentials without having to provide the username/pwd. to be as basic authentication of the current executing user's credentials? I cant use requst.UseDefaultCredentials = true. do you have any suggestions or solutions to this? – Ak777 Apr 26 '20 at 06:26
  • I think that the scenario you are asking is not for BasicAuthentication. You can try using NTLM for example Use some code like: RestClient client = new RestClient(_baseURL); client.Authenticator = new NtlmAuthenticator(); – orellabac Apr 27 '20 at 11:46
  • THanks for the response. You are right, in my case, it expects basic auth, and the NTLM didnt favor too. so, that makes me question, while i am trying to implement basic auth to my api as well, is there any slightest way possible to create basic auth using ClaimsPrincipal/HttpContext? – Ak777 Apr 27 '20 at 13:45
2

Here is the solution for Rest API

class Program
{
    static void Main(string[] args)
    {
        BaseClient clientbase = new BaseClient("https://website.com/api/v2/", "username", "password");
        BaseResponse response = new BaseResponse();
        BaseResponse response = clientbase.GetCallV2Async("Candidate").Result;
    }


    public async Task<BaseResponse> GetCallAsync(string endpoint)
    {
        try
        {
            HttpResponseMessage response = await client.GetAsync(endpoint + "/").ConfigureAwait(false);
            if (response.IsSuccessStatusCode)
            {
                baseresponse.ResponseMessage = await response.Content.ReadAsStringAsync();
                baseresponse.StatusCode = (int)response.StatusCode;
            }
            else
            {
                baseresponse.ResponseMessage = await response.Content.ReadAsStringAsync();
                baseresponse.StatusCode = (int)response.StatusCode;
            }
            return baseresponse;
        }
        catch (Exception ex)
        {
            baseresponse.StatusCode = 0;
            baseresponse.ResponseMessage = (ex.Message ?? ex.InnerException.ToString());
        }
        return baseresponse;
    }
}


public class BaseResponse
{
    public int StatusCode { get; set; }
    public string ResponseMessage { get; set; }
}

public class BaseClient
{
    readonly HttpClient client;
    readonly BaseResponse baseresponse;

    public BaseClient(string baseAddress, string username, string password)
    {
        HttpClientHandler handler = new HttpClientHandler()
        {
            Proxy = new WebProxy("http://127.0.0.1:8888"),
            UseProxy = false,
        };

        client = new HttpClient(handler);
        client.BaseAddress = new Uri(baseAddress);
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        var byteArray = Encoding.ASCII.GetBytes(username + ":" + password);

        client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));

        baseresponse = new BaseResponse();

    }
}
Pramod Lawate
  • 615
  • 1
  • 7
  • 21