你如何使用Windows客户端应用程序中的openAuth?

我正在考虑将公共API集成到现有的Windows窗体应用程序中。 api需要openAuth身份validation。 我见过的所有这些例子都是基于网络的应用程序。

如何在客户端应用程序上使用openAUth?

谢谢

这不是最简单的解释,但是我为YouTube实施了这个:

我构建了一个构建消息的ShardOAuth类:

#Region "Imports" Imports System.Text Imports System.Security.Cryptography #End Region Public NotInheritable Class SharedOAuth #Region "Class Declarations" Private Const unreservedChars As String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~" Private Const OAuthVersion As String = "1.0" Private Const OAuthParameterPrefix As String = "oauth_" Private Const OAuthParameterExclusionPrefix As String = "xoauth_" Private Const OAuthConsumerKeyKey As String = "oauth_consumer_key" Private Const OAuthCallbackKey As String = "oauth_callback" Private Const OAuthVersionKey As String = "oauth_version" Private Const OAuthSignatureMethodKey As String = "oauth_signature_method" Private Const OAuthSignatureKey As String = "oauth_signature" Private Const OAuthTimestampKey As String = "oauth_timestamp" Private Const OAuthNonceKey As String = "oauth_nonce" Private Const OAuthTokenKey As String = "oauth_token" Private Const OAuthTokenSecretKey As String = "oauth_token_secret" #End Region #Region "Constructor" Private Sub New() 'prevent construction End Sub #End Region #Region "Shared Functions" Public Shared Function GetSignatureTypeNameFromType(ByVal signatureType As enumerations.OAuthEnumerations.SignatureTypes) As String Select Case signatureType Case enumerations.OAuthEnumerations.SignatureTypes.HmacSha1 Return "HMAC-SHA1" Case Else Return String.Empty End Select End Function Public Shared Function GenerateTimeStamp() As String 'Implementation of UNIX current UTC time Dim _ts As TimeSpan = DateTime.UtcNow - New DateTime(1970, 1, 1, 0, 0, 0, 0) Return Convert.ToInt64(_ts.TotalSeconds).ToString(CultureInfo.InvariantCulture) End Function Public Shared Function GenerateNonce() As String 'Some random Number Return New Random().Next(123400, 9999999).ToString End Function Public Shared Function UrlEncode(ByVal value As String) As String Dim _result As New StringBuilder If (String.IsNullOrEmpty(value)) Then Return value End If For Each _symbol As Char In value If unreservedChars.IndexOf(_symbol) <> -1 Then _result.Append(_symbol) Else _result.Append(String.Format("%{0}", String.Format("{0:X2}", Asc(_symbol)))) End If Next Return _result.ToString End Function '''  '''Generates a signature using the specified signatureType '''  ''' The full url that needs to be signed including its non OAuth url parameters ''' The consumer key ''' The consumer seceret ''' The token, if available. If not available pass null or an empty string ''' The token secret, if available. If not available pass null or an empty string ''' The http method used. Must be a valid HTTP method verb (POST,GET,PUT, etc) ''' The type of signature to use ''' A base64 string of the hash value Public Shared Function GenerateSignature(ByVal url As Uri, ByVal consumerKey As String, ByVal consumerSecret As String, ByVal token As String, ByVal tokenSecret As String, ByVal httpMethod As String, ByVal timeStamp As String, ByVal nonce As String, ByVal signatureType As enumerations.OAuthEnumerations.SignatureTypes, ByRef normalizedUrl As String, ByRef normalizedRequestParameters As String) As String normalizedUrl = String.Empty normalizedRequestParameters = String.Empty Dim _signatureBase As String Dim _hash As HMACSHA1 Select Case signatureType Case enumerations.OAuthEnumerations.SignatureTypes.HmacSha1 _signatureBase = GenerateSignatureBase(url, consumerKey, token, tokenSecret, httpMethod, timeStamp, nonce, enumerations.OAuthEnumerations.SignatureTypes.HmacSha1, normalizedUrl, normalizedRequestParameters) Dim _sb As New StringBuilder With _sb .Append(UrlEncode(consumerSecret)) .Append("&") If (String.IsNullOrEmpty(tokenSecret)) Then .Append("") Else .Append(UrlEncode(tokenSecret)) End If End With _hash = New HMACSHA1 _hash.Key = Encoding.ASCII.GetBytes(_sb.ToString) Return GenerateSignatureUsingHash(_signatureBase, _hash) Case Else Throw New NotImplementedException End Select End Function Public Shared Function GenerateSignatureUsingHash(ByVal signatureBase As String, ByVal hash As HashAlgorithm) As String Return ComputeHash(hash, signatureBase) End Function Public Shared Function GenerateSignatureBase(ByVal url As Uri, ByVal consumerKey As String, ByVal token As String, ByVal tokenSecret As String, ByVal httpMethod As String, ByVal timeStamp As String, ByVal nonce As String, ByVal signatureType As enumerations.OAuthEnumerations.SignatureTypes, ByRef normalizedUrl As String, ByRef normalizedRequestParameters As String) As String Dim _SignatureTypeName As String = GetSignatureTypeNameFromType(signatureType) If String.IsNullOrEmpty(token) Then token = String.Empty End If If String.IsNullOrEmpty(tokenSecret) Then tokenSecret = String.Empty End If If String.IsNullOrEmpty(consumerKey) Then Throw New ArgumentNullException("consumerKey") End If If String.IsNullOrEmpty(httpMethod) Then Throw New ArgumentNullException("httpMethod") End If If String.IsNullOrEmpty(_SignatureTypeName) Then Throw New ArgumentNullException("SignatureType") End If normalizedUrl = String.Empty normalizedRequestParameters = String.Empty Dim _params As List(Of QueryParameter) = getqueryparameters(url.Query) With _params .Add(New QueryParameter(OAuthVersionKey, OAuthVersion)) .Add(New QueryParameter(OAuthNonceKey, nonce)) .Add(New QueryParameter(OAuthTimestampKey, timeStamp)) .Add(New QueryParameter(OAuthSignatureMethodKey, _SignatureTypeName)) .Add(New QueryParameter(OAuthConsumerKeyKey, consumerKey)) If Not (String.IsNullOrEmpty(token)) Then .Add(New QueryParameter(OAuthTokenKey, token)) End If .Sort(New QueryParameterComparer) End With normalizedUrl = String.Format("{0}://{1}", url.Scheme, url.Host) If Not ((url.Scheme = "http" AndAlso url.Port = 80) OrElse (url.Scheme = "https" AndAlso url.Port = 443)) Then normalizedUrl = String.Format("{0}:{1}", normalizedUrl, url.Port) End If normalizedUrl = String.Format("{0}{1}", normalizedUrl, url.AbsolutePath) normalizedRequestParameters = NormalizeRequestParameters(_params) Dim _sb As New StringBuilder With _sb .AppendFormat(CultureInfo.InvariantCulture, "{0}&", httpMethod.ToUpper) .AppendFormat(CultureInfo.InvariantCulture, "{0}&", UrlEncode(normalizedUrl)) .AppendFormat(CultureInfo.InvariantCulture, "{0}", UrlEncode(normalizedRequestParameters)) End With Return _sb.ToString End Function #End Region #Region "Private Methods" Private Shared Function ComputeHash(ByVal hashAlgorithm As HashAlgorithm, ByVal data As String) As String If hashAlgorithm Is Nothing Then Throw New ArgumentNullException("hashAlgorithm") End If If String.IsNullOrEmpty(data) Then Throw New ArgumentNullException("data") End If Dim _dataBuffer As Byte() = Encoding.ASCII.GetBytes(data) Dim _hashBytes As Byte() = hashAlgorithm.ComputeHash(_dataBuffer) Return Convert.ToBase64String(_hashBytes) End Function Private Shared Function NormalizeRequestParameters(ByVal parameters As IList(Of QueryParameter)) As String Dim _p As QueryParameter Dim _sb As New StringBuilder For i As Integer = 0 To parameters.count - 1 _p = parameters(i) _sb.AppendFormat(CultureInfo.InvariantCulture, "{0}={1}", _p.Name, _p.Value) If i < parameters.count - 1 Then _sb.Append("&") End If Next Return _sb.ToString End Function Private Shared Function GetQueryParameters(ByVal parameters As String) As List(Of QueryParameter) If (parameters.StartsWith("?")) Then parameters = parameters.Remove(0, 1) End If Dim _result As New List(Of QueryParameter) Dim _p As String() = parameters.Split("&"c) Dim _temp As String() If Not (String.IsNullOrEmpty(parameters)) Then For Each s As String In _p If Not (String.IsNullOrEmpty(s)) AndAlso Not (s.StartsWith(OAuthParameterExclusionPrefix)) Then 'AndAlso (s.StartsWith(OAuthParameterPrefix)) Then If s.IndexOf("=") > -1 Then _temp = s.Split("="c) _result.Add(New QueryParameter(_temp(0), _temp(1))) Else _result.Add(New QueryParameter(s, String.Empty)) End If End If Next End If Return _result End Function #End Region End Class 

