2014-01-11 44 views
2

我已被授予使用基本身份验证创建http文章的任务。 我正在使用C#在asp.net MVC应用程序中开发。如何发送一个http basic auth post?

我也给过这个例子。

{ 
POST /v2/token_endpoint HTTP/1.1 
Authorization: Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ= 
Accept: application/json 
Content-Type: application/x-www-form-urlencoded 
User-Agent: Java/1.6.0_33 
Host: api.freeagent.com 
Connection: close 
Content-Length: 127 

grant_type=authorization_code&code=12P3AsFZXwXjd7SLOE1dsaX8oCgix&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Foauth 
} 

我的问题是我该如何在C#中编码? 如果有更多的信息,只需要问,在此先感谢

编辑:我已经取得了一些进展,但我还没有加入grant_type

public void AccessToken(string code) 
    { 
     string url = @"https://api.freeagent.com/v2/token_endpoint"; 
     WebClient client = new WebClient(); 
     string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(ApiKey + ":" + ApiSecret)); 
     client.Headers[HttpRequestHeader.Authorization] = "Basic " + credentials; 
     client.Headers[HttpRequestHeader.Accept] = "application/json"; 
     client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded"; 
     client.Headers[HttpRequestHeader.UserAgent] = "Java/1.6.0_33"; 
     client.Headers[HttpRequestHeader.Host] = "api.freeagent.com"; 
     client.Headers[HttpRequestHeader.Connection] = "close"; 
     client.Headers["grant_type"] = "authorization_code"; 

     var result = client.DownloadString(url); 
    } 

让我怎么加:grant_type = authorization_code &码= 12P3AsFZXwXjd7SLOE1dsaX8oCgix & redirect_uri = http%3A%2F%2Flocalhost%3A8080%2Foauth的帖子?

回答

1

你可以在这里找到两个样本如何进行基本身份验证请求用的WebRequest和WebClient的类:

http://grahamrhay.wordpress.com/2011/08/22/making-a-post-request-in-c-with-basic-authentication/ http://anishshenoy57.wordpress.com/2013/01/22/basic-http-authentication-using-c/

基本上基本身份验证,它只是Base64(username:password),所以很容易实现它。

UPDATE1

这是基于你的方法的例子:

public void AccessToken(string code) 
{ 
    string url = @"https://api.freeagent.com/v2/token_endpoint"; 
    WebClient client = new WebClient(); 
    string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(ApiKey + ":" + ApiSecret)); 
    client.Headers[HttpRequestHeader.Authorization] = "Basic " + credentials; 
    client.Headers[HttpRequestHeader.Accept] = "application/json"; 
    client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded"; 
    client.Headers[HttpRequestHeader.UserAgent] = "Java/1.6.0_33"; 
    client.Headers[HttpRequestHeader.Host] = "api.freeagent.com"; 
    client.Headers[HttpRequestHeader.Connection] = "close"; 
    client.Headers["grant_type"] = "authorization_code"; 

    string data = string.Format(
     "grant_type=authorization_code&code={0}&redirect_uri=http%3A%2F%2Flocalhost%3A8080", 
     code); 
    var result = client.UploadString(url, data); 
} 

WebClient调用方法的唯一不同。 DownloadString会做GET请求,但对于POST您需要使用UploadString方法

+0

对不起,但这些似乎都没有解决方案,显示如何发送所有上述信息的发布请求:s – user1348463

+0

我已经更新基于您的AccessToken方法和POST请求的示例 –

0

我也一直在努力,但我现在已经做到了另一边!

让我最感激的是,如果您在Auth令牌请求中指定了重定向URL,则还必须在使用相同URL的访问令牌请求中指定它,即使它未被使用。

我从某人的部分包装开始,并且已经发展了它几乎无法承认。希望这个包装器(包含auth和访问令牌代码)可以帮助其他人。迄今为止,我只用它来创建发票和发票项目,而其他函数未经测试,但它应该为您提供令牌并且可以调试请求。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Text; 
using System.Web.Script.Serialization; 

namespace ClientZone.External 
{ 
    public class FreeAgent 
    { 
     public enum Methods 
     { 
      POST = 1, 
      PUT 
     } 

