经过一番调查,看起来FormsAuthenticationModule为HttpApplicationContext.EndRequest
事件添加了一个处理程序。在它的处理程序中,它检查401状态代码,并基本上执行一个Response.Redirect(loginUrl)
。据我所知,如果要使用,则无法覆盖此行为FormsAuthenticationModule
。
我最终解决该问题的方法是通过FormsAuthenticationModule
在web.config中禁用,如下所示:
<authentication mode="None" />
然后实现Application_AuthenticateEvent
自己:
void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (Context.User == null)
{
var oldTicket = ExtractTicketFromCookie(Context, FormsAuthentication.FormsCookieName);
if (oldTicket != null && !oldTicket.Expired)
{
var ticket = oldTicket;
if (FormsAuthentication.SlidingExpiration)
{
ticket = FormsAuthentication.RenewTicketIfOld(oldTicket);
if (ticket == null)
return;
}
Context.User = new GenericPrincipal(new FormsIdentity(ticket), new string[0]);
if (ticket != oldTicket)
{
string cookieValue = FormsAuthentication.Encrypt(ticket);
var cookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName] ??
new HttpCookie(FormsAuthentication.FormsCookieName, cookieValue) { Path = ticket.CookiePath };
if (ticket.IsPersistent)
cookie.Expires = ticket.Expiration;
cookie.Value = cookieValue;
cookie.Secure = FormsAuthentication.RequireSSL;
cookie.HttpOnly = true;
if (FormsAuthentication.CookieDomain != null)
cookie.Domain = FormsAuthentication.CookieDomain;
Context.Response.Cookies.Remove(cookie.Name);
Context.Response.Cookies.Add(cookie);
}
}
}
}
private static FormsAuthenticationTicket ExtractTicketFromCookie(HttpContext context, string name)
{
FormsAuthenticationTicket ticket = null;
string encryptedTicket = null;
var cookie = context.Request.Cookies[name];
if (cookie != null)
{
encryptedTicket = cookie.Value;
}
if (!string.IsNullOrEmpty(encryptedTicket))
{
try
{
ticket = FormsAuthentication.Decrypt(encryptedTicket);
}
catch
{
context.Request.Cookies.Remove(name);
}
if (ticket != null && !ticket.Expired)
{
return ticket;
}
context.Request.Cookies.Remove(name);
return null;
}
}
它实际上比这稍微复杂一些,但是我基本上是通过查看inReflector的实现来获得代码的FormsAuthenticationModule
。我的实现与内置的实现不同,FormsAuthenticationModule
如果您使用401进行响应,则它不会执行任何操作-根本不会重定向到登录页面。我想如果有必要,我可以在上下文中放置一个项目以禁用自动重定向或其他功能。