然后使用这些较低级别的函数来构建和解析OAuth消息

 Public MustInherit Class BaseOAuth Inherits BaseAccess #Region "Class Declarations" Protected Const CONSUMER_KEY As String = "anonymous" Protected Const CONSUMER_SECRET As String = "anonymous" Protected Const SCOPEURL As String = "http://gdata.youtube.com" ' Protected m_FeedCollection As ArrayList #End Region #Region "Constructor" Public Sub New() MyBase.new() End Sub Public Sub New(ByVal context As Common.Statefulogic.Context) MyBase.new(context) End Sub #End Region #Region "Public Properties" #End Region #Region "Private Functions" #End Region #Region "Public Methods" Public Function SignCommandUrl(ByVal commandUrl As String) As String Return SignCommandUrl(commandUrl, Nothing, Nothing) End Function Public Function SignCommandUrl(ByVal commandUrl As String, ByVal overrideToken As String, ByVal overrideTokenSecret As String) As String Dim _commandUri = New Uri(commandUrl) Dim _oAuthSignature As String Dim _oAuthTimeStamp As String = SharedOAuth.GenerateTimeStamp Dim _oAuthNOnce As String = SharedOAuth.GenerateNonce Dim _oAuth_normalized_url As String = String.Empty Dim _oAuth_normalized_params As String = String.Empty If Not (String.IsNullOrEmpty(overrideToken)) OrElse Not (String.IsNullOrEmpty(overrideTokenSecret)) Then _oAuthSignature = SharedOAuth.GenerateSignature(_commandUri, CONSUMER_KEY, CONSUMER_SECRET, overrideToken, overrideTokenSecret, "GET", _oAuthTimeStamp, _oAuthNOnce, enumerations.OAuthEnumerations.SignatureTypes.HmacSha1, _oAuth_normalized_url, _oAuth_normalized_params) Else If MasterAccessToken Is Nothing Then _oAuthSignature = SharedOAuth.GenerateSignature(_commandUri, CONSUMER_KEY, CONSUMER_SECRET, String.Empty, String.Empty, "GET", _oAuthTimeStamp, _oAuthNOnce, enumerations.OAuthEnumerations.SignatureTypes.HmacSha1, _oAuth_normalized_url, _oAuth_normalized_params) Else _oAuthSignature = SharedOAuth.GenerateSignature(_commandUri, CONSUMER_KEY, CONSUMER_SECRET, SharedOAuth.UrlEncode(MasterAccessToken.Token), MasterAccessToken.TokenSecret, "GET", _oAuthTimeStamp, _oAuthNOnce, enumerations.OAuthEnumerations.SignatureTypes.HmacSha1, _oAuth_normalized_url, _oAuth_normalized_params) End If End If 'Get a token Dim _sb As New System.Text.StringBuilder With _sb .Append(_oAuth_normalized_url) .Append("?") .Append(_oAuth_normalized_params) .Append("&") .Append("oauth_signature") .Append("=") .Append(SharedOAuth.UrlEncode(_oAuthSignature)) End With Return _sb.ToString End Function Public Function BuildPostHeader(ByVal commandUrl As String) As String Dim _commandUri = New Uri(commandUrl) Dim _oAuthTimeStamp As String = SharedOAuth.GenerateTimeStamp Dim _oAuthNOnce As String = SharedOAuth.GenerateNonce Dim _oAuth_normalized_url As String = String.Empty Dim _oAuth_normalized_params As String = String.Empty Dim _oAuthSignature As String If MasterAccessToken Is Nothing Then _oAuthSignature = SharedOAuth.GenerateSignature(_commandUri, CONSUMER_KEY, CONSUMER_SECRET, String.Empty, String.Empty, "POST", _oAuthTimeStamp, _oAuthNOnce, enumerations.OAuthEnumerations.SignatureTypes.HmacSha1, _oAuth_normalized_url, _oAuth_normalized_params) Else _oAuthSignature = SharedOAuth.GenerateSignature(_commandUri, CONSUMER_KEY, CONSUMER_SECRET, SharedOAuth.UrlEncode(MasterAccessToken.Token), MasterAccessToken.TokenSecret, "POST", _oAuthTimeStamp, _oAuthNOnce, enumerations.OAuthEnumerations.SignatureTypes.HmacSha1, _oAuth_normalized_url, _oAuth_normalized_params) End If Dim _sb As New System.Text.StringBuilder With _sb .Append("Authorization: OAuth oauth_version=""1.0"", ") .AppendFormat("oauth_nonce=""{0}"", ", _oAuthNOnce) .AppendFormat("oauth_timestamp=""{0}"", ", _oAuthTimeStamp) .AppendFormat("oauth_consumer_key=""{0}"", ", CONSUMER_KEY) .AppendFormat("oauth_token=""{0}"", ", MasterAccessToken.Token) .Append("oauth_signature_method=""HMAC-SHA1"", ") .AppendFormat("oauth_signature=""{0}""", _oAuthSignature) End With Return _sb.ToString End Function Public Shared Function PostRequestReturnCollection(ByVal commandUrl As String) As NameValueCollection Dim _nameValCollection As NameValueCollection Dim _request As HttpWebRequest = CType(WebRequest.Create(commandUrl), HttpWebRequest) Using _response As HttpWebResponse = CType(_request.GetResponse, HttpWebResponse) Using _reader As TextReader = New StreamReader(_response.GetResponseStream) _nameValCollection = HttpUtility.ParseQueryString(_reader.ReadToEnd) End Using End Using Return _nameValCollection End Function #End Region End Class 

