我一直在试图寻找答案,但我似乎无法取得任何进展。
我想做的就是检查一个正确的用户名和密码组合,然后给予用户授权以访问用[Authorize]标签装饰的MVC动作。
public ActionResult DoLogin(PageInitModel model)
{
EF_db db = new EF_db();
string saltPassword = getSaltedPasswordEncryption(model.UserName, model.Password);
var user = (from s in db.Users
where s.Username == model.UserName
&& s.Password == saltPassword
select s).FirstOrDefault();
if(user == null)
{
model.LoginFail = true;
return View("Login", model);
}
else
{
//
// give the user some magical token to access [Authorize] actions here
//
return RedirectToAction("Index", "Menu");
}
}
以上是登录操作(从基本表单调用),以下是我想限制访问的操作之一:
public class MenuController : Controller
{
[Authorize]
public ActionResult Index()
{
var pageInitModel = new PageInitModel();
return View("Menu",pageInitModel);
}
}
我想自己跟踪用户(在我自己的表中),因为我想跟踪许多其他属性。我不确定我是否需要编写自定义的AuthorizeAttribute,或者是什么,但我似乎无法取得任何进展。
非常感谢任何帮助我指明正确方向的帮助。
谢谢!
答案 0 :(得分:1)
您应该查看ASP.NET身份。请注意,这是在ASP.NET 5(?)中引入的,并取代了Microsoft已经使用的基本成员资格等旧框架。
老实说,你真的不想自己动手。 ASP.NET Identity完全按照您开箱即用的描述。请记住,身份验证和授权有两个不同的概念。
身份验证正在验证用户是否是他所说的人 授权仅限制访问“允许”的用户。
构建授权的方法有很多,但我认为基于角色的授权可以满足您的需求。您将定义多个角色,例如用户,管理员,主持人,管理员等。
然后,您可以根据角色限制对操作的访问。您甚至可以使角色重叠,并允许单个用户拥有多个角色。最终结果是,一旦用户登录他们的角色,就可以通过授权标签确定他们可以做什么。
[Authorize(Roles="Admin")]
如果用户未登录,他们将被重定向到登录表单AUTHENTICATE(“嗯我不知道你是谁”。一旦通过身份验证,如果他们未获得授权他们将仍被限制在此行动(“哦,我知道你是谁,但你不能这样做”。
要完善它,您还可以进行匿名操作,这意味着不需要身份验证,并授权不限于特定角色的操作(允许任何经过身份验证的用户,但不允许未经身份验证的用户)。
即使使用基本的[授权]您遇到问题,也要相信即使是身份验证也存在一些配置问题。我建议通过一个教程构建一个像这样的示例应用程序: http://blogs.msdn.com/b/webdev/archive/2013/10/20/building-a-simple-todo-application-with-asp-net-identity-and-associating-users-with-todoes.aspx
答案 1 :(得分:0)
据我了解,您拥有自己的用户信息,并且您可能希望使用自定义代码进行身份验证。但要实际登录用户,您必须创建用户会话(Cookie会话)以进一步验证请求。
您已验证用户名和密码。现在您可以使用表单身份验证创建会话cookie。以下是您第一个问题的答案:
//为用户提供一些神奇的令牌来访问[授权]操作
// User name and password matches
if (userValid)
{
FormsAuthentication.SetAuthCookie(username, false);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
Authorize
属性将检查针对该操作的请求是否已通过身份验证。此属性在内部检查会话cookie是否有效并经过身份验证。
此属性不仅会检查身份验证,还可以验证授权。因此,您可以使用自定义角色和“授权”属性来限制用户访问特定视图/操作。
答案 2 :(得分:0)
有人向我指出,我需要查看cookie或现有会员提供商,所以我浏览了FormsAuthenticationTickets并推出了我自己喜欢的反馈解决方案。
当使用FormsAuthenticationTicket类成功登录时,我最终创建了一个新票证(见下文)。
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
user.Username,
DateTime.Now,
DateTime.Now.AddHours(2),
false,
userData,
FormsAuthentication.FormsCookiePath);
// Encrypt the ticket.
string encTicket = FormsAuthentication.Encrypt(ticket);
// Create the cookie.
Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));
然后我写了一个自定义的ActionFilter,所以我可以创建自己的方法装饰器(或者他们所称的任何东西)。
namespace MyApp.Filters
{
public class CustomLoginFilter : ActionFilterAttribute, IActionFilter
{
void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
{
// Retrieves the cookie that contains your custom FormsAuthenticationTicket.
HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
// There's actually a cookie
// Decrypts the FormsAuthenticationTicket that is held in the cookie's .Value property.
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
if (authTicket != null && user != null && data == authTicket.UserData)
{
// Everything looks good
this.OnActionExecuting(filterContext);
}
else
{
//log bounceback - someone screwed with the cookie
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "controller", "Login" },
{ "action", "Index" }
});
}
}
else
{
//log bounceback - not logged in
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "controller", "Login" },
{ "action", "Index" }
});
}
}
}
}
我可能会更多地使用它,但它现在似乎工作正常。
感谢您的帮助。