【发布时间】:2012-02-24 12:08:33
【问题描述】:
问题:
是否有任何方法(可能是一种解决方法)来支持使用 OAuth 2.0 和 DotNetOpenAuth 4 保护的 WCF 4.0 REST 服务的 PUT 和 DELETE HTTP 动词?我没有使用 WCF Web API 或 WCF Starter Kit。
到目前为止我做了什么:
考虑以下 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,然后将请求 POST 到资源服务器。我实现了this sample 中解释的行为。有趣的是,在我的 ServiceAuthorizationManager 实现之前调用了自定义行为,导致完全相同的错误。
另一种方法是解决 DotNetOpenAuth 本身的问题,但我不知道从哪里开始。
我的想法已经不多了,如果有任何建议,我将不胜感激。
【问题讨论】:
标签: wcf c#-4.0 oauth-2.0 dotnetopenauth