最后打电话来获取OAuth令牌..

 Public Function RequestApplicationAccess() As TokenParams Dim _oAuthCallbackConfirmed As Boolean Dim _oAuthTokenUrl As String Dim _oauth_Authenticate_Page As String Dim _oAuthtokendataCollection As NameValueCollection Dim _request As HttpWebRequest Dim _oauth_token As String = String.Empty Dim _oauth_token_secret As String = String.Empty Dim _oauth_verifier As String = String.Empty m_CallbackSite = "http://www.previewthebestof.co.uk/_services/googleauth.aspx" 'Generate a signature Dim _RequestUrl As String = "https://www.google.com/accounts/OAuthGetRequestToken" _oAuthTokenUrl = SignCommandUrl(String.Format("{0}?scope={1}&oauth_callback={2}&xoauth_displayname={3}", _RequestUrl, SharedOAuth.UrlEncode(SCOPEURL), SharedOAuth.UrlEncode(m_CallbackSite), SharedOAuth.UrlEncode(APPDISPLAYNAME))) _oAuthtokendataCollection = PostRequestReturnCollection(_oAuthTokenUrl) _oauth_token = _oAuthtokendataCollection.Item("oauth_token") _oauth_token_secret = _oAuthtokendataCollection.Item("oauth_token_secret") If _oAuthtokendataCollection.Count = 3 Then _oAuthCallbackConfirmed = CType(_oAuthtokendataCollection.Item("oauth_callback_confirmed"), Boolean) End If If String.IsNullOrEmpty(_oauth_token) OrElse String.IsNullOrEmpty(_oauth_token_secret) Then Throw New N5.Common.ExceptionManager.N5Exception("Cannot get an authentication token (_oauth_token or _oauth_token_secret is blank)") End If '---------------------------------------------------- 'Write the token to the users profile m_Context.UserObject.SetUserAuthenticationTokens(_oauth_token, String.Empty, String.Empty, String.Empty) '----------------------------------------------------- 'Authorize the token _RequestUrl = "https://www.google.com/accounts/OAuthAuthorizeToken" _oAuthTokenUrl = String.Format("{0}?oauth_token={1}", _RequestUrl, SharedOAuth.UrlEncode(_oauth_token)) _request = CType(WebRequest.Create(_oAuthTokenUrl), HttpWebRequest) Using _response = CType(_request.GetResponse, HttpWebResponse) Using _reader As TextReader = New StreamReader(_response.GetResponseStream) _oauth_Authenticate_Page = _reader.ReadToEnd End Using End Using If Not (_oauth_Authenticate_Page.ToLower.Contains("")) Then Throw New N5.Common.ExceptionManager.N5Exception("AuthToken Respose does not contain a webpage") End If 'Response contains html, which is the youtube authentication page - need to show this to the user 'write to temp file Dim _tempFileName As String = IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.Temp, String.Concat(FilenameUtilities.GetRandomFilename, ".htm")) Using _tempFile As New StreamWriter(_tempFileName) _tempFile.Write(_oauth_Authenticate_Page) End Using 'Load a browser form and navigate to the file just created. Using _browser As New BasePopupBrowser With _browser .WindowState = FormWindowState.Maximized .AutoCloseText = "

