【问题标题】:DotNetOpenAuth: This message has already been processed. This could indicate a replay attack in progressDotNetOpenAuth:此消息已被处理。这可能表明正在进行重放攻击
【发布时间】:2011-04-03 00:23:36
【问题描述】:

我正在尝试使用 DotNetOpenAuth 的 RelyingPartyLogic 示例保护我的 WCF 服务。我让消费者​​进行身份验证工作,但是当我针对 Api 发出授权请求时,我收到错误 此消息已被处理。这可能表明正在进行重放攻击。” 使用堆栈跟踪:

在 DotNetOpenAuth.Messaging.Bindings.StandardReplayProtectionBindingElement.ProcessIncomingMessage(IProtocolMessage 消息)在 DotNetOpenAuth.Messaging.Channel.ProcessIncomingMessage(IProtocolMessage 消息)在 DotNetOpenAuth.Messaging.Channel.ReadFromRequest(HttpRequestInfo httpRequest) 在 DotNetOpenAuth.Messaging.Channel.TryReadFromRequest[TRequest](HttpRequestInfo httpRequest,TRequest&请求)在 DotNetOpenAuth.OAuth.ServiceProvider.ReadProtectedResourceAuthorization(HttpRequestInfo 请求)在 DotNetOpenAuth.OAuth.ServiceProvider.ReadProtectedResourceAuthorization(HttpRequestMessageProperty 请求,Uri requestUri) 在 RelyingPartyLogic.OAuthAuthorizationManager.CheckAccessCore(OperationContext 操作上下文)在 D:\Code\Nodeler\Nodeler.RelyingPartyLogic\OAuthAuthorizationManager.cs:line 44 在 System.ServiceModel.ServiceAuthorizationManager.CheckAccess(OperationContext 操作上下文)在 System.ServiceModel.ServiceAuthorizationManager.CheckAccess(OperationContext 操作上下文、消息和消息)
在 System.ServiceModel.Dispatcher.AuthorizationBehavior.Authorize(MessageRpc& rpc)

轨迹如下:

2011-04-02 19:16:12,414 (GMT-5) [16] 调试 DotNetOpenAuth.Messaging.Channel - 发送消息:AuthorizedTokenResponse 2011-04-02 19:16:15,362 (GMT-5) [16] 信息 DotNetOpenAuth.Messaging.Channel - 扫描传入的请求 留言: http://localhost:16468/Api/HelloWorld?oauth_token=7ix8k5NXN4NE1EXQWlHYE6klk7A%3D&oauth_consumer_key=f9fa91faa048434a86ab95681e9f732d&oauth_nonce=N7SPWJPl&oauth_signature_method=HMAC-SHA1&oauth_signature=HyNQvfk2OrP%2FnMFjLJdNih4c8N8%3D&oauth_version=1.0&oauth_timestamp=1301789775 2011-04-02 19:16:15,376 (GMT-5) [16] 调试 DotNetOpenAuth.Messaging.Channel - 收到的传入请求:AccessProtectedResourceRequest 2011-04-02 19:16:15,377 (GMT-5) [16] 信息 DotNetOpenAuth.Messaging.Channel - 处理传入的 AccessProtectedResourceRequest (1.0) 消息:oauth_token: 7ix8k5NXN4NE1EXQWlHYE6klk7A= oauth_consumer_key: f9fa91faa048434a86ab95681e9f732d oauth_nonce: N7SPWJPl oauth_signature_method:HMAC-SHA1 oauth_signature: HyNQvfk2OrP/nMFjLJdNih4c8N8= oauth_version:1.0 oauth_timestamp: 1301789775

