无法使用DotNetOpenAuth ServiceProvider使用PLAINTEXT签名

我正在使用DotNetOpenAuth (NuGet包DotNetOpenAuth.OAuth.ServiceProvider, version = 4.1.4.12333 )构build一个OAuth 1.0(a)授权服务器。 服务器托pipe在ASP.NET应用程序中,但与问题无关。

我的ServiceProvider是这样configuration的:

 private ServiceProvider GetServiceProvider() { var baseUri = "http://myauth.com"; return new ServiceProvider( new ServiceProviderDescription { UserAuthorizationEndpoint = new MessageReceivingEndpoint( new Uri(baseUri + "/get_request_token"), HttpDeliveryMethods.GetRequest ), RequestTokenEndpoint = new MessageReceivingEndpoint( new Uri(baseUri + "/authorize"), HttpDeliveryMethods.PostRequest ), AccessTokenEndpoint = new MessageReceivingEndpoint( new Uri(baseUri + "/get_token"), HttpDeliveryMethods.PostRequest ), ProtocolVersion = ProtocolVersion.V10a, TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new PlaintextSigningBindingElement(), new HmacSha1SigningBindingElement(), }, }, tokenManager, new OAuthServiceProviderMessageFactory(tokenManager) ); } 

我的get_request_token端点的相关部分如下所示:

 var serviceProvider = GetServiceProvider(); var tokenRequest = serviceProvider.ReadTokenRequest(); 

现在当一个消费者发送以下请求到这个端点:

 GET /get_request_token?oauth_nonce=C5657420BCE5F3224914304376B5334696B09B7FFC17C105A7F9629A008869DC&oauth_timestamp=1356006599&oauth_consumer_key=sampleconsumer&oauth_signature_method=plaintext&oauth_signature=samplesecret%26&oauth_version=1.0&oauth_callback=http%3a%2f%2flocalhost%3a30103%2fCustomOAuth1 HTTP/1.1 Host: localhost:8180 Connection: close 

(为清楚起见,分解):

 oauth_nonce=C5657420BCE5F3224914304376B5334696B09B7FFC17C105A7F9629A008869DC oauth_timestamp=1356006599 oauth_consumer_key=sampleconsumer oauth_signature_method=plaintext oauth_signature=samplesecret%26 oauth_version=1.0 oauth_callback=http%3a%2f%2flocalhost%3a30103%2fCustomOAuth1 

