Authentication and Security in my website - need advice please
I am using database with a list of username/passwords, and a simple web form that allows for users to enter their username/password.
When they submit the page, I simply do a stored procedure check to authenticate. If they are authorised, then their user details (e.g. username, dob, address, company address, other important info) are stored in a custom User object and then in a session. This custom User object that I created is used throughout the web application, and also in a sub-site (session sharing).
My question/problems are:
Is my method of authentication the correct way to do things?
I find users complaining that their session have expired although they "were not idle", possibly due the app pool recycling? They type large amounts of text and find that their session had expired and thus lose all the text typed in. I am uncertain whether the session does really reset sporadically but will Forms Authentication using cookies/cookiless resolv开发者_高级运维e the issue?
Alternatively should I build and store the User Object in a session, cookie or something else instead in order to be more "correct" and avoid cases like in point #2.
If I go down the Forms Authentication route, I believe I cannot store my custom User object in a Forms Authentication cookie so does it mean I would store the UserID and then recreate the user object on every page? Would this not be a huge increase on the server load?
Advice and answers much appreciated.
L
- It doesn't really care whether you use your own authentication system, or the default membership providers when using such a simple scenario.
- You should avoid using the
InProc
session state when the app might recycle some times a day. Rather store your session into a database (SqlSessionState
) or use aStateServer
. Then the application pool can recycle all day without interferring with your sessions. Setting the session timeout to 60 minutes or something, will solve the remaining issues. Never use cookieless sessions (unless you know what you're doing), as they make it way too easy to steal one's session. - Just store it into the session (or profile if you use the default membership provider). Not only is a cookie easily readible, it is also limited to 4 KB.
- No, you will have a profile where all the user information is stored. It doesn't really matter whether you use forms authentication or a custom system that stores it's data into
SqlSessionState
. The membership provider will store the Profile ID into a cookie, same as the session state will save the Session ID into a cookie.
You can use ASP.NET Membership, Roles, Forms Authentication, and Security Resources I will give an example using c#
For reference Forms Authentication in ASP.NET 2.0
//code for checking user name & password
protected void btnlogin_Click(object sender, EventArgs e)
{
try
{
if (txtUserName.Text.Trim() != "" && txtPassword.Text.Trim() != "")
{
User obj = objUser.UserAuthenticate(txtUserName.Text.Trim(), txtPassword.Text.Trim());
if (obj != null)
{
//To set AuthenticationCookie of usertype "User"
SetAuthenticationCookie("User", obj.UserID.ToString(), obj.DisplayName);
HttpCookie usercookie = new HttpCookie("LoginTime");
usercookie.Value = DateTime.Now.ToString();
Response.Cookies.Add(usercookie);
HttpCookie namecookie = new HttpCookie("LoginName");
namecookie.Value = obj.DisplayName;
Response.Cookies.Add(namecookie);
}
else
{
lblMsg.Text = "Invalid Username or Password.";
}
}
else
{
//lblMsg.Visible = true;
}
}
catch (Exception ex)
{
//lblMsg.Visible = true;
throw ex;
}
}
private void SetAuthenticationCookie(string role, string userid, string name)
{
string userdata = "logintype=user|role=" + role + "|email=" + txtUserName.Text.Trim() + "|name=" + name;
FormsAuthenticationTicket faTicket = new FormsAuthenticationTicket(1, userid,
DateTime.Now, DateTime.Now.AddHours(+1),
false, userdata);
HttpCookie authCookie = new HttpCookie( FormsAuthentication.FormsCookieName,//"martinfernandez@ispg.in",
FormsAuthentication.Encrypt(faTicket));
authCookie.Expires = faTicket.Expiration;
Response.Cookies.Add(authCookie);
}
//code inside global.asax.cs
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (Context.User != null && Context.User.Identity is FormsIdentity && Context.User.Identity.IsAuthenticated)
{
FormsAuthenticationTicket faTicket = FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value);
string[] userdata = faTicket.UserData.Split("|".ToCharArray());
string logintype = "";
string email = "";
string uname = "";
string roleString = "";
foreach (string s in userdata)
{
string keyname = s.Split("=".ToCharArray())[0];
if (keyname == "logintype")
{
logintype = s.Split("=".ToCharArray())[1];
}
else if (keyname == "role")
{
roleString = s.Split("=".ToCharArray())[1];
}
}
string[] rolesArray = roleString.Split(";".ToCharArray());
Context.User = new System.Security.Principal.GenericPrincipal(new FormsIdentity(faTicket), rolesArray);
}
}
Just to touch on point #4 - it would be more efficient memory-wise to not store everyone's "User" object in memory, and re-create the object each HTTP request. This way you also re-verify the login details-- what if someone's account is compromised and the actual user changes their password to try and protect their account, but the "bad user" has already logged in? Under your security mechanism, the "bad user" can keep browsing away since the user data is cached and not re-verified each postback.
Here are the some general security measures that beginner and Advance Web Developer must follow.
#15 Steps To Secure Your Website
1 : Prevent Image Hotlinking (IMP)
Image hotlinking is the process of using someone else’s Image URL in our Website and using their bandwidth. In order to prevent this mystery, we can prevent access for external server by adding following line in code.
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?yourdomain.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ - [NC,F,L]
2 : Prevent CSRF (Cross Site Request Forgery) Attacks
In order to prevent CSRF attacks on your GET and POST requests for form submission, you can use following 2 techniques.
The first it to include a random token with each request, this is a unique string that is generated for each session.
The second method is to use random name for each form field.
3 : Prevent Directory Access / Disable Indexing
Add the following line to your .htaccess file.
Options -Indexes
4 : Secure your Private and CMS Login with IP restrictions
IP restriction is a bit way advanced yet effective method to stop the unauthorized personnel to access a particular area of your website. Here is an example htaccess code to IP restrict the access to a particular location.
ALLOW USER BY IP
<Limit GET POST>
order deny,allow
deny from all
allow from 1.2.3.4
</Limit>
5 : Protect your .htaccess file
You can write this below piece of code in your htaccess file which do not let any others access your htaccess file.
<Files ~ “^.*.([Hh][Tt][Aa])”>
order allow,deny
deny from all
satisfy all
</Files>
6 : Function access rule
By adding "_" as a prefix for Function name, we can prevent function to be called from The Web publicly. This is the best practice when we need some specific function to be accessed via AJAX only.
7 : Lock down your directory and file permissions
File permissions define who can do what to a file.
"Read" = 4 : View the file contents.
"Write" = 2 : Change the file contents.
"Execute" = 1 : Run the program file or script.
8 : Prevent Cron Job to be run from Web Browser
By adding, following line of code in your page, you can protect your page to be accessed from a web browser.
if( ! $this->input->is_cli_request() ) {
die("Only CLI Requests Allowed");
}
9 : Hide admin pages to be crawled by Google
You do not want your admin pages to be indexed by search engines, so you should use the robots_txt file to discourage search engines from listing them.
10 : Disable Right Click on Page if not require
Disabling “right-click” as a way to view your website source code by inspect element to secure Website content for general users.
11 : Use Strong Password for CMS
Keep practice to set random Password with the special character only.
12 : Make Admin Directory Tough to guess
It may happen that Hackers can use scripts that scan all the directories on your web server for giveaway names like ‘admin’ or ‘login’ etc. and your significant stuff may get leaked.
13 : Change your database table prefix
Add a prefix (the mixture of project name and year) which would be hard to presume for a secured side.
To illustrate,
A) BPM Supreme => bpm14_download
B) Glickin => gk15_admin
C) TravelWorthy => tw16_user
14 : Prevent User's Password, that's as important as yours
Regarding Password Encryption algorithm, Use sha1 algorithm instead of tradition algorithm Md5 which is the very old way and becoming less secure nowadays as per sources.
Reference : http://php.net/manual/en/function.sha1.php
15 : Hide Error Log
During development Mode, keep error reporting "ALL" and once we go LIVE change it to "0" without forgetting. Over here
Reference : http://php.net/manual/en/function.error-reporting.php
My advice would be to use asp.net membership and roles (Microsoft). It is a very good security solution - login security, roles (permissions) and is stored in a SQLServer database (not sure if it can be stored elsewhere).
I use it on my site and you can use membership controls straight out of the box (login forms, change password, etc.) or you can roll your own.
The only tricky bit I found was setting up the membership tables, views and stored procs in my dB (you download a dB script), but really it was fairly straightforward to implement.
Here's a link to asp.net membership and roles
精彩评论