我正在实施DotNetOpenAuth(OpenID)和Forms Authentication作为我正在构建的网站的身份验证机制。但是,我对我提出的解决方案的部分内容并不满意,尽管我应该和你们一起检查它是如何完成的。
我已将表单身份验证loginUrl
设置为login.aspx
。这是登录页面背后的代码:
public partial class Login : DataAccessPage {
protected void Page_Load(object sender, EventArgs e) {
if (Request.QueryString["dnoa.receiver"] != "openId") {
openId.ReturnToUrl = Request.Url.ToString();
openId.LogOn();
}
}
protected void openId_LoggedIn(object sender, DotNetOpenAuth.OpenId.RelyingParty.OpenIdEventArgs e) {
var fetch = e.Response.GetExtension();
if (fetch != null) {
string eMail = fetch.GetAttributeValue(WellKnownAttributes.Contact.Email);
string name = fetch.GetAttributeValue(WellKnownAttributes.Name.FullName);
var usr = db.Users.SingleOrDefault(u => u.EMailAddress == eMail);
if (usr != null) {
// update the name in db if it has been changed on Google
if (usr.Name != name) {
usr.Name = name;
db.SaveChanges();
}
FormsAuthentication.RedirectFromLoginPage(usr.UserId.ToString(), false);
}
}
}
protected void openId_LoggingIn(object sender, DotNetOpenAuth.OpenId.RelyingParty.OpenIdEventArgs e) {
var fetch = new FetchRequest();
fetch.Attributes.AddRequired(WellKnownAttributes.Contact.Email);
fetch.Attributes.AddRequired(WellKnownAttributes.Name.FullName);
e.Request.AddExtension(fetch);
}
}
因此,当用户未登录时,会直接将其发送到login.aspx页面,该页面会直接尝试使用针对Google的OpenID登录。它会检查用户是否在允许的用户列表中,然后FormsAuthentication.RedirectFromLoginPage()
。
到目前为止没有问题...... 问题在于退出。理想情况下,我希望登录直接与Google帐户登录状态相关联。如果用户已登录Google,则他/她也应该在我的网站上登录。当用户退出Google时,他/她应该从我的网站注销。 但是,由于使用了表单身份验证,因此即使用户退出Google,故障单也会持续一段时间。
任何人对如何解决这个问题都有任何想法?
提前致谢!
答案 0 :(得分:6)
首先回答您的问题:OpenID 不提供了将Google会话的长度与您自己的会话相关联的方法。您可以做的最好的事情是提供一个仅限会话(非持久性)的cookie,因为它看起来您已经在做,所以如果用户退出Google并关闭他们的浏览器,他们也会被注销到您的网站。这是一个OpenID协议限制 - 没有其他OpenID库可以修复它。
现在谈到你没有要求的问题,但我不能忽视它 - 你的实施是非常不安全的。您隐含地信任AX fetch响应扩展,允许用户控制的任何电子邮件地址是登录的用户。这意味着任何人都可以轻松地设置一个关于电子邮件地址的OpenID提供商并欺骗用户的身份。您可能错误地认为仅仅是因为您将用户重定向到Google,这意味着所有回复都来自Google(假设您信任Google)。仅仅因为您向Google发送请求,并不意味着某人无法从他们自己的非Google服务器中综合回复。
有两种方法可以解决您的安全问题。首先(最好)不要使用电子邮件地址作为您的用户名。请改用IAuthenticationResponse.ClaimedIdentifier
作为用户名。这就是它的用途,并将保护您免受许多不同的攻击。不太可取的解决方案是继续使用电子邮件,但要确认在您信任该电子邮件之前,响应实际上来自Google。您可以通过IAuthenticationResponse.Provider.Uri
属性执行此操作,并验证它是您期望和信任的属性。