我有一个非常奇怪的场景,我坚持下去。我有一个ASP.Net MVC 4应用程序,我正在验证用户并创建一个authCookie并将其添加到响应的cookie中,然后将它们重定向到目标页面:
if (ModelState.IsValid)
{
var userAuthenticated = UserInfo.AuthenticateUser(model.UserName, model.Password);
if (userAuthenticated)
{
var userInfo = UserInfo.FindByUserName(model.UserName);
//SERIALIZE AUTHENTICATED USER
var serializer = new JavaScriptSerializer();
var serializedUser = serializer.Serialize(userInfo);
var ticket = new FormsAuthenticationTicket(1, model.UserName, DateTime.Now, DateTime.Now.AddMinutes(30), false, serializedUser);
var hash = FormsAuthentication.Encrypt(ticket);
var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, hash) {Expires = ticket.Expiration};
Response.Cookies.Add(authCookie);
if (Url.IsLocalUrl(model.ReturnUrl) && model.ReturnUrl.Length > 1 && model.ReturnUrl.StartsWith("/") && !model.ReturnUrl.StartsWith("//") && !model.ReturnUrl.StartsWith("/\\"))
{
return Redirect(model.ReturnUrl);
}
var url = Url.Action("Index", "Course");
return Redirect(url);
}
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
这在所有浏览器中都运行良好。我可以登录并访问我的应用程序中的安全页面。
我的客户正在申请此应用的Android版本。所以,我正在试图找出如何将此应用程序转换为APK文件。我的第一个尝试是创建一个简单的index.html页面,其中包含一个以应用程序为目标的iframe。这在Firefox和IE 9中运行得很好。但是,当访问包含通过Chrome指向应用程序的iframe的index.html页面时,我会通过上面的登录代码并将用户重定向到安全控制器,但是安全控制器具有自定义属性以确保用户已通过身份验证:
public class RequiresAuthenticationAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.User.Identity.IsAuthenticated) return;
if (filterContext.HttpContext.Request.Url == null) return;
var returnUrl = filterContext.HttpContext.Request.Url.AbsolutePath;
if (!filterContext.HttpContext.Request.Browser.IsMobileDevice)
{
filterContext.HttpContext.Response.Redirect(FormsAuthentication.LoginUrl + string.Format("?ReturnUrl={0}", returnUrl), true);
}
else
{
filterContext.HttpContext.Response.Redirect("/Home/Home", true);
}
}
}
我的应用失败:filterContext.HttpContext.User.Identity.IsAuthenticated。即使用户在上面的代码中进行了身份验证,IsAuthenticated始终为false。
请注意,只有在Chrome中通过iframe访问应用时才会出现这种情况。如果我直接访问应用程序而不是通过iframe,那么一切正常。
有什么想法吗?
更新:
我的控制器扩展了SecureController。在SecureController的构造函数中,我有用于反序列化用户的代码:
public SecureController()
{
var context = new HttpContextWrapper(System.Web.HttpContext.Current);
if (context.Request.Cookies[FormsAuthentication.FormsCookieName] != null)
{
var serializer = new JavaScriptSerializer();
var cookie = context.Request.Cookies[FormsAuthentication.FormsCookieName].Value;
var ticket = FormsAuthentication.Decrypt(cookie);
CurrentUser = serializer.Deserialize<UserInfo>(ticket.UserData);
}
else
{
CurrentUser = new UserInfo();
}
//if ajax request and session has expired, then force re-login
if (context.Request.IsAjaxRequest() && context.Request.IsAuthenticated == false)
{
context.Response.Clear();
context.Response.StatusCode = 401;
context.Response.Flush();
}
}
答案 0 :(得分:0)
首先,您应该从AuthorizeAttribute派生,而不是ActionFilterAttribute。授权属性在方法甚至在管道的更高级别调用之前执行,而ActionFilters执行得更远,其他属性可以在您的之前执行。
其次,您没有显示用于解密故障单并设置IPrincipal和IIdentity的代码。既然这就是问题所在,那就很奇怪你没有把它包括在内。