为什么用户必须两次输入正确的凭据?

时间:2014-08-27 11:41:15

标签: c# asp.net-mvc forms-authentication

public ActionResult Login(CredentialsModel model)
{
    authenticator.Authenticate(model.Username, model.Password);

    if (authenticator.Authenticated)
    {
        return Redirect();
    }
}

...

public class Authenticator : IAuthenticator
{
    public bool Authenticated
    {
        get { return HttpContext.Current.User.Identity.IsAuthenticated; }
    }

    public void Authenticate(string username, string password)
    {
        var authenticated = FormsAuthentication.Authenticate(username, password);
        if (authenticated)
            FormsAuthentication.SetAuthCookie(username, false);
    }

    public void Logout()
    {
       FormsAuthentication.SignOut();
    }
}

当上述操作方法向Authenticate方法提供一些有效凭据时,Authenticated属性返回false,这显然是错误的。

当action方法为 second 时间提供某些凭据时,Authenticated属性返回true。

我怀疑这与上下文不会立即更新有关。我实际上设法通过在操作方法中使用FormsAuthentication.Authenticate的立即返回值来解决此错误,但我想知道为什么发生此错误。

1 个答案:

答案 0 :(得分:1)

因为在第一次呼叫用户发送的HTTP上下文中,进行了身份验证(但在此之后它将正确地用于后续呼叫)。在这一行之后:

var authenticated = FormsAuthentication.Authenticate(username, password);

您可能会看到authenticated != Authenticated。为什么?来自MSDN

  

[HttpContext]封装有关单个HTTP请求的所有特定于HTTP的信息。

这意味着它适用于请求(您的输入)而非响应或未来状态(您的输出)。如果您在控制器方法中执行SignOut(),您还会看到HttpContext.Current.User.Identity.IsAuthenticated仍然是true

您可以做的是为Authenticate()添加布尔返回值:

public bool Authenticate(string username, string password)
{
    var authenticated = FormsAuthentication.Authenticate(username, password);
    if (authenticated)
        FormsAuthentication.SetAuthCookie(username, false);

    return authenticated:
}

将控制器中的代码更改为:

if (authenticator.Authenticate(model.Username, model.Password))
{
    return Redirect();
}