     public enum Status 
     { 
      Draft = 1, 
      Sent, 
      Cancelled 
     } 

     private string _subDomain; 
     private string _identifier; 
     private string _secret; 
     private string _redirectURI; 
     public static string AuthToken = ""; 
     private static string _accessToken = ""; 
     private static string _refreshToken = ""; 
     private static DateTime _refreshTime; 

     public FreeAgent(string identifier, string secret, string subdomain, string redirectURI) 
     { 
      _subDomain = subdomain; 
      _identifier = identifier; 
      _secret = secret; 
      _redirectURI = redirectURI; // If this was specified in the Auth Token call, you must specify it here, and it must be the same 
     } 

     public bool GetAccessToken() 
     { 
      try 
      { 
       string url = @"https://api.freeagent.com/v2/token_endpoint"; 
       WebClient client = new WebClient(); 
       string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(_identifier + ":" + _secret)); 
       client.Headers[HttpRequestHeader.Host] = "api.freeagent.com"; 
       client.Headers[HttpRequestHeader.KeepAlive] = "true"; 
       client.Headers[HttpRequestHeader.Accept] = "application/json"; 
       client.Headers[HttpRequestHeader.UserAgent] = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36"; 
       client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded;charset=UTF-8"; 

       client.Headers[HttpRequestHeader.Authorization] = "Basic " + credentials; 
       System.Net.ServicePointManager.Expect100Continue = false; 
       client.Headers[HttpRequestHeader.AcceptEncoding] = "gzip, deflate"; 
       client.Headers[HttpRequestHeader.AcceptLanguage] = "en-US,en;q=0.8"; 

       var result = ""; 
       if (!(_accessToken == "" && _refreshToken != "")) 
       { 
        string data = string.Format("grant_type=authorization_code&code={0}&redirect_uri={1}", AuthToken, _redirectURI); 
        result = client.UploadString(url, data); 
       } 
       else 
       { 
        // Marking the access token as blank and the refresh token as not blank 
        // is a sign we need to get a refresh token 
        string data = string.Format("grant_type=refresh_token&refresh_token={0}", _refreshToken); 
        result = client.UploadString(url, data); 
       } 

       JavaScriptSerializer json_serializer = new JavaScriptSerializer(); 
       var results_list = (IDictionary<string, object>)json_serializer.DeserializeObject(result); 
       _accessToken = results_list["access_token"].ToString(); 
       int secondsUntilRefresh = Int32.Parse(results_list["expires_in"].ToString()); 
       _refreshTime = DateTime.Now.AddSeconds(secondsUntilRefresh); 
       if (results_list.Any(x => x.Key == "refresh_token")) 
       { 
        _refreshToken = results_list["refresh_token"].ToString(); 
       } 

       if (_accessToken == "" || _refreshToken == "" || _refreshTime == new DateTime()) 
       { 
        return false; 
       } 

      } 
      catch 
      { 
       return false; 
      } 

      return true; 
     } 

     private HttpStatusCode SendWebRequest(Methods method, string URN, string request, out string ResponseData) 
     { 
      if (_accessToken == "") 
      { 
       // The access token has not been retrieved yet 
       GetAccessToken(); 
      } 
      else 
      { 
       if (_refreshTime != new DateTime() && _refreshTime < DateTime.Now) { 
        // The token has expired and we need to refresh it 
        _accessToken = ""; 
        GetAccessToken(); 
       } 
      } 

      if (_accessToken != "") 
      { 
       try 
       { 
        WebClient client = new WebClient(); 
        string url = "https://api.freeagentcentral.com/v2/" + URN; 
        client.Headers[HttpRequestHeader.UserAgent] = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36"; 
        client.Headers[HttpRequestHeader.Authorization] = "Bearer " + _accessToken; 
        client.Headers[HttpRequestHeader.ContentType] = "application/json"; 
        client.Headers[HttpRequestHeader.Accept] = "application/json"; 

        if (method == Methods.POST || method == Methods.PUT) 
        { 
         string data = request; 
         var result = client.UploadString(url, method.ToString(), data); 
         ResponseData = result; 
         return HttpStatusCode.Created; 
        } 
        else 
        { 
         var result = client.DownloadString(url); 
         ResponseData = result; 
         return HttpStatusCode.OK; 
        } 
       } 
       catch (WebException e) 
       { 
        if (e.GetType().Name == "WebException") 
        { 
         WebException we = (WebException)e; 
         HttpWebResponse response = (System.Net.HttpWebResponse)we.Response; 

         ResponseData = response.StatusDescription; 
         return response.StatusCode; 
        } 
        else 
        { 
         ResponseData = e.Message; 
         if (e.InnerException != null) 
         { 
          ResponseData = ResponseData + " - " + e.InnerException.ToString(); 
         } 
         return HttpStatusCode.SeeOther; 
        } 
       } 
      } 
      else 
      { 
       ResponseData = "Access Token could not be retrieved"; 
       return HttpStatusCode.SeeOther; 
      } 
     } 