serviceProvider.ReadTokenRequest()方法抛出一个exception:

 The UnauthorizedTokenRequest message required protections {All} but the channel could only apply {Expiration, ReplayProtection}. at DotNetOpenAuth.Messaging.Channel.ProcessIncomingMessage(IProtocolMessage message) at DotNetOpenAuth.Messaging.Channel.ReadFromRequest(HttpRequestBase httpRequest) at DotNetOpenAuth.Messaging.Channel.TryReadFromRequest[TRequest](HttpRequestBase httpRequest, TRequest& request) at DotNetOpenAuth.OAuth.ServiceProvider.ReadTokenRequest(HttpRequestBase request) at DotNetOpenAuth.OAuth.ServiceProvider.ReadTokenRequest() at OAuthServers.OAuth1.Services.OAuth1Service.Any(GetRequestTokenRequest request) at lambda_method(Closure , Object , Object ) at ServiceStack.ServiceHost.ServiceRunner`1.Execute(IRequestContext requestContext, Object instance, TRequest request) 

另一方面,如果客户端发送以下请求:

 GET /get_request_token?oauth_callback=http%3a%2f%2flocalhost%3a65271%2foauth1%2fHandleAccessToken&oauth_consumer_key=sampleconsumer&oauth_nonce=rGFvxlWm&oauth_signature_method=HMAC-SHA1&oauth_signature=HV%2f5Vq%2b0cF3NrtiISE9k4jmgCrY%3d&oauth_version=1.0&oauth_timestamp=1356007830 HTTP/1.1 Host: localhost:8180 Connection: close 

(为清楚起见,分解):

 oauth_callback=http%3a%2f%2flocalhost%3a65271%2foauth1%2fHandleAccessToken oauth_consumer_key=sampleconsumer oauth_nonce=rGFvxlWm oauth_signature_method=HMAC-SHA1 oauth_signature=HV%2f5Vq%2b0cF3NrtiISE9k4jmgCrY%3d oauth_version=1.0 oauth_timestamp=1356007830 

它成功了。

正如您所看到的,这两个请求之间的唯一区别是正在使用的oauth_signature_method 。 在第一种情况下使用PLAINTEXT ,而在第二种HMAC-SHA1

是否有可能让DotNetOpenAuth接受请求标记端点的PLAINTEXT签名方法以及GET谓词(即使OAuth 1.0(a) specificationbuild议将POST用于此端点)? 有没有一些configuration选项,可以放松这个要求在服务器上?

目前修改客户端不是我的select。

OAuth身份validation分三步完成:

  1. 消费者获得未经授权的请求令牌。

  2. 用户授权请求令牌。

  3. 消费者交换访问令牌的请求令牌。

所以这里是这样的:

 public class InMemoryTokenManager : IConsumerTokenManager, IOpenIdOAuthTokenManager { private Dictionary<string, string> tokensAndSecrets = new Dictionary<string, string>(); public InMemoryTokenManager(string consumerKey, string consumerSecret) { if (String.IsNullOrEmpty(consumerKey)) { throw new ArgumentNullException("consumerKey"); } this.ConsumerKey = consumerKey; this.ConsumerSecret = consumerSecret; } public string ConsumerKey { get; private set; } public string ConsumerSecret { get; private set; } #region ITokenManager Members public string GetConsumerSecret(string consumerKey) { if (consumerKey == this.ConsumerKey) { return this.ConsumerSecret; } else { throw new ArgumentException("Unrecognized consumer key.", "consumerKey"); } } public string GetTokenSecret(string token) { return this.tokensAndSecrets[token]; } public void StoreNewRequestToken(UnauthorizedTokenRequest request, ITokenSecretContainingMessage response) { this.tokensAndSecrets[response.Token] = response.TokenSecret; } public void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret) { this.tokensAndSecrets.Remove(requestToken); this.tokensAndSecrets[accessToken] = accessTokenSecret; } /// <summary> /// Classifies a token as a request token or an access token. /// </summary> /// <param name="token">The token to classify.</param> /// <returns>Request or Access token, or invalid if the token is not recognized.</returns> public TokenType GetTokenType(string token) { throw new NotImplementedException(); } #endregion #region IOpenIdOAuthTokenManager Members public void StoreOpenIdAuthorizedRequestToken(string consumerKey, AuthorizationApprovedResponse authorization) { this.tokensAndSecrets[authorization.RequestToken] = string.Empty; } #endregion } 

以下代码块可能会帮助您生成纯文本签名

 public static string GetSignature(OAuthSignatureMethod signatureMethod, AuthSignatureTreatment signatureTreatment, string signatureBase, string consumerSecret, string tokenSecret) { if (tokenSecret.IsNullOrBlank()) { tokenSecret = String.Empty; } consumerSecret = UrlEncodeRelaxed(consumerSecret); tokenSecret = UrlEncodeRelaxed(tokenSecret); string signature; switch (signatureMethod) { case OAuthSignatureMethod.HmacSha1: { var crypto = new HMACSHA1(); var key = "{0}&{1}".FormatWith(consumerSecret, tokenSecret); crypto.Key = _encoding.GetBytes(key); signature = signatureBase.HashWith(crypto); break; } case OAuthSignatureMethod.PlainText: { signature = "{0}&{1}".FormatWith(consumerSecret, tokenSecret); break; } default: throw new NotImplementedException("Only HMAC-SHA1 is currently supported."); } var result = signatureTreatment == OAuthSignatureTreatment.Escaped ? UrlEncodeRelaxed(signature) : signature; return result; }