2008-05-30 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.Security / FormsAuthenticationModule.cs
index 5cfa8c2901d307e26e3efd22bdd6e00132acaefa..fb14b524ed93e45b67601134da50742a43c15421 100644 (file)
@@ -5,8 +5,7 @@
 //     Gonzalo Paniagua Javier (gonzalo@ximian.com)
 //
 // (C) 2002 Ximian, Inc (http://www.ximian.com)
-//
-
+// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using System;
+using System.ComponentModel;
+using System.Security.Permissions;
 using System.Security.Principal;
 using System.Text;
-using System.Web;
 using System.Web.Configuration;
 using System.Web.Util;
 
 namespace System.Web.Security
 {
+       // CAS - no InheritanceDemand here as the class is sealed
+       [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); }
+               }
+               
+               private 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 ()
+               {
+               }
+
                public void Dispose ()
                {
                }
@@ -53,22 +86,49 @@ namespace System.Web.Security
                {
                        HttpApplication app = (HttpApplication) sender;
                        HttpContext context = app.Context;
-                       AuthConfig config = (AuthConfig) context.GetConfig ("system.web/authentication");
-                       if (config.Mode != AuthenticationMode.Forms) {
+
+                       string cookieName;
+                       string cookiePath;
+                       string loginPage;
+                       bool slidingExpiration;
+
+                       InitConfig (context);
+                       if (_config == null || _config.Mode != AuthenticationMode.Forms) {
                                return;
                        }
 
-                       string cookieName = config.CookieName;
-                       string cookiePath = config.CookiePath;
-                       string loginPage = config.LoginUrl;
+#if NET_2_0
+                       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;
+#endif
+
+                       string reqPath = "";
+                       string loginPath = null;
+                       try {
+                               reqPath = context.Request.PhysicalPath;
+                               loginPath = context.Request.MapPath (loginPage);
+                       } catch {} // ignore
 
-                       string reqPath = context.Request.PhysicalPath;
-                       string loginPath = context.Request.MapPath (loginPage);
                        context.SkipAuthorization = (reqPath == loginPath);
                        
+#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) {
@@ -81,15 +141,26 @@ 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;
 
-                       if (config.SlidingExpiration)
+                       FormsAuthenticationTicket oldticket = ticket;
+                       if (slidingExpiration)
                                ticket = FormsAuthentication.RenewTicketIfOld (ticket);
 
                        context.User = new GenericPrincipal (new FormsIdentity (ticket), new string [0]);
 
+                       if (cookie.Expires == DateTime.MinValue && oldticket == ticket) 
+                               return;
+
                        cookie.Value = FormsAuthentication.Encrypt (ticket);
                        cookie.Path = cookiePath;
                        if (ticket.IsPersistent)
@@ -105,17 +176,21 @@ namespace System.Web.Security
                        if (context.Response.StatusCode != 401 || context.Request.QueryString ["ReturnUrl"] != null)
                                return;
 
-                       AuthConfig config = (AuthConfig) context.GetConfig ("system.web/authentication");
-                       if (config.Mode != AuthenticationMode.Forms)
+                       string loginPage;
+                       InitConfig (context);
+#if NET_2_0
+                       loginPage = _config.Forms.LoginUrl;
+#else
+                       loginPage = _config.LoginUrl;
+#endif
+                       if (_config == null || _config.Mode != AuthenticationMode.Forms)
                                return;
 
                        StringBuilder login = new StringBuilder ();
-                       login.Append (UrlUtils.Combine (context.Request.ApplicationPath, config.LoginUrl));
+                       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;
        }
 }