我做了这个动作:
public ActionResult Index(string username, int userID)
{
if (!HttpContext.User.Identity.IsAuthenticated)
{
var ticket = new FormsAuthenticationTicket(2, username, DateTime.Now, DateTime.Now.AddDays(7), false, string.Empty);
var encr = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encr);
Response.Cookies.Add(cookie);
}
return View("Index",null,username);
}
稍后,将调用此部分视图操作:
public PartialViewResult PageHeader()
{
if (HttpContext.User.Identity.IsAuthenticated)
{
string username = HttpContext.User.Identity.Name;
...
}
}
即使在上一个操作中设置了auth cookie,表达式HttpContext.User.Identity.IsAuthenticated
也会被评估为false。只有在刷新页面后,表达式才会评估为真
所以我的问题是:如何告诉asp.net mvc用户已经过身份验证,并使用HttpContext.User.Identity属性?
答案 0 :(得分:2)
ASP.NET 在请求开头只设置一次 HttpContext.User.Identity.IsAuthenticated
。
因此,稍后设置控制器操作中的身份验证Cookie对HttpContext.User.Identity.IsAuthenticated
没有任何影响,因为您处于同一请求的上下文中。
建议的"工作流程"表单身份验证的内容如下:
因此,您需要发出新请求才能正确更新HttpContext.User.Identity.IsAuthenticated
。
成功登录的标准做法是将客户端重定向到原始网址,或者在您的情况下将其重定向到同一操作:
public ActionResult Index(string username, int userID)
{
if (!HttpContext.User.Identity.IsAuthenticated)
{
var ticket = new FormsAuthenticationTicket(2, username, DateTime.Now,
DateTime.Now.AddDays(7), false, string.Empty);
var encr = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encr);
Response.Cookies.Add(cookie);
return RedirectToAction("Index", new {username, userID});
}
return View("Index", null, username);
}
答案 1 :(得分:2)
这似乎是一种奇怪的做法;您在错误的图层中执行身份验证。
用户通常在之前通过身份验证进入操作方法(被调用)。这样,如果未经过身份验证,您可以阻止它们进入控制器或操作。
为什么不使用框架来处理这个任务?它将在管道中的正确阶段自动为您设置cookie。
Subclass MembershipProvider和Override ValidateUser(string username, string password)
:
在此方法中,使用用户名和密码进行验证。如果验证失败(用户名/密码错误等),return false
。如果成功,return true
,将为您设置身份验证cookie。
从这一点开始,您可以创建授权属性(通过继承 AuthorizationAttribute )并装饰您的控制器或操作。在这些属性中,您可以执行诸如检查用户角色,范围,权限等操作,并在用户未正确授权发出请求时拒绝该请求。这非常简单。
您需要做三件事:
false
,它会将它们发送到登录屏幕。否则,它将允许他们继续请求),并将自定义提供程序添加到 web.config ,以便它知道使用它。如果您还没有这样做,可能还需要在web.config中设置“登录”页面。这是正确的(呃)方式,可能会解决您的问题,同时还可以清理您的项目。
// The provider
// This is what gets called during login. your logic to validate the user is placed here
// Return true or false which will indicate whether or not an auth token/cookie will be set
public class MyCustomProvider : MembershipProvider
{
public override bool ValidateUser(string username, string password)
{
const string testUsername = "User1";
const string testPassword = "abcd1234";
// do whatever you need to do in order to verify this dude's identity
return username.Equals(testUsername) && password.Equals(testPassword);
}
//... bunch of other overrides. I only implement them if I actually use them otherwise just wrap them in a region and hide them.
}
// The web.config update. Tell the framework where your login page is. Typically, in an MVC project,
// The view is in Views/Account and the action Login on the Account controller calls WebSecurity.Login
// which is what runs your provider. Define both here.
<system.web>
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" />
</authentication>
<membership defaultProvider="MyCustomProvider">
<providers>
<remove name="AspNetSqlProvider" />
<add name="MyCustomProvider"
type="FullyQualifiedName.MyCustomProvider, AuthDemo, Version=1.0.0.0, Culture=neutral" />
</providers>
</membership>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
// The authorize attribute
// This is where you can check your user's authorization. In this example, I just
// check to see that he was authenticated by the provider.
public class MyCustomAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
// do whatever you need to do here to verify that this dude is allowed to be here
return httpContext.User.Identity.IsAuthenticated;
}
}
// sample usage of the attribute
// the framework will run this attribute before it allows the user into the controller.
// You could also do this at the action level instead of the controller level
[MyCustomAuthorize]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Your contact page.";
return View();
}
}