DotNetOpenAuth:消息签名不正确
Posted
技术标签:
【中文标题】DotNetOpenAuth:消息签名不正确【英文标题】:DotNetOpenAuth: Message signature was incorrect 【发布时间】:2011-01-31 02:59:49 【问题描述】:我在尝试使用 MyOpenID 和 Yahoo 进行身份验证时收到“消息签名不正确”异常。
我使用的几乎都是 DotNetOpenAuth 3.4.2 附带的 ASP.NET MVC 示例代码
public ActionResult Authenticate(string openid)
var openIdRelyingParty = new OpenIdRelyingParty();
var authenticationResponse = openIdRelyingParty.GetResponse();
if (authenticationResponse == null)
// Stage 2: User submitting identifier
Identifier identifier;
if (Identifier.TryParse(openid, out identifier))
var realm = new Realm(Request.Url.Root() + "openid");
var authenticationRequest = openIdRelyingParty.CreateRequest(openid, realm);
authenticationRequest.RedirectToProvider();
else
return RedirectToAction("login", "home");
else
// Stage 3: OpenID provider sending assertion response
switch (authenticationResponse.Status)
case AuthenticationStatus.Authenticated:
// TODO
case AuthenticationStatus.Failed:
throw authenticationResponse.Exception;
return new EmptyResult();
与 Google、AOL 和其他公司合作良好。但是,Yahoo 和 MyOpenID 属于 AuthenticationStatus.Failed 情况,但有以下例外:
DotNetOpenAuth.Messaging.Bindings.InvalidSignatureException: Message signature was incorrect.
at DotNetOpenAuth.OpenId.ChannelElements.SigningBindingElement.ProcessIncomingMessage(IProtocolMessage message) in c:\Users\andarno\git\dotnetopenid\src\DotNetOpenAuth\OpenId\ChannelElements\SigningBindingElement.cs:line 139
at DotNetOpenAuth.Messaging.Channel.ProcessIncomingMessage(IProtocolMessage message) in c:\Users\andarno\git\dotnetopenid\src\DotNetOpenAuth\Messaging\Channel.cs:line 992
at DotNetOpenAuth.OpenId.ChannelElements.OpenIdChannel.ProcessIncomingMessage(IProtocolMessage message) in c:\Users\andarno\git\dotnetopenid\src\DotNetOpenAuth\OpenId\ChannelElements\OpenIdChannel.cs:line 172
at DotNetOpenAuth.Messaging.Channel.ReadFromRequest(HttpRequestInfo httpRequest) in c:\Users\andarno\git\dotnetopenid\src\DotNetOpenAuth\Messaging\Channel.cs:line 386
at DotNetOpenAuth.OpenId.RelyingParty.OpenIdRelyingParty.GetResponse(HttpRequestInfo httpRequestInfo) in c:\Users\andarno\git\dotnetopenid\src\DotNetOpenAuth\OpenId\RelyingParty\OpenIdRelyingParty.cs:line 540
看来其他人也有同样的问题:http://trac.dotnetopenauth.net:8000/ticket/172
有人有解决方法吗?
【问题讨论】:
在执行此测试时,我使用 DotNetOpenAuth 测试台也遇到了同样的异常:test-id.org/RP/POSTAssertion.aspx 这看起来像一个类似的问题:***.com/questions/2508327/… 【参考方案1】:原来这是在网络农场环境中使用 DotNetOpenAuth 时出现的问题。
当您创建 OpenIdRelyingParty 时,请确保在构造函数中传递 null。
这会将您的网站置于 OpenID 无状态或“哑”模式。用户登录的速度稍慢(如果您注意到的话),但您不必编写 IRelyingPartyApplicationStore 以允许 DotNetOpenAuth 在您的农场中工作;
var openIdRelyingParty = new OpenIdRelyingParty(null);
【讨论】:
我怀疑这可能会引入安全漏洞。有人可以确认吗?【参考方案2】:所有这些讨论都围绕以下问题:
依赖方 (RP) 如何确保包含身份验证令牌的请求来自他将用户请求转发到的 OP(OpenId 提供者)?
以下步骤解释了它是如何发生的
-
用户请求来自回复方 (RP),在我们的案例中是我们的网站
应用程序将该用户对应的唯一签名存储在本地签名存储(LSS)中,然后将该签名嵌入到消息中,并将该消息转发给 OpenId Provider(OP)
用户键入他的凭据,OP 对其消息进行身份验证,然后将该消息(其中仍嵌入签名)转发回 RP
RP 将嵌入在消息中的签名与 LSS 中的签名进行比较,如果它们匹配 RP,则对用户进行身份验证
如果 LSS 在消息从 OP 返回之前消失(不知何故),则 RP 无法将签名与之进行比较,因此它无法验证用户并抛出错误:消息签名不正确。
LSS 怎么会消失:
-
ASP.net 刷新应用程序池
IIS 已重新启动
在网络场中,消息由托管在不同服务器上的应用程序提供服务
这个问题的两个解决方案:
RP 在哑模式下运行
a. 它不在本地存储和签名,因此不使用签名比较来确保消息来自他将用户转发到的 OP 以进行身份验证
b. 相反,一旦 RP 收到来自 OP 的身份验证消息,它会将消息发送回 OP,并要求他检查他是否是验证此用户的人并且是消息。如果 OP 回复是,我是此消息的发起者并且我已创建此消息,则用户已通过 RP 身份验证
实现您自己的不会消失的持久性存储,无论 ASP.net 对进程做什么,就像使用 SQL 存储会话状态一样。
【讨论】:
【参考方案3】:我们通过实现 IRelyingPartyApplicationStore
(在较新版本的 DotNetOpenAuth 中为IOpenIdApplicationStore
)并将商店类名称添加到 .config 来解决此问题
<dotNetOpenAuth>
<openid ...>
<relyingParty>
...
<store type="some.name.space.MyRelyingPartyApplicationStore, some.assembly"/>
</relyingParty>
</openid>
...
</dotNetOpenAuth>
接口是由另外两个接口组成的,总共有五个成员。
/// <summary>
/// A hybrid of the store interfaces that an OpenID Provider must implement, and
/// an OpenID Relying Party may implement to operate in stateful (smart) mode.
/// </summary>
public interface IOpenIdApplicationStore : ICryptoKeyStore, INonceStore
我们使用哑模式作为启动运行的快速解决方案,但最终您可能会想要这样的东西。
【讨论】:
以上是关于DotNetOpenAuth:消息签名不正确的主要内容,如果未能解决你的问题,请参考以下文章
字段“签名”的值不正确:值为 662655099,但应为 67324752
如何从 R 中的散列消息和签名中正确恢复 ECDSA 公钥 ||小号 || V格式?