【问题标题】:Calling a rest api with username and password - how to使用用户名和密码调用 rest api - 如何
【发布时间】:2013-08-21 00:33:01
【问题描述】:

我是 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?

标签: c# rest basic-authentication


【解决方案1】:

如果 API 要求使用 HTTP Basic 身份验证,那么您需要在请求中添加 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;

当然,用正确的值替换 "username""password"

【讨论】:

  • @SHEKHARSHETE 您可能想看看HttpWebResponse.GetResponseStream()。完成后,请特别注意关于关闭 Stream 的备注说明。这很重要。
  • 确保您取消注释 req.Credentials.. 与您的用户名和密码行。否则它将保持未经授权。
  • @Gurusinghe 在我以前使用过它的任何时候都没有这样做过。这个 sn-p 制作了 Authorization 标头,该标头被传递给所有者服务器
【解决方案2】:

您还可以使用 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。您对此有什么建议或解决方案吗?
  • 我认为您所要求的方案不适用于 BasicAuthentication。例如,您可以尝试使用 NTLM 使用一些代码,例如: RestClient client = new RestClient(_baseURL); client.Authenticator = new NtlmAuthenticator();
  • 感谢您的回复。你是对的,就我而言,它需要基本身份验证,而 NTLM 也不赞成。所以,这让我产生疑问,虽然我也在尝试对我的 api 实现基本身份验证,但是否有任何方法可以使用 ClaimsPrincipal/HttpContext 创建基本身份验证?
【解决方案3】:

这里是 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();

    }
}

【讨论】:

    猜你喜欢
    • 2016-08-17
    • 2015-03-13
    • 1970-01-01
    • 2015-02-18
    • 2016-01-21
    • 1970-01-01
    • 2012-04-06
    • 1970-01-01
    • 2016-06-06
    相关资源
    最近更新 更多