使用Box Windows SDK v2库在C#桌面应用程序中对Box进行身份验证

时间:2014-03-02 05:14:08

标签: c# oauth-2.0 box-api

看起来这应该是一件简单的事情,但我无法找到一个示例或足够详尽的文档来解决这个问题。

我有一个C#桌面应用程序,我想通过Box API与Box集成。我假设使用Box Windows SDK v2 for .NET将是最佳选择。

有人能指出一个适用于桌面应用程序的简单,简单的示例吗?

2 个答案:

答案 0 :(得分:9)

我决定尝试自己解决这个问题。尽管OAuth2支持非基于浏览器的身份验证,但显然Box.com决定不实现它(或者,至少,我没有提到如何在任何地方执行此操作)。

因此,基于桌面的应用程序的唯一替代方法是以某种方式拦截发生的URL重定向并从查询字符串参数中抽出身份验证信息。

然而,由于IE最近落后于时代,我在C#和.NET工作,我决定研究嵌入另一个浏览器,而不是使用内置的浏览器控件。我选择了Awesomium - 一个托管的.NET Chromium包装器。

所以,不用多说,我将介绍适用于桌面应用程序的简单示例。

我的解决方案有两种形式,一种是我纯粹用作“浏览器”和主要形式:frmMain包含所有代码,frmBrowser包含Awesomium控件。

using Newtonsoft.Json.Linq;
using System.Web;

private static frmBrowser browser = null;
private const string BoxClientId = "{your client id}";
private const string BoxSecret = "{your secret}";    

private void authenticateWithBox()
{
   browser = new frmBrowser();
   browser.Show();

   browser.webControl1.Source = new Uri("https://www.box.com/api/oauth2/authorize?response_type=code&client_id=" + BoxClientId + "&redirect_uri=https://localsess");
   browser.webControl1.AddressChanged += new Awesomium.Core.UrlEventHandler(webControl1_AddressChanged);
}

void webControl1_AddressChanged(object sender, Awesomium.Core.UrlEventArgs e)
{
  //MessageBox.Show(e.Url.ToString());
  if (e.Url.Host == "localsess")
  {
    NameValueCollection parms = HttpUtility.ParseQueryString(e.Url.Query);
    if (parms.AllKeys.Contains("error"))
    {
       MessageBox.Show("Error connecting to Box.com: " + parms["error"] + " " + parms["error_description"]);
    }
    else
    {
        boxContinue(parms["code"]);
    }
  }
}

以上代码是魔术发生的地方。每次Web控件显示的URL发生更改时,都会触发AddressChanged事件。因此,您必须将重定向URL设置为您可以检测到的唯一URL - 它甚至不必存在,如示例代码中所示。然后你可以抽出你需要的参数并继续验证过程。

string postToUrl(string url, string data)
{
  string results = String.Empty;
  WebRequest req = WebRequest.Create(url);
  req.Method = WebRequestMethods.Http.Post;
  byte[] byteArray = Encoding.UTF8.GetBytes(data);
  req.ContentType = "application/x-www-form-urlencoded";
  req.ContentLength = byteArray.Length;
  Stream dataStream = req.GetRequestStream();
  dataStream.Write(byteArray, 0, byteArray.Length);
  dataStream.Close();
  WebResponse res = req.GetResponse();
  dataStream = res.GetResponseStream();
  StreamReader reader = new StreamReader(dataStream);
  results = reader.ReadToEnd();
  return results;
}

void boxContinue(string code)
{
  browser.Close();
  browser.Dispose();
  string json = postToUrl("https://www.box.com/api/oauth2/token", "code=" + code + "&grant_type=authorization_code&client_id=" + BoxClientId + "&client_secret=" + BoxSecret);
  JToken token = JObject.Parse(json);

  string access_token = (string)token.SelectToken("access_token");
  string refresh_token = (string)token.SelectToken("refresh_token");
}

void boxRefresh(string refresh_token)
{
  string json = postToUrl("https://www.box.com/api/oauth2/token", "grant_type=refresh_token&refresh_token=" + refresh_token + "&client_id=" + BoxClientId + "&client_secret=" + BoxSecret);
  JToken token = JObject.Parse(json);

  string access_token = (string)token.SelectToken("access_token");
  string new_refresh_token = (string)token.SelectToken("refresh_token");
}

其余的代码只是你的普通认证代码,它使用令牌以及以前的请求来获取更多令牌等等.Box使用“refresh_tokens”来获得额外的访问权限,我也展示了如何做到这一点的例子。

如果您发现任何错误或有任何意见等,请发表评论。

答案 1 :(得分:0)

请确保您使用的是Box SDK的官方v2版本: https://github.com/box/box-windows-sdk-v2

解决方案中有一个完整的WPF示例可帮助您入门。如果您遇到任何其他问题,请随时在github页面的问题部分留言。