C# 表单身份验证理解 context.user.identity
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8810496/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Forms Authentication understanding context.user.identity
提问by Dexter
Since documentation on this process is very vague and confusing (or old), I wanted to verify that I was doing it correctly and not missing any steps.
由于有关此过程的文档非常模糊且令人困惑(或陈旧),因此我想验证我是否正确执行此操作并且没有遗漏任何步骤。
I am trying to create a secure login system, that expires on browser-close.
我正在尝试创建一个安全的登录系统,该系统在浏览器关闭时过期。
-- in my web.config I have the following --
-- 在我的 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.......... />
So I have a login form with username/password textbox and this button:
所以我有一个带有用户名/密码文本框和这个按钮的登录表单:
<asp:Button ID="LoginButton" runat="Server" OnClick="Login_Authenticate" Text="Sign in" />
Inside Login_Authenticate I do the following:
在 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");
}
}
--- in the MasterPage.master.cs I have the following check in Page_Init() ---
--- 在 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;
}
}
}
EDIT: --- GLOBAL.ASAX ; some code that I am not quite sure is correct or know what it does
编辑:--- 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);
}
}
}
}
--- from then on, on every page, I use the Session userid to gather the user information and content and make sure the user has proper authentication and group-role permissions.
--- 从那时起,在每个页面上,我都使用会话用户 ID 来收集用户信息和内容,并确保用户具有正确的身份验证和组角色权限。
Is this all correct? Or do I have to Decrypt anything somewhere?
这一切都正确吗?还是我必须在某处解密任何东西?
Is this enough to make a secure user login? Or should I not bother with forms authentication and find my own way to make my own cookies and manage it myself?
这足以进行安全的用户登录吗?或者我不应该打扰表单身份验证并找到自己的方式来制作自己的 cookie 并自己管理它?
采纳答案by Joe Enzminger
The way your code is written logins will persist across browser sessions. It might help to understand the basics of what is going on.
您编写代码的方式登录将在浏览器会话中持续存在。这可能有助于了解正在发生的事情的基础知识。
For cookie based authentication methods, there are really three actions:
对于基于 cookie 的身份验证方法,实际上有三个操作:
1) Login - validates user's credentials and creates and stores a cookie on their browser.
1) 登录 - 验证用户的凭据并在他们的浏览器上创建和存储 cookie。
2) Logout - simply removes the cookie from the browser (by expiring the cookie or deleting it)
2) 注销 - 只需从浏览器中删除 cookie(通过使 cookie 过期或删除它)
3) Per Request Validation (the part that is is your Application_AuthenticateRequest) - check to see if a cookie exists, and if so, get the user's Identity and Roles and set HttpContext.Current.User.
3)每个请求验证(部分是您的Application_AuthenticateRequest)-检查cookie是否存在,如果存在,获取用户的身份和角色并设置HttpContext.Current.User。
Typically, the FormsAuthentication module hides most of this from you. It looks like your code is trying to use some of the elements of FormAuthentication (like the FormsAuthenticationTicket and FormsIdentity. This is fine as long as you get what you want.
通常,FormsAuthentication 模块对您隐藏了大部分内容。看起来您的代码正在尝试使用 FormAuthentication 的一些元素(例如 FormsAuthenticationTicket 和 FormsIdentity。只要您得到想要的东西,这很好。
Your Login_Authenticate method looks fine EXCEPT you are setting an expiration on the cookie. This will make the cookie persist even if you close and reopen the browser. Since this is not the behavior you want, I would not set a cookie expiration. Setting this is like checking the "remember me" checkbox.
您的 Login_Authenticate 方法看起来不错,除非您在 cookie 上设置了过期时间。即使您关闭并重新打开浏览器,这也会使 cookie 持续存在。由于这不是您想要的行为,因此我不会设置 cookie 过期时间。设置它就像选中“记住我”复选框。
The code in Application_AuthenticateRequest gets run every time a page is served from your application. It's primary job is to set HttpContext.Current.User. Typically, if no user is logged in, User is either null or an Anonymous user. If a user is logged in, this should represent your user.
每次从您的应用程序提供页面时,Application_AuthenticateRequest 中的代码都会运行。它的主要工作是设置 HttpContext.Current.User。通常,如果没有用户登录,则 User 为空或匿名用户。如果用户已登录,这应该代表您的用户。
If you are doing these three things, then anywhere in your code you can reference HttpContext.Current.User to decide what level of information you want to display. For instance, if you want to restrict a page to administrators only, you could call HttpContext.Current.Users.IsInRole("Administrators"), and redirect them away from the page if the call returns false.
如果你正在做这三件事,那么你可以在代码的任何地方引用 HttpContext.Current.User 来决定你想要显示什么级别的信息。例如,如果您只想将页面限制为管理员,您可以调用 HttpContext.Current.Users.IsInRole("Administrators"),如果调用返回 false,则将它们重定向到远离页面。
Hope this helps.
希望这可以帮助。
回答by Wiktor Zychla
There's a problem in your authorization tag, should be:
你的授权标签有问题,应该是:
<authorization>
<deny users="?" />
<allow users="*" />
</authorization>
because you want to deny anonymous users. If you fix this, you can safely remove all the stuff from the master page and global.asax - you don't have to remap the forms identity to your own custom identity stored in session. It's the waste of resources and I don't think it raises the security of your solution in a significant way. You can rely on the forms cookie.
因为你想拒绝匿名用户。如果您解决此问题,您可以安全地从母版页和 global.asax 中删除所有内容 - 您不必将表单身份重新映射到存储在会话中的您自己的自定义身份。这是资源的浪费,我认为它不会以显着的方式提高您的解决方案的安全性。您可以依赖表单 cookie。
回答by Frédéric
I am a bit late on the subject, but for those trying to implement forms authentication while keeping things simple (like I was trying to), here the relevant most current documentation I have found on msdn: http://msdn.microsoft.com/en-us/library/xdt4thhy(v=vs.100).aspx
我在这个主题上有点晚了,但是对于那些试图在保持简单的同时实现表单身份验证的人(就像我试图这样做),这里是我在 msdn 上找到的相关最新文档:http: //msdn.microsoft.com /en-us/library/xdt4thhy(v=vs.100).aspx
In short, do not mess up with setting cookies, checking them, instantiating tickets or principal, ... Leave-it to FormsAuthenticationclass.
简而言之,不要搞砸设置 cookie、检查它们、实例化票证或主体,......交给FormsAuthentication课堂。
On log on, when your code has check credentials and if they are valid, just call
登录时,当您的代码具有检查凭据并且它们有效时,只需调用
FormsAuthentication.RedirectFromLoginPage(yourUserId, false);
It does set the authentication cookie for you, which, combined with the redirect, is enough. The "false" is for not persisting the authorization: it will be lost on browser close (or authorization timeout).
它确实为您设置了身份验证 cookie,这与重定向相结合就足够了。" false" 用于不保留授权:它将在浏览器关闭(或授权超时)时丢失。
On already authenticated request, there is nothing to check by code for ensuring your authentication is valid. Use Context.User.Identity.Nameto know who is connected (would be the string yourUserIdabove).
对于已通过身份验证的请求,无需通过代码检查以确保您的身份验证有效。使用Context.User.Identity.Name知道谁是连接(将字符串yourUserId以上)。
On explicit logout, call
在显式注销时,调用
FormsAuthentication.SignOut();
FormsAuthentication.RedirectToLoginPage();
And have forms authentication configured in web.config.
并在 web.config 中配置了表单身份验证。
<system.web>
<authentication mode="Forms">
<forms loginUrl="yourLoginPage" defaultUrl="yourDefaultPageAfterLogin">
</forms>
</authentication>
<authorization>
<deny users="?" />
</authorization>
</system.web>
Note that for MVC applications the authorization part should be removed from configuration and handled with AuthorizeAttributeregistered as a global filter attribute, with usage of AllowAnonymousAttributeon controllers or actions needing it. (MVC 4; prior to this one, it was required to create its own attributes for handling that.)
请注意,对于 MVC 应用程序,应从配置中删除授权部分并使用AuthorizeAttribute注册为全局过滤器属性进行处理,并使用AllowAnonymousAttribute控制器或需要它的操作。(MVC 4;在此之前,需要创建自己的属性来处理它。)
回答by Believe2014
The full workflow for Remember Me requires: 1. Write custom data to the cookie. 2. Read that custom data.
记住我的完整工作流程需要: 1. 将自定义数据写入 cookie。2. 读取自定义数据。
Even if you can authenticate a request via cookie, it does not mean an HttpSession object is resumable for that request.
即使您可以通过 cookie 对请求进行身份验证,也不意味着 HttpSession 对象可以为该请求恢复。
http://www.codeproject.com/Articles/779844/Remember-Me
http://www.codeproject.com/Articles/779844/Remember-Me



