DotNetOpenAuth和FormsAuthentication

时间:2010-10-17 16:35:32

标签: asp.net forms-authentication dotnetopenauth

我正在实施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,故障单也会持续一段时间。

任何人对如何解决这个问题都有任何想法?

提前致谢!

1 个答案:

答案 0 :(得分:6)

首先回答您的问题:OpenID 提供了将Google会话的长度与您自己的会话相关联的方法。您可以做的最好的事情是提供一个仅限会话(非持久性)的cookie,因为它看起来您已经在做,所以如果用户退出Google并关闭他们的浏览器,他们也会被注销到您的网站。这是一个OpenID协议限制 - 没有其他OpenID库可以修复它。

现在谈到你没有要求的问题,但我不能忽视它 - 你的实施是非常不安全的。您隐含地信任AX fetch响应扩展,允许用户控制的任何电子邮件地址是登录的用户。这意味着任何人都可以轻松地设置一个关于电子邮件地址的OpenID提供商并欺骗用户的身份。您可能错误地认为仅仅是因为您将用户重定向到Google,这意味着所有回复都来自Google(假设您信任Google)。仅仅因为您向Google发送请求,并不意味着某人无法从他们自己的非Google服务器中综合回复。

有两种方法可以解决您的安全问题。首先(最好)不要使用电子邮件地址作为您的用户名。请改用IAuthenticationResponse.ClaimedIdentifier作为用户名。这就是它的用途,并将保护您免受许多不同的攻击。不太可取的解决方案是继续使用电子邮件,但要确认在您信任该电子邮件之前,响应实际上来自Google。您可以通过IAuthenticationResponse.Provider.Uri属性执行此操作,并验证它是您期望和信任的属性。