Also presented are suggestions as to how this security could be improved if you cross the boundary of ASP.Net functionality into supporting technologies. Firstly, however I'll provide an overview of web application security and the features available in ASP.Net, focusing particularly on forms based authentication, as this is the approach we shall eventually use as the basis for our login facility.
Pre-requisites for this article include some prior knowledge of ASP.Net (web.config, security, etc.) and related technologies (e.g. IIS) as well as a basic understanding of general web and security related concepts, e.g. HTTP, cookies.
Security for web applications is comprised of two processes: authentication and authorization. The process of identifying your user and authenticating that they are who they claim they are is authentication. Authorization is the process of determining whether the authenticated user has access to the resource they are attempting to access.
The authentication process requires validation against an appropriate data store, commonly called an authority, for example an instance of Active Directory.
ASP.Net provides authorization services using both the URL and the file of the requested resource. Both checks must be successful for the user to be allowed to proceed to access said resource.
Integrated Windows authentication uses the domain, username and computer name of the client user to generate a ‘challenge’. The client must enter the correct password which will causes the correct response to be generated and returned to the server.
In order for integrated Windows authentication to be used successfully in ASP.Net the application needs to be properly configured to do so via IIS – you will commonly want to remove anonymous access so users are not automatically authenticated via the machines IUSR account. You should also configure the directory where the protected resource is located as an application, though this may already be the case if this is the root directory of your web application.
Forms authentication is flexible in the authorities against which it can validate. . For example, it can validate credentials against a Windows based authority, as per integrated Windows, or other data sources such as a database or a simple text file. A further advantage over integrated Windows is that you have control over the login screen used to authenticate users.
Forms authentication is enabled in the applications web.config file, for example:
<configuration> <system.web> <authentication mode="Forms"> <forms name=".AUTHCOOKIE" loginURL="login.aspx" protection="All" /> </authentication> <machineKey validationKey="Autogenerate" decryption key="Autogenerate" validation"SHA1" /> <authorization> <deny users="?" /> <authorization> </system.web> </configuration> |
Within the login page you could validate against a variety of data sources. This might be an XML file of users and passwords. This is an insecure solution however so should not be used for sensitive data though you could increase security by encrypting the passwords.
Alternatively you can use the credentials element of the web.config file, which is a sub-element of the <forms> element, as follows:
<credentials passwordFormat=”Clear”> <user name=”Chris” password=”Moniker” /> <user name=”Maria” password=”Petersburg” /> </credentials> |
Note also the passwordFormat attribute is required, and can be one of the following values:
Clear
Passwords are stored in clear text. The user password is compared directly to this value without further transformation.
MD5
Passwords are stored using a Message Digest 5 (MD5) hash digest. When credentials are validated, the user password is hashed using the MD5 algorithm and compared for equality with this value. The clear-text password is never stored or compared when using this value. This algorithm produces better performance than SHA1.
SHA1
Passwords are stored using the SHA1 hash digest. When credentials are validated, the user password is hashed using the SHA1 algorithm and compared for equality with this value. The clear-text password is never stored or compared when using this value. Use this algorithm for best security.
What is hashing? Hash algorithms map binary values of an arbitrary length to small binary values of a fixed length, known as hash values. A hash value is a unique and extremely compact numerical representation of a piece of data. The hash size for the SHA1 algorithm is 160 bits. SHA1 is more secure than the alternate MD5 algorithm, at the expense of performance.
At this time there is no ASP.Net tool for creating hashed passwords for insertion into configuration files. However, there are classes and methods that make it easy for you to create them programmatically, in particular the FormsAuthentication class. It’s HashPasswordForStoringInConfigFile method can do the hashing. At a lower level, you can use the System.Security.Cryptography classes, as well. We'll be looking at the former method later in this article.
The flexibility of the authentication provider for Forms Authentication continues as we can select SQLServer as our data source though the developer needs then to write bespoke code for validating user credentials against the database. Typically you will then have a registration page to allow users to register their login details which will then be stored in SQLServer for use when the user then returns to a protected resource and is redirected to the login page by the forms authentication, assuming the corresponding cookie is not still in existence.
This raises a further feature - we would want to give all users access to the registration page so that they may register but other resources should be protected. Additionally, there may be a third level of security, for example an admin page to list all users registered with the system. In such a situation we can have multiple system.web sections in our web.config file to support the different levels of authorization, as follows:
<configuration> <system.web> <authentication mode="Forms"> <forms name=".AUTHCOOKIE" loginURL="login.aspx" protection="All" /> </authentication> <machineKey validationKey="Autogenerate" decryption key="Autogenerate" validation"SHA1" /> <authorization> <deny users="?" /> <authorization> </system.web> <location path="register.aspx"> <system.web> <authorization> <allow users="*,?" /> </authorization> </system.web> </location> <location path="admin.aspx"> <system.web> <authorization> <allow users="admin " /> <deny users="*" /> </authorization> </system.web> </location> </configuration> |
Alternatively you can have multiple web.config files, with that for a sub-directory overriding that for the application a whole, an approach that we shall implement later for completeness.
Finally, you may also perform forms authentication in ASP.Net against a Web Service, which we won’t consider any further as this could form an article in itself, and against Microsoft Passport. Passport uses standard web technologies such as SSL, cookies and Javascript and uses strong symmetric key encryption using Triple DES (3DES) to deliver a single sign in service where a user can register once and then has access to any passport enabled site.
In terms of specific authorities:
Passport is most appropriately utilized where your site will be used in conjunction with other Passport enabled sites and where you do not wish to maintain your own user credentials data source. This is not the case in our chosen problem domain where Passport would both be overkill and inappropriate.
SQLServer would be the correct solution for the most common web site scenario where you have many users visiting a site where the majority of content is protected. Then an automated registration facility is the obvious solution with a configuration as per the web.config file just introduced. In our chosen problem domain we have stated that we potentially have only a handful of users accounts accessing a small portion of the application functionality and hence SQLServer is not necessarily the best solution, though is perfectly viable.
Use of the credentials section of the forms element of web.config or a simple text/ XML file would seem most suitable for this problem domain. The extra security and simplicity of implementation offered by the former makes this the method of choice.
File authorization utilizes windows security services access control lists (ACLs) – using the authorized identity to do so. Further, ASP.Net allows further refinement based on the URL requested, as you may have recognized in the examples already introduced, as well as the HTTP request method attempted via the verb attribute, valid values of which are: GET, POST, HEAD or DEBUG. I can't think of many occasions in which you'd want to use this feature but you may have other ideas! You may also refer to windows roles as well as named users.
A few examples to clarify:
<authorization> <allow users=”Chris” /> <deny users=”Chris” /> <deny users=”*” /> </authorization> |
<authorization> <allow roles=”Administrators” /> <deny users=”*” /> </authorization> <authorization> <allow verbs=”GET, POST” /> </authorization> |
<system.web> <identity impersonate=”true” /> </system.web> |
<system.web> <identity impersonate=”false” userName=”domain\sullyc” password=”password” /> </system.web> |
ASP.Net will only impersonate during the request handler - tasks such as executing the compiler and reading configuration data occur as the default process account. This is configurable via the <processModel> section of your system configuration file (machine.config). Care should be taken however not to use an inappropriate (too powerful) account which exposes your system to the threat of attacks.
The situation is further complicated by extra features available in IIS6 … but we’ll leave those for another article perhaps as the situation is complex enough!
Let’s move onto developing a login solution for our chosen problem domain.
<authorization> <deny users="?" /> </authorization> |
Given the above scenario we have two security issues for further consideration:
Validation works exactly the same for authentication cookies as it does for view state: the <machineKey> element's validationKey is appended to the cookie, the resulting value is hashed, and the hash is appended to the cookie. When the cookie is returned in a request, ASP.Net verifies that it wasn't tampered with by rehashing the cookie and comparing the new hash to the one accompanying the cookie. Encryption works by encrypting the cookie, hash value and all with <machineKey>'s decryptionKey attribute. Validation consumes less CPU time than encryption and prevents tampering. It does not, however, prevent someone from intercepting an authentication cookie and reading its contents.
Encrypted cookies can't be read or altered, but they can be stolen and used illicitly. Time-outs are the only protection a cookie offers against replay attacks, and they apply to session cookies only. The most reliable way to prevent someone from spoofing your site with a stolen authentication cookie is to use an encrypted communications link (HTTPS). Talking of which, this is one situation when you might want to turn off both encryption and validation. There is little point encrypting the communication again if you are already using HTTPS.
Whilst on the subject of cookies, remember also that cookie support can be turned off via the client browser. This should also be borne in mind when designing your application.
Yes is the answer. Thus if you want a secure solution but don't want the overhead of encrypting communications to all parts of your site, consider at least submitting user names and passwords over HTTPS, this assuming your web hosting service provides this.
To reiterate, the forms security model allows us to configure keys to use for encryption and decryption of forms authentication cookie data. Here we have a problem - this only encrypts the cookie data - the initial login screen data, i.e. email / password is not encrypted. We are using standard HTTP transmitting data in clear text which is susceptible to interception. The only way around this is to go to HTTPS and a secure communication channel.
Which perhaps begs the question – what is the point of encrypting the cookie data if our access is susceptible anyway if we are using an unsecured communication channel? Well, if we enable cookie authentication when we first login then subsequent interaction with the server will be more secure. After that initial login a malicious attacker could not easily gain our login details and gain access to the site simply by examining the contents of the packets of information passed to and from the web server. However, note the earlier comments on cookie theft. It is important to understand these concepts and the impact our decisions have on the overall security of our application data.
It is perhaps unsurprising given the above that for the most secure applications:
It is up to the application architect/ programmer to decide whether this level of security is appropriate to their system.
Finally, before we actually come up with some code remember that forms based security secures only ASP.Net resources. It doesn’t protect HTML files, for example. Just because you have secured a directory using web.config / ASP.Net doesn’t mean you have secured all files in that directory. To do this you could look at features available via IIS.
Starting with our web.config file. We can secure the sub-directory either via the location element, as described above, but just to demonstrate the alternative double web.config based approach, here is the web.config at the root level:
<configuration> <system.web> <authentication mode="Forms"> <forms name=".AUTHCOOKIE" loginUrl="login_credentials.aspx" protection="All"> <credentials passwordFormat="Clear"> <user name="chris" password="password" /> </credentials> </forms> </authentication> <machineKey validationKey="AutoGenerate" decryptionKey="AutoGenerate" validation="SHA1" /> <authorization> <allow users="*" /> </authorization> </system.web> </configuration> |
<configuration> <system.web> <authorization> <deny users="?" /> </authorization> </system.web> </configuration> |
Onto the login file: you will need form fields to allow entry of username and password data. Note that security will be further improved by enforcing minimum standards on passwords (e.g. length), which can be achieved by validation controls. There is only minimal validation in the example. Note that there is no facility to request a ‘persistent cookie’ as this provides a minor security risk. It is up to you to decide whether a permanent cookie is acceptable in your application domain.
Then in the login file, login_credentials.aspx, after allowing the user to enter username and password data, in the sub executed on the server when the submit form button is clicked we validate the entered data against the web.config credentials data, achieved simply as follows:
If FormsAuthentication.Authenticate(Username.Value, UserPass.Value) Then FormsAuthentication.RedirectFromLoginPage (UserName.Value, false) Else Msg.text="credentials not valid" End If |
Back to web.config to improve the security. The details are being stored unencrypted – we can encrypt them with the aforementioned HashPasswordForStoringInConfigFile of the FormsAuthentication class, achieved simply as follows:
Private Function encode(ByVal cleartext As String) As String encode = FormsAuthentication.HashPasswordForStoringInConfigFile(cleartext, "SHA1") Return encode End Function |
Thus, our new improved configuration section of our root web.config file becomes:
<credentials passwordFormat="SHA1"> <user name="chris" password="5BAA61E4C9B93F3F0682250B6CF8331B7EE68FD8" /> </credentials> |
Root/web.config | root web.config file |
Root/webform1.aspx | test page |
Root/login_credentials.aspx | login page |
Root/encode.aspx | form to SHA1 encode a password for <credentials> |
Root/secure/web.config | directives to override security for this sub-directory to deny anonymous access |
Root/secure/webform1.aspx | test page |
In summary you should consider forms based authentication when:
You should not consider forms based authentication when:
Further security considerations for forms based authentication:
Finally, different authorities are appropriate for form-based authentication for different problem domains. For our considered scenario where the number of users was limited as we were only protecting a specific administrative resource credentials / XML file based authorities are adequate. For a scenario where all site information is ‘protected’ a database authority is most likely to be the optimal solution.
.Net SDK documentation
Various online articles, in particular:
ASP.Net Security: An Introductory Guide to Building and Deploying More Secure Sites with ASP.Net and IIS -- MSDN Magazine, April 2002
http://msdn.microsoft.com/msdnmag/issues/02/04/ASPSec/default.aspx
An excellent and detailed introduction to IIS and ASP.Net security issues.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/authaspdotnet.asp
Authentication in ASP.Net: .Net Security Guidance
You may download the code here.
本文地址:http://com.8s8s.com/it/it43730.htm