2011-04-02 19:16:15,377 (GMT-5) [16] 调试 DotNetOpenAuth.Messaging.Bindings - 验证传入 AccessProtectedResourceRequest 消息 签名: HyNQvfk2OrP/nMFjLJdNih4c8N8= 2011-04-02 19:16:15,377 (GMT-5) [16] 调试 DotNetOpenAuth.Messaging.Channel - 将秘密应用于消息以准备签名或签名 确认。 2011-04-02 19:16:15,423 (GMT-5) [16] 调试 DotNetOpenAuth.Messaging.Bindings - 构造的签名基本字符串: GET&HTTP%3A%2F%2Flocalhost%3A16468%2FApi%2FHelloWorld&oauth_consumer_key%3Df9fa91faa048434a86ab95681e9f732d%26oauth_nonce%3DN7SPWJPl%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1301789775%26oauth_token%3D7ix8k5NXN4NE1EXQWlHYE6klk7A%253D%26oauth_version%3D1.0 2011-04-02 19:16:15,424 (GMT-5) [16] 调试 DotNetOpenAuth.Messaging.Bindings - 绑定元素 DotNetOpenAuth.OAuth.ChannelElements.SigningBindingElementChain 应用于消息。 2011-04-02 19:16:15,424 (GMT-5) [16] 调试 DotNetOpenAuth.Messaging.Bindings - 绑定元素 DotNetOpenAuth.Messaging.Bindings.StandardExpirationBindingElement 应用于消息。 2011-04-02 19:16:15,424 (GMT-5) [16] 调试 DotNetOpenAuth.Messaging.Bindings - 绑定元素 DotNetOpenAuth.Messaging.Bindings.StandardReplayProtectionBindingElement 应用于消息。 2011-04-02 19:16:15,424 (GMT-5) [16] 调试 DotNetOpenAuth.Messaging.Bindings - 绑定元素 DotNetOpenAuth.OAuth.ChannelElements.OAuthHttpMethodBindingElement 不适用于消息。 2011-04-02 19:16:15,528 (GMT-5) [16] 调试 DotNetOpenAuth.Messaging.Bindings - 绑定元素 DotNetOpenAuth.OAuth.ChannelElements.TokenHandlingBindingElement 不适用于消息。 2011-04-02 19:16:15,528 (GMT-5) [16] 调试 DotNetOpenAuth.Messaging.Channel - 绑定元素处理后, 已收到 AccessProtectedResourceRequest (1.0) 消息是:oauth_token: 7ix8k5NXN4NE1EXQWlHYE6klk7A= oauth_consumer_key: f9fa91faa048434a86ab95681e9f732d oauth_nonce: N7SPWJPl oauth_signature_method:HMAC-SHA1 oauth_signature: HyNQvfk2OrP/nMFjLJdNih4c8N8= oauth_version:1.0 oauth_timestamp: 1301789775

2011-04-02 19:16:15,816 (GMT-5) [5] 信息 DotNetOpenAuth.Messaging.Channel - 扫描传入的消息请求: http://localhost:16468/Api/HelloWorld?oauth_token=7ix8k5NXN4NE1EXQWlHYE6klk7A%3D&oauth_consumer_key=f9fa91faa048434a86ab95681e9f732d&oauth_nonce=N7SPWJPl&oauth_signature_method=HMAC-SHA1&oauth_signature=HyNQvfk2OrP%2FnMFjLJdNih4c8N8%3D&oauth_version=1.0&oauth_timestamp=1301789775 2011-04-02 19:16:15,826 (GMT-5) [5] 调试 DotNetOpenAuth.Messaging.Channel - 收到的传入请求:AccessProtectedResourceRequest 2011-04-02 19:16:15,826 (GMT-5) [5] 信息 DotNetOpenAuth.Messaging.Channel - 处理传入的 AccessProtectedResourceRequest (1.0) 消息:oauth_token: 7ix8k5NXN4NE1EXQWlHYE6klk7A= oauth_consumer_key: f9fa91faa048434a86ab95681e9f732d oauth_nonce: N7SPWJPl oauth_signature_method:HMAC-SHA1 oauth_signature: HyNQvfk2OrP/nMFjLJdNih4c8N8= oauth_version:1.0 oauth_timestamp: 1301789775