OAuth Token Authorised

" .CheckForAutoCloseText = True .NavigateTo(New System.Uri(_tempFileName)) End With End Using 'Clean up the tempfile My.Computer.FileSystem.DeleteFile(_tempFileName) '------------------------------------------------------ 'Check the db for a request_token - did the user press authorise? m_Context.UserObject.RefreshUserAuthenticationTokens() Dim _dv As DataView = m_Context.UserObject.AuthenticationTokensDataView _dv.RowFilter = "TokenName='YouTubeAuthVerifier'" If _dv.Count > 0 Then _oauth_verifier = _dv(0)("Value").ToString End If If String.IsNullOrEmpty(_oauth_verifier) Then 'We didnt get a verification token back, chances are the user pressed reject, Doh! Return Nothing End If '--------------------------------------------------------- 'Now we need to exchange the request token for an access token _RequestUrl = String.Format("https://www.google.com/accounts/OAuthGetAccessToken?oauth_verifier={0}", SharedOAuth.UrlEncode(_oauth_verifier)) _oAuthTokenUrl = SignCommandUrl(_RequestUrl, _oauth_token, _oauth_token_secret) _oAuthtokendataCollection = PostRequestReturnCollection(_oAuthTokenUrl) _oauth_token = _oAuthtokendataCollection.Item("oauth_token") _oauth_token_secret = _oAuthtokendataCollection.Item("oauth_token_secret") m_Context.UserObject.SetUserAuthenticationTokens(String.Empty, String.Empty, _oauth_token, _oauth_token_secret) Return New TokenParams(_oauth_token, _oauth_token_secret) End Function

Wrox书籍专业Twitter开发:.NET 3.5中的示例演示了从C#客户端执行OAuth,并且可以从他们的网站免费下载代码。