     private int ExtractNewID(string resp, string URN) 
     { 
      if (resp != null && resp.Trim() != "") 
      { 
       JavaScriptSerializer json_serializer = new JavaScriptSerializer(); 
       var results_list = (IDictionary<string, object>)json_serializer.DeserializeObject(resp); 

       if (results_list.Any(x => x.Key == "invoice")) 
       { 
        var returnInvoice = (IDictionary<string, object>)results_list["invoice"]; 

        if (returnInvoice["created_at"].ToString() != "") 
        { 
         string returnURL = returnInvoice["url"].ToString(); 

         if (returnURL.Contains("http")) 
         { 
          return int.Parse(returnURL.Remove(0, ("https://api.freeagentcentral.com/v2/" + URN).Length + 1)); 
         } 
         else 
         { 
          return int.Parse(returnURL.Remove(0, URN.Length + 2)); 
         } 
        } 
       } 
      } 

      return -1; 
     } 

     public int CreateContact(string firstName, string lastName, string emailAddress, string street, string city, string state, string postcode, string country) 
     { 
      StringBuilder request = new StringBuilder(); 

      request.Append("{\"contact\":{"); 
      request.Append("\"first-name\":"); 
      request.Append(firstName); 
      request.Append("\","); 
      request.Append("\"last-name\":"); 
      request.Append(lastName); 
      request.Append("\","); 
      request.Append("\"email\":"); 
      request.Append(emailAddress); 
      request.Append("\","); 

      request.Append("\"address1\":"); 
      request.Append(street); 
      request.Append("\","); 
      request.Append("\"town\":"); 
      request.Append(city); 
      request.Append("\","); 
      request.Append("\"region\":"); 
      request.Append(state); 
      request.Append("\","); 
      request.Append("\"postcode\":"); 
      request.Append(postcode); 
      request.Append("\","); 
      request.Append("\"country\":"); 
      request.Append(country); 
      request.Append("\""); 

      request.Append("}"); 

      string returnData = string.Empty; 

      HttpStatusCode responseCode = SendWebRequest(Methods.POST, "contacts", request.ToString(), out returnData); 
      if (responseCode == HttpStatusCode.OK || responseCode == HttpStatusCode.Created) 
      { 
       return ExtractNewID(returnData, "contacts"); 
      } 
      else 
      { 
       return -1; 
      } 
     } 

     public int CreateInvoice(int contactID, DateTime invoiceDate, int terms, string reference, string comments, string currency = "GBP") 
     { 
      StringBuilder request = new StringBuilder(); 

      request.Append("{\"invoice\":{"); 
      request.Append("\"dated_on\": \""); 
      request.Append(invoiceDate.ToString("yyyy-MM-ddTHH:mm:00Z")); 
      request.Append("\","); 

      if (!string.IsNullOrEmpty(reference)) 
      { 
       request.Append("\"reference\": \""); 
       request.Append(reference); 
       request.Append("\","); 
      } 

      if (!string.IsNullOrEmpty(comments)) 
      { 
       request.Append("\"comments\": \""); 
       request.Append(comments); 
       request.Append("\","); 
      } 

      request.Append("\"payment_terms_in_days\": \""); 
      request.Append(terms); 
      request.Append("\","); 

      request.Append("\"contact\": \""); 
      request.Append(contactID); 
      request.Append("\","); 

      if (currency == "EUR") 
      { 
       request.Append("\"ec_status\": \""); 
       request.Append("EC Services"); 
       request.Append("\","); 
      } 

      request.Append("\"currency\": \""); 
      request.Append(currency); 
      request.Append("\""); 

      request.Append("}}"); 

      string returnData = string.Empty; 

      HttpStatusCode responseCode = SendWebRequest(Methods.POST, "invoices", request.ToString(), out returnData); 
      if (responseCode == HttpStatusCode.OK || responseCode == HttpStatusCode.Created) 
      { 
       return ExtractNewID(returnData, "invoices"); 
      } 
      else 
      { 
       return -1; 
      } 
     } 