2011-04-02 19:16:15,826 (GMT-5) [5] 调试 DotNetOpenAuth.Messaging.Bindings - 验证传入 AccessProtectedResourceRequest 消息 签名: HyNQvfk2OrP/nMFjLJdNih4c8N8= 2011-04-02 19:16:15,826 (GMT-5) [5] 调试 DotNetOpenAuth.Messaging.Channel - 将秘密应用于消息以准备签名或签名 确认。 2011-04-02 19:16:15,853 (GMT-5) [5] 调试 DotNetOpenAuth.Messaging.Bindings - 构造的签名基本字符串: GET&HTTP%3A%2F%2Flocalhost%3A16468%2FApi%2FHelloWorld&oauth_consumer_key%3Df9fa91faa048434a86ab95681e9f732d%26oauth_nonce%3DN7SPWJPl%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1301789775%26oauth_token%3D7ix8k5NXN4NE1EXQWlHYE6klk7A%253D%26oauth_version%3D1.0 2011-04-02 19:16:15,853 (GMT-5) [5] 调试 DotNetOpenAuth.Messaging.Bindings - 绑定元素 DotNetOpenAuth.OAuth.ChannelElements.SigningBindingElementChain 应用于消息。 2011-04-02 19:16:15,853 (GMT-5) [5] 调试 DotNetOpenAuth.Messaging.Bindings - 绑定元素 DotNetOpenAuth.Messaging.Bindings.StandardExpirationBindingElement 应用于消息。 2011-04-02 19:16:15,853 (GMT-5) [5] 错误 DotNetOpenAuth.OpenId - 重放的随机数 检测到(N7SPWJPl 04/03/2011 00:16:15)。拒绝消息。

更新:经过进一步挖掘,问题是 StandardExpirationBindingElement 被应用了两次,这导致 Nonce 被多次添加到 NonceMemoryStore 中。我一生都无法弄清楚为什么会这样。

【问题讨论】:

标签: c# dotnetopenauth


【解决方案1】:

我找到了根本问题。 OAuthAuthenticationModule 也在处理请求。更新 IsOAuthControllerRequest 函数修复了它。我不确定这是否是一个适当的修复,但在这一点上我继续前进。我不确定这只是自然还是 OAuth 还是 DotNetOpenAuth 本身,但多年来我从未对编程感到如此沮丧。

private bool IsOAuthControllerRequest()
{
    return string.Equals(this.application.Context.Request.Url.AbsolutePath, "/OAuth.ashx", StringComparison.OrdinalIgnoreCase)
        || this.application.Context.Request.Url.AbsolutePath.ToLower().StartsWith("/api/");
}

【讨论】:

  • OAuth 要求每个签名请求只接收一次,以防止重放攻击。您关于它正在由两个模块处理的结论是正确的。默认情况下,您所基于的 DotNetOpenAuth 项目模板对每个传入请求应用 OAuth 安全检查。由于您将它应用于 WCF 传入消息,因此它发生了两次。禁用一个或另一个是正确的解决方法(选择正确的取决于场景)。
  • 您对IsOAuthControllerRequest 的修改不正确。现在你的方法在撒谎。您可能应该更改调用此方法的代码,以选择退出其他情况(您的 /api/ 路径)。或者,只需完全禁用 OAuthAuthenticationModule,因为您的 WCF API 是独立保护的。
  • 好的,我现在明白了。没有意识到他们在做基本相同的事情。我删除了 OAuthAuthorizationManager 并更新了 web.config 以使用 FormsAuthentication “保护” Api,它现在可以正常工作而无需解决。如果您想将其写为答案,我可以接受它是正确的。 ;) 感谢您的帮助。
【解决方案2】:

项目模板附带的OAuthAuthenticationModule 已经“消耗”了 OAuth 授权请求中包含的随机数。当您的OAuthAuthorizationManager 也被应用时,它会尝试第二次消耗随机数,因此被检测为重放攻击。第一个模块在 ASP.NET 级别授权任何传入的 HTTP 请求,而第二个模块专门授权传入的 WCF 请求(在 ASP.NET 验证之上),以便应用 WCF 样式的授权。应该只应用一个——一个或另一个,但不能同时应用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-16
    • 1970-01-01
    相关资源
    最近更新 更多