[OAuth Series] EasyOAuth Framework 2.0 Desktop and Web Edition

繼今年四月份的 EasyOAuth Framework 1.0 上架到 Codeplex.com 後,除了再檢視程式本身以外,還吸取一些來自社群的意見 (雖然不多...),以及配合 Windows Live ID 支援 OAuth 2.0 規格的發表,EasyOAuth Framework 也順勢改版到 2.0,同樣支援 Desktop Edition 與 Web Edition,可供桌面應用程式與 Web 應用程式的 OAuth 認證機制開發功能。

繼今年四月份的 EasyOAuth Framework 1.0 上架到 Codeplex.com 後,除了再檢視程式本身以外,還吸取一些來自社群的意見 (雖然不多...),以及配合 Windows Live ID 支援 OAuth 2.0 規格的發表,EasyOAuth Framework 也順勢改版到 2.0,同樣支援 Desktop Edition 與 Web Edition,可供桌面應用程式與 Web 應用程式的 OAuth 認證機制開發功能。

EasyOAuth Framework 2.0 相對於 1.0 版有一些改變:

1. 重構整個程式碼,將不必要的程式移除與整併,並將 OAuth 1.0 與 2.0 的用戶端程式濃縮成基礎的類別,也就是 EasyOAuth.Core.OAuthDesktopClientV1 (Web: OAuthWebClientV1) 與 EasyOAuth.Core.OAuthDesktopClientV2 (Web: OAuthWebClientV2) 兩個類別,搭配 Configuration 組態檔以串接完整的 OAuth 認證與授權流程,但所需的程式碼卻很少:

// v1.0
context = new OAuthContext("Facebook");

context.ObtainRequestToken();
context.ObtainVerifier();
context.ObtainAccessToken();

Console.WriteLine("access token=" + context.Provider.GetDataRepository().Token);


// v2.0
EasyOAuth.Core.OAuthDesktopClientV1 client = EasyOAuth.Core.OAuthDesktopFactory.CreateProviderForOAuthV2("facebook");
client.VerifyAuthentication();
Console.WriteLine("access token=" + client.Token);

2. 組態檔配合 2.0 的改版做調整,讓它更階層與明確化:

<configuration>
  <configSections>
    <section name="oauth.configuration" type="EasyOAuth.Core.Configuration.OAuthConfigurationSection, EasyOAuth.Core" />
  </configSections>
  <oauth.configuration>
    <v1.0>
      <add name="twitter"
           consumerkey="[Consumer Key]"
           consumersecret="[Consumer Secret]"
           isVerifyCodeRequiredInDesktopMode="true" />
      <add name="google"
           consumerkey="[Consumer Key]"
           consumersecret="[Consumer Secret]"
           isVerifyCodeRequiredInDesktopMode="true"
           scope="
http://www-opensocial.googleusercontent.com/api/people/">
        <ServiceProviders>
          <add type="requestToken" url="
https://www.google.com/accounts/OAuthGetRequestToken?scope={0}" />
          <add type="verifier" url="
https://www.google.com/accounts/OAuthAuthorizeToken" />
          <add type="requestAccessToken" url="
https://www.google.com/accounts/OAuthGetAccessToken" />
          <add type="requestProfile" url="
http://www-opensocial.googleusercontent.com/api/people/@me/@self" />
        </ServiceProviders>
      </add>
      <add name="linkedin"
           consumerkey="[Consumer Key]"
           consumersecret="[Consumer Secret]"
           isVerifyCodeRequiredInDesktopMode="true" />
      <add name="plurk"
           consumerkey="[Consumer Key]"
           consumersecret="[Consumer Secret]"
           isVerifyCodeRequiredInDesktopMode="true" />
      <add name="dropbox"
           consumerkey="[Consumer Key]"
           consumersecret="[Consumer Secret]"
           isVerifyCodeRequiredInDesktopMode="true" />
      <add name="yahoo"
           consumerkey="[Consumer Key]"
           consumersecret="[Consumer Secret]"
           isVerifyCodeRequiredInDesktopMode="true" />
    </v1.0>
    <v2.0>
      <add name="facebook"
           consumerkey="[Consumer Key]"
           consumersecret="[Consumer Secret]"
           scope="publish_stream,read_stream,email,offline_access" />
      <add name="windowslive"
           consumerkey="[Consumer Key]"
           consumersecret="[Consumer Secret]"
           scope="publish_stream,read_stream,email,offline_access" />
    </v2.0>
  </oauth.configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

保留組態檔的目的,是為了保持擴充的彈性,如果需要使用到不屬於內建的提供者的 OAuth Service Provider 時,可以透過組態檔來設定。

