使用用户名和密码调用Rest API - 如何操作

50

我是rest API和通过.NET调用它们的新手。

我有一个API:https://sub.domain.com/api/operations?param=value&param2=value

API的注释说,要进行授权,我需要使用基本访问身份验证-我该如何做?

我目前有以下代码:

        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;

然而我收到了401未授权的错误。

我错过了什么?如何使用基本访问权限进行API调用?


认证类型取决于API。您要调用的API是什么?401未经授权意味着您明显传递了无效凭据,并且不提供足够的诊断上下文。该API是否使用OAuth? - Karan Ashar
3个回答

71
如果API要求使用HTTP基本身份验证,则需要在请求中添加Authorization标头。我会更改您的代码,使其看起来像这样:
    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;

当然,用正确的值替换"用户名""密码"


@SHEKHARSHETE 你可能想要查看HttpWebResponse.GetResponseStream()。特别注意一下备注中关于在使用完流后关闭它的说明。这非常重要。 - Adrian
请务必取消注释req.Credentials行并填写您的用户名和密码,否则它将保持未经授权状态。 - Gurusinghe
@Gurusinghe之前我使用过,他从来没有做过那件事。这段代码片段构造了授权头,该头信息被传递给所有者服务器。 - Adrian
WebRequest已经过时。建议将此代码更改为使用HttpClientHttpWebRequest - Robert Harvey
@RobertHarvey 我的意思是,这是八年前写的。我不会一直回来更正已接受的答案,根据当前范例或当事物过时或离开终身支持。 - Adrian

6

你也可以使用RestSharp库,例如

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);

那么,在这种情况下,我如何传递当前用户的默认凭据,而无需提供用户名/密码。以当前执行用户凭据的基本身份验证方式?我不能使用requst.UseDefaultCredentials = true。你有任何建议或解决方案吗? - Ak777
我认为你所询问的场景不适用于BasicAuthentication。你可以尝试使用NTLM,例如:使用以下代码: RestClient client = new RestClient(_baseURL); client.Authenticator = new NtlmAuthenticator(); - orellabac
谢谢您的回复。您说得对,在我的情况下,它期望基本身份验证,而NTLM并不适用。因此,这让我怀疑,当我也尝试将基本身份验证实现到我的API中时,是否有任何可能使用ClaimsPrincipal/HttpContext创建基本身份验证的最微小方法? - Ak777

2
这是关于 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();

    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接