[.NET][OAuth Series] EasyOAuth Library: 容易使用且可擴充的 OAuth Library

這是筆者的第三個 Codeplex 開放原始碼專案,承繼前面四篇 OAuth Series 文章的說明,EasyOAuth Library 建構於 .NET Framework 之上,並且可以很容易的將 OAuth 的功能套用到自己的 .NET 應用程式中,並且開發人員可以依照 EasyOAuth Library 開放的介面,為非內建的 OAuth Service Provider 開發介面,以在 EasyOAuth Library 中直接使用。

這是筆者的第三個 Codeplex 開放原始碼專案,承繼前面四篇 OAuth Series 文章的說明,EasyOAuth Library 建構於 .NET Framework 之上,並且可以很容易的將 OAuth 的功能套用到自己的 .NET 應用程式中,並且開發人員可以依照 EasyOAuth Library 開放的介面,為非內建的 OAuth Service Provider 開發介面,以在 EasyOAuth Library 中直接使用。

EasyOAuth Library 支援 Google Account, Facebook, Twitter 以及 Yahoo 四種 OAuth Service Provider 的驗證與授權功能,分別內建於 OAuth.Desktop 與 OAuth.Web 兩個函式庫中,分別是 GoogleOAuthProvider, FacebookOAuthProvider, TwitterOAuthProvider 與 YahooOAuthProvider 四個類別,它們有自己的 Configuration 機制,並且可以一次在同一個應用程式中使用不同的 OAuth Service Provider 進行認證與授權。同時,授權取得的認證碼 (access token) 會自動保存在 OAuthAccessTokens.dat 檔案中,這個檔案是一個 XML 的檔案。

目前筆者首先釋出 Desktop Application 版本的 EasyOAuth Library,未來會再釋出 Web Application 版本的 EasyOAuth Library。

首先,請到 http://easyoauth.codeplex.com 下載 Desktop Application 的 Binary code,並且加入參考到桌面應用程式 (可以是 Console application 或 Windows Forms application),然後在 app.config (如果專案中沒有的話要加) 中加入下列宣告:

<configSections>
  <section name="oauth.configuration" type="OAuth.OAuthConfigurationSection, OAuth"/>
</configSections>

然後,加入下面的 EasyOAuth 組態設定:

<oauth.configuration defaultPersistProvider="XML">
  <providers>
    <add provider="GoogleAccount" assembly="OAuth.Desktop" type="OAuth.Desktop.GoogleOAuthProvider" consumerKey="" consumerSecret="" scope="
https://www.google.com/base/feeds/ http://gdata.youtube.com/feeds/api/videos/" consentUrl="https://www.google.com/accounts/OAuthAuthorizeToken" requestTokenUrl="https://www.google.com/accounts/OAuthGetRequestToken" requestAccessTokenUrl="https://www.google.com/accounts/OAuthGetAccessToken"/>
    <add provider="Yahoo" assembly="OAuth.Desktop" type="OAuth.Desktop.YahooOAuthProvider" consumerKey="" consumerSecret="" scope="" consentUrl="
https://api.login.yahoo.com/oauth/v2/request_auth" requestTokenUrl="https://api.login.yahoo.com/oauth/v2/get_request_token" requestAccessTokenUrl="https://api.login.yahoo.com/oauth/v2/get_token"/>
    <add provider="Twitter" assembly="OAuth.Desktop" type="OAuth.Desktop.TwitterOAuthProvider" consumerKey="" consumerSecret="" scope="" consentUrl="
http://api.twitter.com/oauth/authorize" requestTokenUrl="https://api.twitter.com/oauth/request_token" requestAccessTokenUrl="https://api.twitter.com/oauth/access_token"/>
    <add provider="Flickr" assembly="OAuth.Desktop" type="OAuth.Desktop.FlickrOAuthProvider" consumerKey="" consumerSecret="" scope="" consentUrl="" requestTokenUrl="" requestAccessTokenUrl=""/>
    <add provider="Facebook" assembly="OAuth.Desktop" type="OAuth.Desktop.FacebookOAuthProvider" consumerKey="" consumerSecret="" scope="publish_stream,read_stream,email,offline_access" consentUrl="
https://graph.facebook.com/oauth/authorize?client_id={0}&amp;redirect_uri=http://www.facebook.com/connect/login_success.html&amp;type=user_agent&amp;display=popup&amp;scope={1}" requestTokenUrl="" requestAccessTokenUrl=""/>
  </providers>
  <persists>
    <add name="DB" provider="OAuth.PersistDBProvider" connectionString=""/>
    <add name="XML" provider="OAuth.PersistXmlProvider" connectionString=""/>
  </persists>
</oauth.configuration>

這些組態設定定義了 OAuth Service Provider 的認證行為,包含應用程式的金鑰 (consumerKey),密碼 (consumerSecret),授權介面 URL (consentUrl),要求授權 URL (requestTokenUrl) 以及要求存取 URL (requestAccessTokenUrl) 等設定,如果 OAuth Service Provider 沒有變動的話,基本上 URL 可以不用改。

組態設定好後,只要在程式中引入 OAuth 命名空間:

using OAuth;

然後使用 OAuthContext 物件,即可操作 OAuth 的流程:

OAuth.OAuthContext context = new OAuth.OAuthContext();
string userID = "1111"; // 這個可由開發人員自訂,在多使用者的情況下,識別該使用者的 access token。

try
{

    if (!context.IsAccessTokenValid(userID))
    {
        context.ObtainRequestToken();
        context.ObtainVerifier();
        context.ObtainAccessToken();
        context.PersistAccessToken(userID);
    }
    else
        context.LoadAccessToken(userID);

    Console.WriteLine(context.Provider.PerformRequest("http://gdata.youtube.com/feeds/api/videos/"));
}
catch (OAuth.OAuthUnauthorizedException ue)
{
    Console.WriteLine("HTTP 401");
    Console.WriteLine("Signature: " + ue.Signature);
    Console.WriteLine("base_string:" + ue.SignatureBaseString);
    Console.WriteLine("Response: " + ue.ResponseDataString);
}
catch (OAuth.OAuthNetworkException ne)
{
    Console.WriteLine("Network Problem");
    Console.WriteLine("Response: " + ne.ResponseDataString);
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
    Console.WriteLine(e.StackTrace);
}
finally
{
    context = null;
}

這段範例程式會存取 Google Account,若程式發現目前沒有授權時,會執行 context.ObtainRequestToken() 與 context.ObtainVerifier() 程序,此時使用者應該會看到一個要求授權的對話盒:

image

當使用者授予權限時,會看到:

image

使用者需要將畫面上的授權碼 (每個 Service Provider 的畫面會不太一樣) 貼到下方的授權碼文字框,然後按下 [授予存取],接著 OAuthContext 就會執行 ObtainAccessToken() 取得存取碼,最後將存取碼保存在 OAuthAccessTokens.dat 檔案中,下次若仍是同一個使用者存取時,就直接取用在 OAuthAccessTokens.dat 檔案的存取碼直接存取。

目前 EasyOAuth Library 已經實作了完整的 OAuth 認證與授權流程,但並未包含存取這些服務的 Private APIs,因此如有這個需求的開發人員,可以參考這篇文章,以使用 access token 存取 Private APIs,未來可能筆者也會釋出針對這些 Service Provider 的 API 存取的 Library (我只說可能哦…)。