2 // System.Web.Security.FormsAuthenticationModule
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // (C) 2002 Ximian, Inc (http://www.ximian.com)
8 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Security.Permissions;
31 using System.Security.Principal;
33 using System.Web.Configuration;
34 using System.Web.Util;
36 namespace System.Web.Security
38 // CAS - no InheritanceDemand here as the class is sealed
39 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
40 public sealed class FormsAuthenticationModule : IHttpModule
43 AuthenticationSection _config = null;
45 AuthConfig _config = null;
47 bool isConfigInitialized = false;
49 private void InitConfig (HttpContext context)
51 if(isConfigInitialized)
54 _config = (AuthenticationSection) WebConfigurationManager.GetSection ("system.web/authentication");
56 _config = (AuthConfig) context.GetConfig ("system.web/authentication");
58 isConfigInitialized = true;
61 [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
62 public FormsAuthenticationModule ()
66 public void Dispose ()
70 public void Init (HttpApplication app)
72 app.AuthenticateRequest += new EventHandler (OnAuthenticateRequest);
73 app.EndRequest += new EventHandler (OnEndRequest);
76 void OnAuthenticateRequest (object sender, EventArgs args)
78 HttpApplication app = (HttpApplication) sender;
79 HttpContext context = app.Context;
84 bool slidingExpiration;
87 if (_config == null || _config.Mode != AuthenticationMode.Forms) {
92 cookieName = _config.Forms.Name;
93 cookiePath = _config.Forms.Path;
94 loginPage = _config.Forms.LoginUrl;
95 slidingExpiration = _config.Forms.SlidingExpiration;
97 cookieName = _config.CookieName;
98 cookiePath = _config.CookiePath;
99 loginPage = _config.LoginUrl;
100 slidingExpiration = _config.SlidingExpiration;
104 string loginPath = null;
106 reqPath = context.Request.PhysicalPath;
107 loginPath = context.Request.MapPath (loginPage);
110 context.SkipAuthorization = (reqPath == loginPath);
113 //TODO: need to check that the handler is System.Web.Handlers.AssemblyResourceLoader type
114 string filePath = context.Request.FilePath;
115 if (filePath.Length > 15 && String.CompareOrdinal ("WebResource.axd", 0, filePath, filePath.Length - 15, 15) == 0)
116 context.SkipAuthorization = true;
119 FormsAuthenticationEventArgs formArgs = new FormsAuthenticationEventArgs (context);
120 if (Authenticate != null)
121 Authenticate (this, formArgs);
123 bool contextUserNull = (context.User == null);
124 if (formArgs.User != null || !contextUserNull) {
126 context.User = formArgs.User;
130 HttpCookie cookie = context.Request.Cookies [cookieName];
131 if (cookie == null || (cookie.Expires != DateTime.MinValue && cookie.Expires < DateTime.Now))
134 FormsAuthenticationTicket ticket = null;
136 ticket = FormsAuthentication.Decrypt (cookie.Value);
138 catch (ArgumentException) {
139 // incorrect cookie value, suppress the exception
142 if (ticket == null || (!ticket.IsPersistent && ticket.Expired))
145 FormsAuthenticationTicket oldticket = ticket;
146 if (slidingExpiration)
147 ticket = FormsAuthentication.RenewTicketIfOld (ticket);
149 context.User = new GenericPrincipal (new FormsIdentity (ticket), new string [0]);
151 if (cookie.Expires == DateTime.MinValue && oldticket == ticket)
154 cookie.Value = FormsAuthentication.Encrypt (ticket);
155 cookie.Path = cookiePath;
156 if (ticket.IsPersistent)
157 cookie.Expires = ticket.Expiration;
159 context.Response.Cookies.Add (cookie);
162 void OnEndRequest (object sender, EventArgs args)
164 HttpApplication app = (HttpApplication) sender;
165 HttpContext context = app.Context;
166 if (context.Response.StatusCode != 401 || context.Request.QueryString ["ReturnUrl"] != null)
170 InitConfig (context);
172 loginPage = _config.Forms.LoginUrl;
174 loginPage = _config.LoginUrl;
176 if (_config == null || _config.Mode != AuthenticationMode.Forms)
179 StringBuilder login = new StringBuilder ();
180 login.Append (UrlUtils.Combine (context.Request.ApplicationPath, loginPage));
181 login.AppendFormat ("?ReturnUrl={0}", HttpUtility.UrlEncode (context.Request.RawUrl));
182 context.Response.Redirect (login.ToString (), false);
185 public event FormsAuthenticationEventHandler Authenticate;