由于此过程的文档非常模糊且令人困惑(或过时),我想验证我是否正确执行此操作并且没有遗漏任何步骤。
我正在尝试创建一个安全的登录系统,在浏览器关闭时到期。
- 在我的web.config中我有以下内容 -
<authentication mode="Forms">
<forms loginUrl="~/Login.aspx" defaultUrl="Index.aspx" name=".ASPXFORMSAUTH" timeout="100" />
</authentication>
<authorization>
<allow users="?" />
</authorization>
<machineKey decryption="AES" validation="SHA1" validationKey.......... />
所以我有一个带有用户名/密码文本框的登录表单和这个按钮:
<asp:Button ID="LoginButton" runat="Server" OnClick="Login_Authenticate" Text="Sign in" />
Inside Login_Authenticate我执行以下操作:
protected void Login_Authenticate(object sender, EventArgs e){
string userName = UserName.Text;
string password = Password.Text;
bool Authenticated = false;
// Here's code that makes sure that Username and Password is CORRECT
if(AuthClass.Authenticate(userName, password)){
Authenticated = true;
}
// error checking does happen here.
if (Authenticated)
{
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddMinutes(30), rememberUserName, String.Empty, FormsAuthentication.FormsCookiePath);
string encryptedCookie = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedCookie);
cookie.Expires = DateTime.Now.AddMinutes(30);
Response.Cookies.Add(cookie);
//FormsAuthentication.RedirectFromLoginPage(userName, false);
Response.Redirect("MainPage.aspx");
}
}
---在MasterPage.master.cs中,我在Page_Init()---
中进行了以下检查if (Context.User.Identity.IsAuthenticated)
{
int userid = (int)Session["userid"];
if (userid == null)
{
userid = GetUserID(Context.User.Identity.Name);
if (userid != null)
{
Session["userid"] = userid;
}
}
}
修改: --- GLOBAL.ASAX;一些我不太确定的代码是正确的或知道它做了什么
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
// look if any security information exists for this request
if (HttpContext.Current.User != null)
{
// see if this user is authenticated, any authenticated cookie (ticket) exists for this user
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
// see if the authentication is done using FormsAuthentication
if (HttpContext.Current.User.Identity is FormsIdentity)
{
// Get the roles stored for this request from the ticket
// get the identity of the user
FormsIdentity identity = (FormsIdentity)HttpContext.Current.User.Identity;
//Get the form authentication ticket of the user
FormsAuthenticationTicket ticket = identity.Ticket;
//Get the roles stored as UserData into ticket
string[] roles = { };
//Create general prrincipal and assign it to current request
HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(identity, roles);
}
}
}
}
---从那时起,在每个页面上,我使用Session userid收集用户信息和内容,并确保用户具有适当的身份验证和组角色权限。
这一切都正确吗?或者我必须在任何地方解密?
这足以让用户登录安全吗?或者我应该不打扰表单身份验证并找到自己的方式来制作自己的cookie并自己管理它?
答案 0 :(得分:12)
编写代码的方式登录将在浏览器会话中保持不变。它可能有助于理解正在发生的事情的基础。
对于基于cookie的身份验证方法,实际上有三个操作:
1)登录 - 验证用户的凭据,并在其浏览器上创建并存储cookie。
2)注销 - 只需从浏览器中删除cookie(通过使cookie过期或删除它)
3)Per Request Validation(您的Application_AuthenticateRequest部分) - 检查是否存在cookie,如果存在,请获取用户的Identity和Roles并设置HttpContext.Current.User。
通常,FormsAuthentication模块会隐藏大部分内容。看起来你的代码试图使用FormAuthentication的一些元素(比如FormsAuthenticationTicket和FormsIdentity。只要你得到你想要的东西就没问题。
您的Login_Authenticate方法看起来很好除了您在Cookie上设置过期时。即使您关闭并重新打开浏览器,这也会使cookie保持不变。由于这不是您想要的行为,我不会设置cookie过期。设置此项就像检查“记住我”复选框一样。
每次从应用程序提供页面时,都会运行Application_AuthenticateRequest中的代码。它的主要工作是设置HttpContext.Current.User。通常,如果没有用户登录,则User为null或匿名用户。如果用户已登录,则应代表您的用户。
如果您正在执行这三项操作,那么您可以在代码中的任何位置引用HttpContext.Current.User来决定要显示的信息级别。例如,如果您只想将页面限制为管理员,则可以调用HttpContext.Current.Users.IsInRole(“Administrators”),如果调用返回false,则将它们重定向离开页面。
希望这有帮助。
答案 1 :(得分:6)
我对这个问题有点迟了,但是对于那些试图实现表单身份验证同时保持简单的人(就像我想要的那样),这里是我在msdn上找到的相关最新文档: http://msdn.microsoft.com/en-us/library/xdt4thhy(v=vs.100).aspx
简而言之,不要搞乱设置cookie,检查它们,实例化故障单或校长,......将它留给FormsAuthentication
课程。
登录时,如果您的代码具有检查凭据且有效,请致电
FormsAuthentication.RedirectFromLoginPage(yourUserId, false);
它会为您设置身份验证Cookie,与重定向相结合就足够了。 “false
”用于不持久授权:它将在浏览器关闭(或授权超时)时丢失。
在已经过身份验证的请求中,没有任何内容可以通过代码进行检查以确保您的身份验证有效。使用Context.User.Identity.Name
知道谁已连接(将是上面的字符串yourUserId
。)
在显式注销时,请致电
FormsAuthentication.SignOut();
FormsAuthentication.RedirectToLoginPage();
并在web.config中配置表单身份验证。
<system.web>
<authentication mode="Forms">
<forms loginUrl="yourLoginPage" defaultUrl="yourDefaultPageAfterLogin">
</forms>
</authentication>
<authorization>
<deny users="?" />
</authorization>
</system.web>
请注意,对于MVC应用程序,应从配置中删除授权部分,并使用AuthorizeAttribute
注册为全局过滤器属性进行处理,并在控制器上使用AllowAnonymousAttribute
或需要它的操作。 (MVC 4;在此之前,需要创建自己的属性来处理它。)
答案 2 :(得分:2)
授权标签中存在问题,应该是:
<authorization>
<deny users="?" />
<allow users="*" />
</authorization>
因为您要拒绝匿名用户。如果您解决了这个问题,您可以安全地从母版页和global.asax中删除所有内容 - 您不必将表单标识重新映射到会话中存储的自定义标识。这是浪费资源,我认为它不会以显着的方式提高解决方案的安全性。您可以依赖表单cookie。
答案 3 :(得分:1)
Remember Me的完整工作流程要求: 1.将自定义数据写入cookie。 2.阅读该自定义数据。
即使你可以通过cookie验证请求,也不意味着HttpSession对象可以恢复该请求。
http://www.codeproject.com/Articles/779844/Remember-Me