我在您的代码中看到了几个问题。首先回答您的直接问题,Google 在回访时不记得您的原因是因为您每次登录时都会将随机 GUID 作为您的领域的一部分传入。症状实际上比您意识到的要严重得多。不仅 Google 在回访时提示用户,您的网站在回访时根本不会识别用户,因为 Google 会在每次访问 时为他们提供一个新的声明标识符。
解决方法是您应该为每个登录请求使用完全相同的 Realm:
Realm realm = "http://www.yoursite.com/";
var req = openid.CreateRequest(discoveryUri, realm, URIbuilder.Uri );
或者我个人最喜欢的:
var req = openid.CreateRequest(discoveryUri, Realm.AutoDetect, URIbuilder.Uri );
Realm.AutoDetect
除非您的网站可通过 HTTP 和 HTTPS 访问,否则您将可以使用,在这种情况下,您需要将其锁定为其中一种或另一种,以便 Google 将您的网站识别为始终相同。
您还必须记住,作为第三个参数传入的 returnTo URLCreateRequest
必须始终基于领域。因此,如果您的领域是 HTTPS,那么您的 returnTo 参数也必须如此。
我还想指出,您似乎有一些 GUID 代码和复杂的 URL 操作,试图确保您接受的每个 OpenID 响应都来自您发出的请求。我不确定您为什么首先尝试这样做,尽管肯定有正当的理由。你这样做的方式是不安全的,可以被规避。我建议您删除所有这些代码,以便将其添加到您的 web.config 文件中:
<dotNetOpenAuth>
<openid>
<relyingParty>
<security rejectUnsolicitedAssertions="true" />
</relyingParty>
</openid>
</dotNetOpenAuth>
该库支持要求所有响应都来自您的内置请求,并且它这样做是安全的,因此我之前提到的安全漏洞是不可能的。
但是,如果您只是尝试应用此限制以便知道它来自 Google,我是否建议您不要拒绝未经请求的断言,而是IAuthenticationResponse.Provider.Uri
在收到响应时检查该属性并验证它来自 Google OP Endpoint ? 然后,如果 Google 曾经支持发送未经请求的断言,它将在您的网站上运行,并且最终您的安全门正是您想要的位置。