[PLinq] Move NET_4_0 define check under licence text
[mono.git] / mcs / class / System.Web / System.Web.Security / FormsAuthenticationModule.cs
index 36f7b3bff4b7624c9700d2e7dcb1bf17b463896f..cab57fea2f2ff83ab4b858d4e5947ac9b7c4d058 100644 (file)
@@ -27,6 +27,8 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+using System.ComponentModel;
+using System.Globalization;
 using System.Security.Permissions;
 using System.Security.Principal;
 using System.Text;
@@ -39,6 +41,33 @@ namespace System.Web.Security
        [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
        public sealed class FormsAuthenticationModule : IHttpModule
        {
+               static readonly object authenticateEvent = new object ();
+               
+#if NET_2_0
+               AuthenticationSection _config = null;
+#else
+               AuthConfig _config = null;
+#endif
+               bool isConfigInitialized = false;
+               EventHandlerList events = new EventHandlerList ();
+               
+               public event FormsAuthenticationEventHandler Authenticate {
+                       add { events.AddHandler (authenticateEvent, value); }
+                       remove { events.RemoveHandler (authenticateEvent, value); }
+               }
+               
+               void InitConfig (HttpContext context)
+               {
+                       if(isConfigInitialized)
+                               return;
+#if NET_2_0
+                       _config = (AuthenticationSection) WebConfigurationManager.GetSection ("system.web/authentication");
+#else
+                       _config = (AuthConfig) context.GetConfig ("system.web/authentication");
+#endif
+                       isConfigInitialized = true;
+               }
+
                [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
                public FormsAuthenticationModule ()
                {
@@ -64,40 +93,46 @@ namespace System.Web.Security
                        string loginPage;
                        bool slidingExpiration;
 
-#if NET_2_0
-                       AuthenticationSection config = (AuthenticationSection) WebConfigurationManager.GetSection ("system.web/authentication");
-#else
-                       AuthConfig config = (AuthConfig) context.GetConfig ("system.web/authentication");
-#endif
-
-                       if (config == null || config.Mode != AuthenticationMode.Forms) {
+                       InitConfig (context);
+                       if (_config == null || _config.Mode != AuthenticationMode.Forms) {
                                return;
                        }
 
 #if NET_2_0
-                       cookieName = config.Forms.Name;
-                       cookiePath = config.Forms.Path;
-                       loginPage = config.Forms.LoginUrl;
-                       slidingExpiration = config.Forms.SlidingExpiration;
+                       cookieName = _config.Forms.Name;
+                       cookiePath = _config.Forms.Path;
+                       loginPage = _config.Forms.LoginUrl;
+                       slidingExpiration = _config.Forms.SlidingExpiration;
 #else
-                       cookieName = config.CookieName;
-                       cookiePath = config.CookiePath;
-                       loginPage = config.LoginUrl;
-                       slidingExpiration = config.SlidingExpiration;
+                       cookieName = _config.CookieName;
+                       cookiePath = _config.CookiePath;
+                       loginPage = _config.LoginUrl;
+                       slidingExpiration = _config.SlidingExpiration;
 #endif
 
-                       string reqPath = "";
+                       if (!VirtualPathUtility.IsRooted (loginPage))
+                               loginPage = "~/" + loginPage;
+
+                       string reqPath = String.Empty;
                        string loginPath = null;
                        try {
                                reqPath = context.Request.PhysicalPath;
                                loginPath = context.Request.MapPath (loginPage);
                        } catch {} // ignore
 
-                       context.SkipAuthorization = (reqPath == loginPath);
+                       context.SkipAuthorization = String.Compare (reqPath, loginPath, RuntimeHelpers.CaseInsensitive, Helpers.InvariantCulture) == 0;
                        
+#if NET_2_0
+                       //TODO: need to check that the handler is System.Web.Handlers.AssemblyResourceLoader type
+                       string filePath = context.Request.FilePath;
+                       if (filePath.Length > 15 && String.CompareOrdinal ("WebResource.axd", 0, filePath, filePath.Length - 15, 15) == 0)
+                               context.SkipAuthorization = true;
+#endif
+
                        FormsAuthenticationEventArgs formArgs = new FormsAuthenticationEventArgs (context);
-                       if (Authenticate != null)
-                               Authenticate (this, formArgs);
+                       FormsAuthenticationEventHandler eh = events [authenticateEvent] as FormsAuthenticationEventHandler;
+                       if (eh != null)
+                               eh (this, formArgs);
 
                        bool contextUserNull = (context.User == null);
                        if (formArgs.User != null || !contextUserNull) {
@@ -110,8 +145,15 @@ namespace System.Web.Security
                        if (cookie == null || (cookie.Expires != DateTime.MinValue && cookie.Expires < DateTime.Now))
                                return;
 
-                       FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt (cookie.Value);
-                       if (ticket == null || (ticket.IsPersistent && ticket.Expired))
+                       FormsAuthenticationTicket ticket = null;
+                       try {
+                               ticket = FormsAuthentication.Decrypt (cookie.Value);
+                       }
+                       catch (ArgumentException) {
+                               // incorrect cookie value, suppress the exception
+                               return;
+                       }
+                       if (ticket == null || (!ticket.IsPersistent && ticket.Expired))
                                return;
 
                        FormsAuthenticationTicket oldticket = ticket;
@@ -139,23 +181,20 @@ namespace System.Web.Security
                                return;
 
                        string loginPage;
+                       InitConfig (context);
 #if NET_2_0
-                       AuthenticationSection config = (AuthenticationSection) WebConfigurationManager.GetSection ("system.web/authentication");
-                       loginPage = config.Forms.LoginUrl;
+                       loginPage = _config.Forms.LoginUrl;
 #else
-                       AuthConfig config = (AuthConfig) context.GetConfig ("system.web/authentication");
-                       loginPage = config.LoginUrl;
+                       loginPage = _config.LoginUrl;
 #endif
-                       if (config == null || config.Mode != AuthenticationMode.Forms)
+                       if (_config == null || _config.Mode != AuthenticationMode.Forms)
                                return;
 
                        StringBuilder login = new StringBuilder ();
                        login.Append (UrlUtils.Combine (context.Request.ApplicationPath, loginPage));
                        login.AppendFormat ("?ReturnUrl={0}", HttpUtility.UrlEncode (context.Request.RawUrl));
-                       context.Response.Redirect (login.ToString ());
+                       context.Response.Redirect (login.ToString (), false);
                }
-
-               public event FormsAuthenticationEventHandler Authenticate;
        }
 }