3. 支援 8 個主流的 OAuth Service Provider,包含 Google, Facebook, Twitter, Yahoo, Linked In, Dropbox, Plurk 與 Windows Live ID 等,且以 EasyOAuth.Providers 組件提供內建的支援,並且同時支援 Desktop 與 Web,不用再像 v1.0 版時還要分開加入參考,而且如果使用內建的 Provider,可以在不設定組態檔的情況下直接使用:

EasyOAuth.Providers.Desktop.GoogleClient client =
    EasyOAuth.Providers.OAuthDesktopProviderFactory.CreateOAuthClient<EasyOAuth.Providers.Desktop.GoogleClient>(
    "[consumer key]", "[consumer secret]", "[scope]");

client.VerifyAuthentication();
Console.WriteLine("access token=" + client.Token);

也就是說,如果只要用到內建的 OAuth Service Provider,則只要使用 EasyOAuth.Providers.dll 中提供的類別即可,但若要用到額外的 OAuth Service Provider,則可以使用 OAuthDesktopClient 或 OAuthWebClient 配合組態檔的設定來存取。

4. EasyOAuth Framework 2.0 的 Web 實作有一部份變更,在 EasyOAuth.WebUtility.dll 中封裝了 OAuthVerifyHandler 類別,它是一個 HTTP Handler,要先將它註冊到 Web.config 中成為一個處理常式,它會作為 Callback 的處理常式,所以在 OAuth Service Provider 如果需要 callback URL,要記得把這支處理常式的 URL 提供給 OAuth Service Provider。而 Web Application 這裡使用的是 OAuthClientContext 物件,並呼叫 BeginAuthentication() 觸發認證:

// 註解掉的這個用法也可以,但為了展示使用內建 Provider 的能力,所以先註解掉本行。
//EasyOAuth.WebUtility.OAuthClientContext oauthContext =
//    EasyOAuth.WebUtility.OAuthClientContext.Create(EasyOAuth.Core.OAuthWebFactory.CreateProviderForOAuthV1("google"));

EasyOAuth.WebUtility.OAuthClientContext oauthContext =
    EasyOAuth.WebUtility.OAuthClientContext.Create(
    EasyOAuth.Providers.OAuthWebProviderFactory.CreateOAuthClient<EasyOAuth.Providers.Web.GoogleClient>("google"));

try
{
    oauthContext.BeginAuthentication();
}
catch (OAuthNetworkException one)
{
    this.labelError.Text = one.Message;
    this.labelResponseText.Text = one.ResponseDataString;
    this.labelOAuthHeader.Text = one.OAuthHeader;
}
catch (OAuthException oe)
{
    this.labelError.Text = oe.Message + " - " + oe.InnerException.Message;
}

然後再於 Web.config 中設定 Web 要使用的 acceptedRedirectUrl (認證通過時要導向的網頁) 與 failedRedirectUrl (認證失敗時要導向的網頁):

<configuration>
  <configSections>
    <section name="oauth.configuration" type="EasyOAuth.Core.Configuration.OAuthConfigurationSection, EasyOAuth.Core" />
  </configSections>
  <oauth.configuration>
   
<web acceptedRedirectUrl="~/Accepted.aspx" failedRedirectUrl="~/Rejected.aspx" />
    <v1.0>
      ....
    </v1.0>
    </v2.0>
      ....
    </v2.0>
  </oauth.configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <customErrors mode="Off" />
  </system.web>
  <system.webServer>
    <handlers>
      <add name="OAuthVerifyHandler" path="OAuthVerify.do"
           verb="GET" type="EasyOAuth.WebUtility.OAuthVerifyHandler, EasyOAuth.WebUtility" />
    </handlers>
  </system.webServer>

</configuration>

就完成了使用 EasyOAuth Framework 2.0 Web Edition 的設定了,最後只要在 acceptedRedirectUrl 的網頁中使用下列程式碼,即可取得 access token:

this.labelAccessToken.Text = EasyOAuth.WebUtility.OAuthClientContext.Current.Token;

EasyOAuth Framework 2.0 Web Edition 的測試公開網址在 http://www.studyazure.com (暫行的):

image

當認證完成時,可以看到 access token 的值:

image

4. 暫時移除自動保存 access token 的功能,因為個人覺得這個功能寫的有點爛,而且好像很容易誤解,所以先移除。等到 2.0 SP1 時再加回去。

 

EasyOAuth Framework 2.0 Desktop and Web Edition 一樣可以由 http://easyoauth.codeplex.com 下載,這個版本應該是不會再變了,日後的 OAuth 相關的功能應該就是以這個為基礎向上開發。如果用起來有什麼樣的意見或看法,也歡迎 feedback 給我或在 EasyOAuth 的 Codeplex 網站討論區上留言。