4

WCF 4.0 是否对 WCF REST Starter Kit 的 RequestInterceptor 有一个模拟类/模块/任何东西?

4

3 回答 3

7

我回来更新了。

我碰巧重视代码的简单性,在成功解决了这个问题之后,我不能说我比 Query String 方法更喜欢它。将单个调用放入调用 AuthN 方法和 AuthZ 方法的每个服务端点似乎比某些人想象的要容易。

无论如何,足够多的意见......关于解决方案。该解决方案就在我们对 Stackoverflow 的关注范围内,但在我们的上下文中没有得到很好的描述......所以我将在此处找到的示例代码归功于“user634119”: OperationContext 中的标题

首先,我们需要在 web.config 文件中添加一个 serviceBehavior:

<behaviors>
  <serviceBehaviors>
    <behavior>
      <serviceAuthenticationManager serviceAuthenticationManagerType="WCF.BasicAuthorization, WCF"></serviceAuthenticationManager>
      <serviceAuthorization impersonateCallerForAllOperations="false" principalPermissionMode="Custom" serviceAuthorizationManagerType="WCF.BasicAuthentication, WCF">
      </serviceAuthorization>
    </behavior>
  </serviceBehaviors>
</behaviors>

接下来创建一个类(在上面的 serviceBehaviors 块中引用称为 BasicAuthorization):

//Authorize the call against the URI resource being requested...
public class BasicAuthorization : ServiceAuthorizationManager
{
    public override bool CheckAccess(OperationContext operationContext, 
    ref Message message)
    {
        //some code
    }
}

接下来创建一个 Authentication 类:

// Authenticate the header signature as described in my previous post
public class BasicAuthentication : ServiceAuthenticationManager
{
    public override ReadOnlyCollection<IAuthorizationPolicy> Authenticate(
        ReadOnlyCollection<IAuthorizationPolicy> authPolicy, Uri listenUri, 
        ref Message message)
    {
        //some code
    }
}

In the Authenticate method, use HttpRequestMessageProperty to pull the request header details out and perform the same 3 steps described in my first reply.

于 2011-06-29T14:27:04.017 回答
4

Eduardo,您问:@carlosfigueira:我可以用它来实现身份验证子系统吗?

我正在解决同样的问题,并且至少为您提供了一种解决方案(如下所述),以及即将推出的基于授权标头的解决方案(我相信这是您正在考虑“拦截”的解决方案)。

保护基于 WCF 4 REST WebHttp 编程模型的端点的最简单方法是:

  1. 向每个客户端颁发一个共享密钥和一个 API 密钥以用作凭据。API 密钥实际上与用户名相同。
  2. 通过 SSL 运行所有端点以确保您始终拥有通道/消息/数据安全性
  3. 要求客户端使用共享密钥生成包含时间戳及其 API 密钥的 HMAC-SHA1(或等效)哈希签名字符串。
  4. 要求客户端在每个请求中将所有这 3 个作为查询字符串参数传递:
    • 签名
    • 时间戳
    • API 密钥
    • 示例:https ://127.0.0.1/RestEndpoint? Sig= {sigString}&ApiKey={apiKey}&TimeStamp={timeStamp}&所有其他参数在这里...
  5. 在您的服务端,实现一个接受所有 3 个字符串的 Authentication 方法,然后:
    • 查找 API 密钥并返回在数据库或其他地方拥有的客户端共享密钥。
    • 将时间戳与 DateTime.Now 进行比较,以确保请求不超过 15 分钟,以抵御重放攻击。
    • 使用这 3 个字符串,重新创建签名字符串并将您的字符串与客户端传入的字符串进行比较。
    • 如果它们匹配,则请求者是真实的。

现在,更好的方法是使用 HTTP 授权请求标头来存储这 3 个字符串,并让一个全局拦截器进程监视所有请求。这将防止没有身份验证块的暴露端点的可能性(好吧,至少它不太可能)。

使用查询字符串来携带所有这些信息的问题是查询字符串的最大长度为 2k(因客户端/浏览器而异),并且在调试时查询字符串变得非常难以阅读......但只要习惯它。

有些人认为更复杂的方法是使用 STS 模型,您需要客户端将这 3 个身份验证字符串传递给安全令牌服务端点。响应消息将传回一个会话令牌,客户端将在每次调用时传入该令牌以代替 3 个字符串。确实,对于客户端而言,不需要在每次调用时生成 HMAC 哈希签名,但服务器端仍必须对令牌进行身份验证,并且会话概念会破坏干净的 RESTful 无状态行为。

我将尽我所能发布实现查询字符串和 auth 标头方法的代码块。

于 2011-06-23T13:29:09.740 回答
3

没有任何东西可以将 1-1 映射到它,但是您可以使用 WCF 核心中的 IDispatchMessageInspector 来实现 RequestInspector 可以执行的大多数方案。http://blogs.msdn.com/b/carlosfigueira/archive/2011/04/19/wcf-extensibility-message-inspectors.aspx上的帖子包含有关消息检查器的一些详细信息。

于 2011-05-16T22:15:09.917 回答