Я решил именно эту проблему. Следующим образом:
web.config
* * 1004
<authentication mode="Forms">
<forms name="APPAUTH"
defaultUrl="/webapp/Home.mvc"
loginUrl="/webapp/Session.mvc/Login"
protection="All"
timeout="30"
path="/"/>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
<location path="Session">
<system.web>
<authorization>
<allow users="*"/>
</authorization>
</system.web>
</location>
Затем я зацепил Application_AuthenticateRequest
что-то вроде:
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = Context.Request.Cookies[cookieName];
if (null == authCookie)
{
//no authentication cokie present
return;
}
FormsAuthenticationTicket authTicket = null;
try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch (Exception)
{
// Can't do anything if we can't decrypt the ticket so treat it as not there
FormsAuthentication.SignOut(); // Remove bad ticket
}
if (authTicket == null)
{
//could not decrypt cookie
return;
}
// get the role
string[] roles = authTicket.UserData.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
// Set the security context
ISecurityService security = ContainerProvider.RequestContainer.Resolve<ISecurityService>();
Models.User user = security.GetUser(authTicket.Name);
if (user == null)
{
FormsAuthentication.SignOut();
throw new HttpException((int)System.Net.HttpStatusCode.Unauthorized, "Session expired!");
}
AppIdentity id = new AppIdentity(user, !authTicket.Expired);
AppPrincipal principal = new AppPrincipal(id, roles);
Context.User = principal;
}
Вызов ContainerProvider.RequestContainer.Resolve<ISecurityService>();
относится к контейнеру Autofac , но вы можете сделать здесь все, что вам нужно / нужно.
Классы AppIdentity
и AppPrincipal
являются пользовательскими, поэтому я могу получить доступ к своим ролям, но они не так сложны.