如何发送PUT请求发送到使用OAuth 2.0和DotNetOpenAuth

问题描述:

问题保护的WCF 4.0 REST服务:如何发送PUT请求发送到使用OAuth 2.0和DotNetOpenAuth

是否有任何手段(也许是一个解决方法),以支持PUT和DELETE与HTTP动词使用OAuth 2.0和DotNetOpenAuth 4保护的WCF 4.0 REST服务?我没有使用WCF Web API或WCF入门套件。

我迄今所做的:

考虑以下WCF 4.0 REST服务:

[ServiceContract] 
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] 
public class MyService 
{ 
    [WebGet(UriTemplate = "")] 
    public List<Resource> GetCollection() 
    { 
     /* some implementation */ 
    } 

    [WebInvoke(UriTemplate = "", Method = "POST")] 
    public Resource Create(Resource instance) 
    { 
     /* some implementation */ 
    } 

    [WebGet(UriTemplate = "{id}")] 
    public Resource Get(string id) 
    { 
     /* some implementation */ 
    } 

    [WebInvoke(UriTemplate = "{id}", Method = "PUT")] 
    public Resource Update(string id, Resource instance) 
    { 
     /* some implementation */ 
    } 

    [WebInvoke(UriTemplate = "{id}", Method = "DELETE")] 
    public void Delete(string id) 
    { 
     /* some implementation */ 
    } 
} 

的OAuth 2.0用于控制对服务的访问。它通过使用DotNetOpenAuth的自定义ServiceAuthorizationManager实现来完成所有工作。该实现与DotNetOpenAuth 4.0示例提供的实现几乎完全相同。

对于POST和GET请求它很好。然而,请求失败的PUT和DELETE与错误信息的请求:

'AccessProtectedResourceRequest' messages cannot be received with HTTP verb 'PutRequest' 

客户端代码看起来类似于:

public class ResourceClient 
{ 
    public Resource UpdateResource(Resource resource) 
    { 
     var uri = new Uri(new Uri("http://api.example.com/"), Resource.Format("resources/{0}", resource.Id)); 
     var serializer = new DataContractSerializer(typeof(Resource)); 
     var request = (HttpWebRequest)WebRequest.Create(uri); 
     request.Method = "PUT"; 
     request.ContentType = "application/xml"; 
     ClientBase.AuthorizeRequest(request, Authorization.AccessToken); 

     using (var requestStream = request.GetRequestStream()) 
     { 
      serializer.WriteObject(requestStream, resource); 
     } 

     using (var response = (HttpWebResponse)request.GetResponse()) 
     { 
      using (var responseStream = response.GetResponseStream()) 
      { 
       Debug.Assert(responseStream != null, "responseStream != null"); 
       return (Resource)serializer.ReadObject(responseStream); 
      } 
     } 
    } 
} 

another question答案似乎这是可能DotNetOpenAuth中的一个缺陷。查看OAuth 2.0规范,我没有看到禁止在访问资源时使用PUT或DELETE http动词的任何内容。也就是说,我不是OAuth 2.0的专家,也不是我的心。

所以我认为我会“聪明”,并使用“X-HTTP-Method-Override”指定PUT,然后将请求发布到资源服务器。我按照this sample中的解释执行了该行为。有趣的是,自定义行为在我的ServiceAuthorizationManager实现之前被调用,导致了完全相同的错误。

另一种方法是解决DotNetOpenAuth本身的问题,但我不知道从哪里开始。

我用尽了想法,我会很感激任何建议。

这个跟踪Issue #62。如果您希望将其移植到您的版本而无需等待下一个版本发布,您可以浏览该修补程序。

+0

下一个发布计划何时计划? – bloudraak 2012-02-24 07:00:23

+0

您可以在这里查看各种功能发布计划的最佳预测日期:https://github.com/AArnott/dotnetopenid/issues/milestones – 2012-02-24 14:11:11