1

我正在尝试根据现有的 cookie 对用户进行身份验证。我过去通过使用自定义IIdentityIPrincipal

public class CustomIdentity : IIdentity {

    public string Name { get; set; }
    public bool IsAuthenticated { get { return true; } }
    public string AuthenticationType { get { return String.Empty; } }

}

public class CustomPrincipal : IPrincipal {

    private CustomIdentity _identity;
    private string[] _roles;

    public IIdentity Identity {
        get { return _identity; }
    }

    public CustomPrincipal(CustomIdentity identity, string[] roles) {
        _identity = identity;
        _roles = roles;
    }

    public bool IsInRole(string role) {
        return true;
        //TODO
    }
}

我设置了一个简单的 HttpModule 来处理身份验证。

public class Authentication : IHttpModule {

    public void Init(HttpApplication application) {
        application.AuthenticateRequest += new EventHandler(Application_AuthenticateRequest);
    }

    private void Application_AuthenticateRequest(object sender, EventArgs e) {
        //TODO: authentication logic here
        CustomIdentity identity = new CustomIdentity();
        CustomPrincipal principal = new CustomPrincipal(identity, new string[] { });
        HttpContext.Current.User = principal;
    }

    public void Dispose() { }
}

当我通过 web.config 禁止匿名用户时,框架会无限重定向到 login.aspx,即使HttpContext.Current.Request.IsAuthenticated在身份验证事件之后是真的。

这发生在身份验证模式 Windows、Forms 和 None 上。

如何使框架相信请求已正确验证?

更新:

事实证明,其他地方还有其他代码正在调用System.Web.Security.FormsAuthentication.SignOut(),因此我的身份验证模块正在设置主体,调用了注销并且模块将再次触发。因此无休止的重定向循环。

4

4 回答 4

1

在 web.config 中,将成员资格元素上的默认提供程序设置为您的自定义提供程序的名称:

...
<membership Default="YourDefaultProvider">
<providers>
<clear/>
<add Name="YourDefaultProvider" etc.. />
</providers>
</membership>
于 2013-11-14T17:12:56.180 回答
0

当您Forms在 Web.config 文件中将身份验证模式设置为时,FormsAuthentication类将负责根据 ASP.NET 创建的 cookie 对请求进行身份验证。

由于 ASP.NET 有自己的公式来创建身份验证票证,因此任何其他 cookie 都不会通过身份验证。

由于您拥有创建和读取 cookie 的身份验证逻辑和公式,我认为您有两个选择:

  1. 禁用 ASP.NET 的默认身份验证(不使用 web.config,并将身份验证机制自定义到 100%,或者实际上,从头开始编写自定义身份验证)
  2. 使用 ASP.NET 公式创建身份验证 cookie。为此,您需要使用FormsAuthentication.SetAuthenticationCookie方法。
于 2013-11-14T16:59:16.803 回答
0

您是否删除了 asp.net 自动化模块?

<authentication mode="None">
 ....
<modules runAllManagedModulesForAllRequests="false">
  <remove name="WindowsAuthentication" />
  <remove name="PassportAuthentication" />
  <remove name="AnonymousIdentification" />
  <remove name="FormsAuthentication" />
  ...
  <add name="myauthmodule" type="myauthmodule" />

你在使用 UrlAuthorization 吗?

<authorization>
  <allow roles="Admin" />
  <deny users="?" />
  <deny users="*" />
</authorization>

我认为问题是由于您混合了自定义自动化和 asp.net 授权这两个世界。

如果你想这样做,你必须读取你的cookie数据,然后做asp.net想要的:一个formauthentication cookie

//create ticket
var ticket = new FormsAuthenticationTicket(
        1, // ticket version
        userName,
        DateTime.Now,
        DateTime.Now.Add(timeout), // timeout
        true, // cookie persistent
        roles,
        FormsAuthentication.FormsCookiePath);

// cookie crypt
string hash = FormsAuthentication.Encrypt(ticket);

var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hash);
cookie.Domain = FormsAuthentication.CookieDomain;

// cookie timeout as ticket timeout
if (ticket.IsPersistent)
{
    cookie.Expires = ticket.Expiration;
}
CurrentContext.Response.Cookies.Add(cookie);
    ....
HttpContext.Current.User = new GenericPrincipal(new FormsIdentity(ticket), roles);
于 2013-11-14T16:57:34.703 回答
0

这只是一个假设,我目前无法验证它,但我相信你不能用空名称设置身份。您的 CustomIdentity 构造函数没有设置一个。

    CustomIdentity identity = new CustomIdentity();
    identity.Name = "foo";

试试这个来检查理论,如果它有效,请继续进一步实现您的自定义身份验证逻辑。

于 2013-11-14T17:55:39.947 回答