     public bool ChangeInvoiceStatus(int invoiceID, Status status) 
     { 
      string returnData = string.Empty; 

      HttpStatusCode resp = SendWebRequest(Methods.PUT, "invoices/" + invoiceID.ToString() + "/transitions/mark_as_" + status.ToString().ToLower(), string.Empty, out returnData); 

      return false; 
     } 

     public int CreateInvoiceItem(int invoiceID, string itemType, float price, int quantity, float taxRate, string description) 
     { 
      StringBuilder request = new StringBuilder(); 

      request.Append("{\"invoice\":{"); 
      request.Append("\"invoice_items\":[{"); 

      request.Append("\"item_type\": \""); 
      request.Append(itemType); 
      request.Append("\","); 

      request.Append("\"price\": \""); 
      request.Append(price.ToString("0.00")); 
      request.Append("\","); 

      request.Append("\"quantity\": \""); 
      request.Append(quantity); 
      request.Append("\","); 

      request.Append("\"sales_tax_rate\": \""); 
      request.Append(taxRate.ToString("0.00")); 
      request.Append("\","); 

      request.Append("\"description\": \""); 
      request.Append(description); 
      request.Append("\""); 

      request.Append("}]"); 
      request.Append("}"); 
      request.Append("}"); 

      string returnData = string.Empty; 

      HttpStatusCode responseCode = SendWebRequest(Methods.PUT, "invoices/" + invoiceID.ToString(), request.ToString(), out returnData); 
      if (responseCode == HttpStatusCode.OK || responseCode == HttpStatusCode.Created) 
      { 
       // Invoice items is an update call to an invoice, so we just get a 200 OK with no response body to extract an ID from 
       return 0; 
      } 
      else 
      { 
       return -1; 
      } 
     } 
    } 
} 

要在MVC的设置,你需要在索引中检测登录是否有必要或不使用此。如果是,则告诉FreeAgent返回另一个ActionResult(我使用Auth)来捕获重定向并存储代码。

public ActionResult Index() 
    { 
     if (MyNamespace.External.FreeAgent.AuthToken == "") 
     { 
      return Redirect("https://api.freeagent.com/v2/approve_app?redirect_uri=" + Request.Url.Scheme + "://" + Request.Url.Authority + "/Invoice/Auth" + "&response_type=code&client_id=123456789"); 

     } 
     else 
     { 
      return View(); 
     } 
    } 


    public ActionResult Auth() 
    { 
     if (Request.Params.Get("code").ToString() != "") 
     { 
      ClientZone.External.FreeAgent.AuthToken = Request.Params.Get("code").ToString(); 
     } 

     return View("Index"); 
    } 

然后使用这些功能的所有你需要的是

MyNameSpace.External.FreeAgent FA = new ClientZone.External.FreeAgent("abcdefghhijklmnopqrstu", "123456789", "acme", "http://localhost:52404/Invoice/Auth"); 

int newID = FA.CreateInvoice(54321, InvoiceDate, 30, "", "", "GBP"); 
if (newID != -1) 
{ 
    FA.CreateInvoiceItem(newID, unit, rate, quantity, number, description); 
} 

有一个在CreateInvoice一些英国/欧洲特定的编码。我不确定这是如何定制或标准化的,但是我已经将其留在了原地,因为删除它比重新创建它更容易。