Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 64 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
64
Dung lượng
0,95 MB
Nội dung
Demanding Permissions from a Configuration Class There is little known capability in the configuration system that you can use for supporting partial trust applications. You can use a custom configuration class as a kind of gatekeeper to a feature and prevent the feature from being used in a partial trust application. If you remember back to the Chapter 3 on trust levels, and the discussion on the “ processRequestInApplicationTrust” attribute, there is a subtle issue with features and code being called when only trusted code is on the stack. Custom configuration classes are part of this issue because when configuration is being loaded, it isn’t guaranteed that there will be any user code on the stack. More importantly, the feature that carries out work and that consumes the configuration information may itself always be called with trusted code on the stack. Scenarios like GAC’d classes that are HttpModules have this problem. An HttpModule only has the ASP.NET pipeline code sitting above it, so any demands a custom HttpModule located in the GAC makes always succeed. A feature can indirectly work around this problem by taking advantage of the fact that the configuration system calls PermitOnly on the named permission set for the current trust level. This behavior is the same approach that the page handler takes when it calls PermitOnly prior to running a page. The configuration system makes this call just before attempting to deserialize a configuration section. As a result, a custom configuration class that overrides ConfigurationSection.PostDeserialize can demand an appropriate permission in an override of this method. using System; using System.Data.SqlClient; using System.Security.Permissions; using System.Configuration; public class SampleConfigClass : ConfigurationSection { public SkeletalConfigClass() {} protected override void PostDeserialize() { SqlClientPermission scp = new SqlClientPermission(PermissionState.Unrestricted); scp.Demand(); } //the rest of the configuration class } The previous configuration class demands the SqlClientPermission. Because the configuration sys- tem restricts the set of allowed permissions to whatever is defined for the application’s current trust level prior to the deserialization process, the sample configuration class is usable only if the current trust level grants the SqlClientPermission. If a feature living in the GAC attempts to read its configuration information and the current trust level doesn’t grant this permission, the feature initialization fails because any attempt to read its configuration always fails with a SecurityException. Given this capability, when would you actually use it? Should you always demand something from your custom configuration class? If you know your GAC’d code is going to be called in scenarios where only trusted code exists on the stack, you should make use of the PostDeserialize method. It is the only point when you will have a chance to enforce a CAS restriction. Identifying these scenarios can be diffi- cult though. If your feature includes a GAC’d HttpModule, this is one obvious case. A custom handler 165 Configuration System Security 07_596985 ch04.qxp 12/14/05 7:47 PM Page 165 that is deployed in the GAC would be another example where using PostDeserialize as a surrogate trust enforcement mechanism makes sense. However, it may impossible to make an intelligent demand in PostDeserialize if you depend on the code that consumes your feature to supply dynamic information. For example, if your feature reads and writes to the file system, you may not know which path to demand permission against until after some consumer code sets some properties on your feature. As a result the PostDeserialize method is appro- priate only for demanding permissions that always need to be statically configured in a trust policy file. FileIOPermission and the Design-Time API Unlike the runtime portion of the configuration API (for example GetSection), the design-time API always results in physical file I/O operations occurring up the chain of parent configuration files. Because in Medium trust an ASP.NET application only has rights to read and write files within the application’s directory structure, partial trust code doesn’t have rights to open files outside the application. For this rea- son, the design-time API is basically useless when running in Medium trust or below. Although you could theoretically tweak the lower trust levels’ policy files to get the design-time API working, it is better to con- sider the design-time API suitable only for full trust or High trust applications. If you attempt to use one of the design-time APIs such as WebConfigurationManager.OpenWebConfiguration in partial trust, you will run into an exception like the following: SecurityException: Request for the permission of type ‘System.Security.Permissions.FileIOPermission, ’ failed.] snip System.Security.CodeAccessPermission.Demand() System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy) System.IO.FileStream ctor(String path, FileMode mode, FileAccess access, FileShare share) snip System.Configuration.UpdateConfigHost.OpenStreamForRead(String streamName) System.Configuration.BaseConfigurationRecord.InitConfigFromFile() This stack trace shows that the open attempt eventually results in the use of the FileStream object. Attempting to open a FileStream on top of a file always results in a demand for a FileIOPermission. So, long before the configuration system ever gets around to demanding ConfigurationPermission, the file I/O that occurs during a call to OpenWebConfiguration in a partial trust application will fail. This behavior is another reason the design-time APIs are useful only in High and Full trust web applications. Protected Configuration Since ASP.NET 1.0 a common request has been for a way to safely store sensitive configuration informa- tion and shield it from prying eyes. The most common information that developers want to protect are connection strings because these frequently contain username-password pairs. But sorts of interesting information beyond connection strings is contained within ASP.NET configuration files. If you use the 166 Chapter 4 07_596985 ch04.qxp 12/14/05 7:47 PM Page 166 <identity /> section, you again have credentials stored in configuration. If you use classes in the System.Net namespace, you may have configuration elements listing out SMTP servers or other network endpoints, and so on. The 2.0 Framework introduces a new feature to deal with this problem called protected configuration. Protected configuration is a way to take selected pieces of any configuration file and store the configuration information instead in a secure and encrypted format. The great thing about the protected configuration feature is that it can be used with just about any configuration section—both ASP.NET and non-ASP.NET configuration sections. As with other features in ASP.NET, protected configuration is provider-based, so you can buy or write alternative protected configuration providers instead of using the built-in providers. Out of the box, the .NET Framework ships with two protected configuration providers: ❑ System.Configuration.DPAPIProtectedConfigurationProvider ❑ System.Configuration.RsaProtectedConfigurationProvider As the class names suggest, the first provider uses the data protection API (DPAPI) functionality in Windows to encrypt and decrypt configuration sections. The second provider uses the public-key RSA algorithm for performing the same functionality. The basic idea behind protected configuration is that you use the aspnet_regiis command-line tool, or the configuration API (the SectionInformation.ProtectSection and SectionInformation .UnprotectSection methods to be precise) to encrypt selected pieces of your configuration informa- tion prior to putting an application into production. Then at runtime the configuration system decrypts the protected configuration information just prior to handing the configuration information back to the requesting code. The important thing is that protecting a configuration section is transparent to the features that rely on the configuration section. No feature code has to change just because an underlying configuration section has been encrypted. When you use protected configuration you start with some configuration section that might look like the following: <machineKey validationKey=”123456789012345678901234567890123456789012345678” decryptionKey=”123456789012345678901234567890123456789012345678” /> This is a perfect example of the type of section you probably would like to protect. You would rather not have any random person with read access to your web.config walking away with the signing and vali- dation keys for your application. You can encrypt this configuration section from the command line using the aspnet_regiis tool: aspnet_regiis -pe system.web/machineKey -app /Chapter4/ConfigurationSample -prov DataProtectionConfigurationProvider After you use the protected configuration feature, the <machineKey /> section looks something like the following: <machineKey configProtectionProvider=”DataProtectionConfigurationProvider”> <EncryptedData> 167 Configuration System Security 07_596985 ch04.qxp 12/14/05 7:47 PM Page 167 <CipherData> <CipherValue>encrypted data here</CipherValue> </CipherData> </EncryptedData> </machineKey> Of course, instead of the text “encrypted data here,” the actual result has about five lines of text containing the base-64 encoded representation of the encrypted blob for the <machineKey /> section. When you run the application everything still works normally though because internally the configuration system trans- parently decrypts the section using the extra information added to the <machineKey /> element. Depending on whether you use the RSA- or the DPAPI-based provider, different information will show up within the <machineKey /> element. In the previous example, the configuration system added the configProtectionProvider attribute to the <machineKey/> element. This is a pointer to one of the protected configuration providers defined in machine.config. At runtime, the configuration system instantiates the specified provider and asks it to decrypt the contents of the <EncryptedData /> ele- ment. This means that custom protected configuration providers can place additional information within the <EncryptedData /> element containing any extra information required by the provider to success- fully decrypt the section. In the case of the DPAPI provider, no additional information behind the encrypted blob that is necessary. What Can’t You Protect? Protected configuration sounds like the final answer to the age-old problem of encrypting connection strings. However, due to the interaction between app-domain startup and configuration you cannot blindly encrypt every single configuration section in your configuration files. In some cases, you have a “chicken-and-egg” effect where ASP.NET or the Framework needs to read configuration information to bootstrap itself, but it has to do this prior to having read the configuration information that defines the protected configuration providers. The following list names some configuration sections (this is not an exhaustive list) that you may have in your various configuration files that can’t be encrypted with protected configuration: ❑ processModel —ASP.NET needs to be able to read this just as it is starting up. Furthermore, for IIS5 and IIS 5.1 it controls the identity of the worker process, so you would be in a Catch-22 situ- ation if you needed the correct worker process identity in order to read protected configuration. ❑ startup and runtime —These configuration sections are used by the Framework to determine things such as which version of the Framework to load as well as information on assembly redirection. ❑ cryptographySettings —This configuration section defines the actual cryptography classes used by the framework. Because protected configuration depends on some of these classes, you can’t encrypt the configuration section that contains information about the algorithms used by the protected configuration feature. ❑ configProtectedData —This is the configuration section that contains the definition of the pro- tected configuration providers on the machine. This would also be a Catch-22 if the section were encrypted because the configuration system needs to be able to read this section to get the appropriate provider for decrypting other configuration sections. 168 Chapter 4 07_596985 ch04.qxp 12/14/05 7:47 PM Page 168 Selecting a Protected Configuration Provider Now that you know you have at least two different options for encrypting configuration information, you need to make a decision about which one to use. Additionally, you need to determine how you want to use each provider. The criteria for selecting and then configuring a provider revolve around two questions: ❑ Do you need to share configuration files across machines? ❑ Do you need to isolate encrypted configuration data between applications? The first question is relevant for those of you that need to deploy an application across multiple machines in a web farm. Obviously in a load-balanced web farm, you want an application that is deployed on multiple machines to use the same set of configuration data. You can use either the DPAPI provider or the RSA provider for this scenario. Both providers require some degree of setup to work properly in a web farm. Of the two providers, the RSA provider is definitely the more natural fit. With the DPAPI provider, you would need to do the following to deploy a web.config file across multiple machines: 1. Deploy the unencrypted configuration file to each web server. 2. On each web server, run aspnet_regiis to encrypt the desired configuration sections. The reason for this is that the DPAPI provider relies on machine-specific information, and this information it not portable across machines. Although you can make the DPAPI provider work in a web farm, you will probably get tired of constantly reencrypting configuration sections each time you push a new configuration file to a web farm. The RSA provider depends on key containers that contain the actual key material for encrypting and decrypting configuration sections. For a web farm, you would perform a one-time setup to synchronize a key container across all the machines in a web farm. After you create a common key container across all machines in the farm, you can encrypt a configuration file once on one of the machines — perhaps even using a utility machine that is not part of the web farm itself but that still has the common key container. When you push the encrypted configuration file to all machines in the web farm, each web server is able to decrypt the protected configuration information because each machine has access to a common set of keys. The second question around isolation of encryption information deals with how the encryption keys are protected from other web applications. Both the DPAPI and the RSA providers can use keys that are accessible machine-wide, or use keys that are accessible to only a specific user identity. RSA has the additional functionality of using machine-wide keys that only grant access to specific user accounts. Currently, the recommendation is that if you want to isolate key material by user account, you should separate your web applications into different application pools in IIS6, and you should use the RSA provider. This allows you to specify a different user account for each worker process. Then when you configure the RSA protected configuration providers, you take some extra steps to ensure that encryp- tion succeeds only while running as a specific user account. At runtime, this means that even if one application can somehow gain access to another application’s configuration data, the application will not be able to decrypt it because the required key material is associated with a different identity. 169 Configuration System Security 07_596985 ch04.qxp 12/14/05 7:47 PM Page 169 Both the DPAPI and RSA have per-user modes of operation that can store encryption material directly associated with a specific user account. However, both of these technologies have the limitation that the Windows user profile for the process identity needs to be loaded into memory before it can access the necessary keys. Loading of the Windows user profile does not happen on IIS6 (it will occur though for other reasons in IIS5/5.1). As a result the per-user modes for the DPAPI and RSA providers really aren’t useful for web applications. There is another aspect to isolating encryption data for the DPAPI provider because the provider supports specifying an optional entropy value to use during encryption and decryption. The entropy value is essen- tially like a second piece of key material. Two different applications using different entropy values with DPAPI will be unable to read each other’s data. However, using entropy is probably more suitable when you want the convenience of using the machine-wide store in DPAPI, but you still want some isolation between applications. The following table summarizes the provider options that you should consider before setting up pro- tected configuration for use in ASP.NET: Need to Support Multiple Machines Only Deploy on a Single Machine Sharing key RSA provider. Either the RSA or the DPAPI material is acceptable provider will work Use the default machine-wide Use the machine-wide options key container, and grant Read for either provider. access to all accounts. Can optionally use key entropy with DPAPI provider Can optionally use RSA key containers with different ACLs. Key material should RSA provider. RSA provider. be isolated Use machine-wide RSA key Use machine-wide RSA key containers, but ACL different key containers, but ACL different key containers to different user identities. containers to different identities. DPAPI per-user key containers require a loaded user profile and thus should not be used. RSA per-user key containers also require a loaded user profile and thus should not be used. 170 Chapter 4 07_596985 ch04.qxp 12/14/05 7:47 PM Page 170 171 Configuration System Security Caveat When Using Stores That Depend on User Identity If you choose to use either provider with their per-user mode of operation or if you use machine-wide RSA key containers that are ACL’d to specific users, you need to be aware of an issue with using protected configuration. The sequence in which ASP.NET reads and then deserializes configuration sections is not fixed. Although ASP.NET internally obtains configuration sections in a certain sequence during app-domain startup, this sequence may very well change in the future. One very important configuration section that is read early on during app-domain startup is the <identity /> section. You can use <identity /> to configure applica- tion impersonation for ASP.NET. However, if you use RSA key containers for example that depend on specific user identities you can end up in a situation where ASP.NET starts initially running as a specific process identity (NETWORK SERVICE by default on IIS6), and then after reading the <identity /> section it switches to running as the defined application impersonation identity. This can lead to a situation where you have granted permission on an RSA key con- tainer to an IIS6 worker process account, and suddenly other configuration sections are no longer decrypting properly because they are being decrypted after ASP.NET switches over to the application impersonation account. As a result, you should always configure and ACL key stores on the basis of a known process identity. For IIS6 this means setting up protected configuration based on the identity that will be used for an individual worker process. If your applications need to run as different identities, instead of using application impersonation on IIS6 you should separate the applications into different application pools (aka worker processes). This guarantees that at runtime ASP.NET will always be running with a stable identity, and thus regardless of the order in which ASP.NET reads configuration sections during app- domain startup, protected configuration sections will always be capable of being decrypted using the same identity. For older versions like IIS5 and IIS 5.1, you can choose a different process identity using the <processModel /> element. However, application impersonation is really the only way to isolate applications by identity on these older versions of IIS. Although you could play around with different configuration sections to determine which ones are being read with the identity defined in <processModel /> and which ones are read using the application impersonation identity in <identity />, you could very well end up with a future service pack subtly changing the order in which configura- tion sections are deserialized. As a result, the recommendation for IIS5/5.1 is to upgrade to IIS6 if you want to use a feature like RSA key containers with user-specific ACLs. Granted that this may sound a bit arbitrary, but using key storage that depends on specific identities with protected configuration gets somewhat complicated as you will see in a bit. Attempting to keep track of the order of configuration section deserialization adds to this complexity and if depended on would result in a rather brittle approach to securing configuration sec- tions. Separating applications with IIS6 worker processes is simply a much cleaner and more maintainable approach over the long term. 07_596985 ch04.qxp 12/14/05 7:47 PM Page 171 Defining Protected Configuration Providers The default protected configuration providers are defined in machine.config: <configProtectedData defaultProvider=”RsaProtectedConfigurationProvider”> <providers> <add name=”RsaProtectedConfigurationProvider” type=”System.Configuration.RsaProtectedConfigurationProvider, “ description=”Uses RsaCryptoServiceProvider to encrypt and decrypt” keyContainerName=”NetFrameworkConfigurationKey” cspProviderName=”” useMachineContainer=”true” useOAEP=”false” /> <add name=”DataProtectionConfigurationProvider” type=”System.Configuration.DpapiProtectedConfigurationProvider, ” description=”Uses CryptProtectData and CryptUnProtectData “ useMachineProtection=”true” keyEntropy=”” /> </providers> </configProtectedData> If you author or purchase a custom provider, you would configure it in the <configProtectedData /> section and assign it a name so that tools like aspnet_regiis can make use of it. Other than the “name” and “type” attributes, all of the information you see on the provider <add /> elements is unique to each specific provider. Custom providers can support their own set of configuration properties that you can then define when you configure them with the <add /> element. As with most other provider-based features, you can define as many protected configuration providers as you want. Then when using a tool like apnet_regiis, writing code with the ProtectSetion method, or creating web.config files, you can reference one of the protected configuration providers from <configProtectedData /> by name. For example, the -prov command-line switch you saw ear- lier on aspnet_regiis refers to a named provider within <configProtectedData/>. In these scenar- ios, if you do not explicitly select a provider, then the value of defaultProvider on the <configProtectedData /> element is used. This means that by default the RSA provider is used for protected configuration. DpapiProtectedConfigurationProvider This protected configuration provider uses the data protection API (DPAPI) that is part of Windows. This functionality will probably be familiar to those of you who used the aspnet_setreg tool back in ASP.NET 1.1 or who wrote a managed DPAPI wrapper for use in applications. The nice thing about the DPAPI provider is that it is very easy to use. Configuring the provider is quite simple because you need to consider only two provider-specific options: ❑ keyEntropy —This is a string value containing some random information that will be used during the encryption process. If you use a different keyEntropy value for each application, applications that share the same set of DPAPI encryption keys still cannot read each other’s pro- tected configuration data. 172 Chapter 4 07_596985 ch04.qxp 12/14/05 7:47 PM Page 172 ❑ useMachineProtection —Because DPAPI has the concept of a machine store and a per-user store, this configuration attribute indicates which one to use. If you set this attribute to true (the default), all applications can decrypt each other’s protected configuration data. If you set this attribute to false, then only applications running under the same credentials will be able to decrypt each other’s protected configuration data. The DPAPI provider should really be used only for single-machine applications. Although you can go through a manual step whereby you always reencrypt your configuration files after they have been deployed to a machine, this is inconvenient. Furthermore, it opens up the possibility of someone forget- ting to encrypt a configuration file (and remember you may need to encrypt multiple configuration files up the configuration inheritance hierarchy). keyEntropy The keyEntropy option is only useful for giving a modicum of protection against two different applica- tions reading each other’s configuration data when useMachineProtection is set to true. With the machine-wide DPAPI key store technically anyone who can get code onto the machine will be able to successfully decrypt your protected configuration data. Specifying an entropy value gives you a lightweight approach to protecting the encrypted data. You can use keyEntropy with the per-user mode of operation for DPAPI as an additional layer of protection although the per-user mode for the DPAPI provider is not suitable for use with web applications. If each web application uses a different keyEntropy parameter in its configuration, only code with knowledge of that value will be able to read the configuration data. Of course, the management problem with using keyEntropy is that you need a separate provider definition for each different keyEntropy value. If you have a fair number of applications to protect on a server, and you want to isolate the encrypted data between each application, you can easily end up with dozens of provider definitions just so that you can use a different keyEntropy value for each application. There is also the related issue that you need to ACL the appropriate configuration files so that random users cannot open them and read the configuration. Placing the different provider definitions in machine.config or the root web.config prevents applications running at Medium trust or lower from being able to use the strongly typed configuration classes to read the raw provider definitions (note that the actual provider class DpapiProtectedConfigurationProvider doesn’t expose the keyEntropy value as a property). However High and Full trust applications have the ability to open any file on the file system (ACLs permitting). For these types of applications, you need to run each application in a separate application pool with each application pool being assigned a different user identity. With this approach, you can then place each application’s provider definition within the application’s web.config file, and the ACLs prevent one worker process from reading the configuration file from another application. If you were to leave the application-specific provider definition in machine.config or web.config, Full and High trust applications would be able to open these files and read the keyEntropy attribute. Using keyEntropy is pretty basic: You just define another instance of the DPAPI provider and put any value you want as a value for this attribute: <configProtectedData> <providers> <add name=”AppSpecificDPAPIProvider” type=”System.Configuration.DpapiProtectedConfigurationProvider ” 173 Configuration System Security 07_596985 ch04.qxp 12/14/05 7:47 PM Page 173 useMachineProtection=”true” keyEntropy=”AD50GC20FKQ43%dj!@4F” /> </providers> </configProtectedData> You should set the keyEntropy value to something that cannot be easily guessed. In this case, I just used a random string of characters. Any long string of random values will work; there are no restrictions on the length of the keyEntropy configuration attribute. If another application attempts to decrypt a protected configuration section and uses a different entropy value, it receives an error message stating that the data in the configuration section is invalid. useMachineProtection The default DPAPI configuration uses the machine-wide DPAPI key store; if you configure the DPAPI provider and fail to set the useMachineProtection attribute, internally the provider will also default to using the machine-wide store. If you are running in a trusted environment and it doesn’t really matter if applications can read each other’s configuration data, this setting is reasonable. However, if you are on a machine that hosts applications from development groups that don’t trust each other, or if you have a business requirement that different applications should not be able to read each other’s configuration data, setting useMachineProtection to false is an option. If you set this attribute to false the identity of the application needs to be switched to a different user account (see the earlier section on using per-user key stores). Of course, after you change your application to run as a different identity, you already have the option of using file ACLs as a protection mechanism for prevent- ing other applications from reading your configuration data. In a sense, using the per-user mode of the DPAPI provider is an additional layer of protection above and beyond what you gain just by changing applications to run as different user identities. As mentioned earlier though, there is a pretty severe limitation if you set useMachineProtection to false. Due to the way DPAPI works, it needs access to the user profile for the process identity to access the key material. On IIS6 the user profile for a worker process account (specifically machine or domain accounts other than LOCAL SERVICE or NETWORK SERVICE) is never loaded by IIS. If you follow the steps outlined in this section everything will work until you reboot the machine and the side effects of the runas command window are lost. If you really, really want to get per-user DPAPI working, you need a hack such as launching runas from a scheduled task or having an NT service that forcibly loads the profile for a user identity. Realistically though, I would never depend on such workarounds for a production application, and hence the machine store for the DPAPI protected configuration provider is the only really viable option for web applications. Non-ASP.NET applications don’t have the limitation with the Windows user profile though, so you may be interested in using DPAPI user stores for securing configuration information used by a fat client application. To set up the provider for per-user DPAPI just change the useMachineProtection attribute to false: <configProtectedData> <providers> <add name=”AppSpecificDPAPIProvider” type=”System.Configuration.DpapiProtectedConfigurationProvider ” useMachineProtection=”false” </providers> </configProtectedData> 174 Chapter 4 07_596985 ch04.qxp 12/14/05 7:47 PM Page 174 [...]... investment in time and effort 197 Chapter 5 Securing the Ticket on the Wire By default, the forms authentication ticket is digitally encrypted and signed using a keyed hash This security has been available since ASP.NET 1.0, and ASP.NET 2.0 uses the same security for the ticket However, there have been some new questions over hash security and support for new encryption options in ASP.NET 2.0 How Secure... authentication ticket is protected, persisted and passed around applications For all practical purposes, developers use the terms “forms authentication ticket” and “forms authentication cookie” interchangeably Understanding Persistent Tickets Since ASP.NET 1.0, the forms authentication feature has supported persistent and nonpersistent tickets In ASP.NET 1.0 and 1.1 the forms authentication ticket was... used the local date-time representation for the expiration date In ASP.NET 2.0, the team considered changing this behavior through a configuration setting, but ultimately decided against it due to the following problems: ❑ Changing to a UTC-based expiration would break authentication in mixed ASP.NET 1.1 and ASP.NET 2.0 environments The ASP.NET 1.1 servers would think the expiration date was in local... wasn’t sitting in the GMT time zone of course!) ❑ Although a configuration switch for ASP.NET 2.0 was a possibility, this would introduce a fair amount of confusion around when to turn it on or off If the UTC time handling was turned on, and then later an ASP.NET 1.1 application was introduced into your web farm, ASP.NET 2.0 would have to be switched back to the original behavior In two scenarios, local... facing ASP.NET sites The appeal of forms authentication is that sites with only a few pages and simple authentication requirements can make use of forms authentication, and complex sites can still rely on forms authentication for the basic handling of authenticating users In ASP.NET 2.0, the core functionality of forms authentication remains the same, but some new security scenarios have been enabled and. .. Using forms authentication across ASP.NET 1.1 and ASP.NET 2.0 ❑ Leveraging the UserData property of FormsAuthenticationTicket ❑ Passing forms authentication tickets between applications ❑ Enforcing a single login and preventing replayed tickets after logout Chapter 5 Quick Recap on Forms Authentication In Chapter 2, the sections on AuthenticateRequest, AuthorizeRequest and EndRequest described how forms... recycle whenever you update configuration data stored in locations other than the standard file-based configuration files Summar y Configuration security in ASP.NET 2.0 includes quite a number of improvements While the original based locking approach is still supported (and is definitely still useful), ASP.NET 2.0 s configuration system now gives you the ability to enforce more granular control... though the ASP.NET 2.0 behavior changes the cookie expiration for new cookies issued using forms authentication, the new behavior has no effect on preexisting cookies If you upgrade an ASP.NET 1.1 application to ASP.NET 2.0, any users with 50-year cookies floating around will continue to retain these cookies Even if you use sliding expiration for your forms authentication tickets, because ASP.NET hasn’t... of text that results in a matching SHA1 hash) So, this new attack against SHA1 theoretically reduces the number of attempts by a pretty hefty 12083355238 042 7 046 90 544 64 iterations (after notepad, I think calc.exe is the most frequently entered command from the Run option in Windows) Suffice it say that that the current estimate of 2^69 attempts to find a SHA1 collision would still entail enormous computing... minimal security requirements, and so on) to store a representation of the authenticated user without constantly requiring users to log in again Clearly for some sites where users infrequently access the application (and hence are always forgetting their credentials), persistent cookies are a great usability enhancement The one “small” problem is that on ASP.NET 1.0 and ASP.NET 1.1 sites, persistent . the following: <machineKey validationKey=” 123 45 678 90 123 45 678 90 123 45 678 90 123 45 678 90 123 45 678” decryptionKey=” 123 45 678 90 123 45 678 90 123 45 678 90 123 45 678 90 123 45 678” /> This is a perfect example of. configProtectionProvider=”AppSpecificRSAProvider”> <EncryptedData Type=”http://www.w3.org / 20 01 / 04 /xmlenc#Element” xmlns=”http://www.w3.org / 20 01 / 04 /xmlenc#”> <EncryptionMethod Algorithm=”http://www.w3.org / 20 01 / 04 /xmlenc#tripledes-cbc” /> <KeyInfo. xmlns=”http://www.w3.org / 20 00/ 09/xmldsig#”> <EncryptedKey xmlns=”http://www.w3.org / 20 01 / 04 /xmlenc#”> <EncryptionMethod Algorithm=”http://www.w3.org / 20 01 / 04 /xmlenc#rsa-1_5” /> <KeyInfo