DotNetOpenAuth和FormsAuthentication

jos*_*son 2 asp.net forms-authentication dotnetopenauth

我正在实施DotNetOpenAuth(OpenID)和Forms Authentication作为我正在构建的网站的身份验证机制.但是,我对我提出的解决方案的部分内容并不满意,尽管我应该和你们一起检查它是如何完成的.

我已将表单身份验证设置loginUrllogin.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);
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,当用户未登录时,会直接将其发送到login.aspx页面,该页面直接尝试使用针对Google的OpenID登录.它检查用户是否在允许的用户列表中,然后FormsAuthentication.RedirectFromLoginPage().

到目前为止没有问题...... 问题在于退出.理想情况下,我希望登录直接与Google帐户登录状态相关联.如果用户已登录Google,则他/她也应该在我的网站上登录.当用户退出Google时,他/她应该从我的网站注销.但是,由于使用了表单身份验证,即使用户退出Google,故障单也会持续一段时间.

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

提前致谢!

And*_*ott 6

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

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

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