2 // System.Web.Security.FormsAuthentication
5 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 // (C) 2002 Ximian, Inc (http://www.ximian.com)
11 using System.Collections;
12 using System.Security.Cryptography;
15 using System.Web.Configuration;
16 using System.Web.Util;
18 namespace System.Web.Security
20 public sealed class FormsAuthentication
22 static string authConfigPath = "system.web/authentication";
23 static bool initialized;
24 static string cookieName;
25 static string cookiePath;
27 static FormsProtectionEnum protection;
29 public static bool Authenticate (string name, string password)
31 if (name == null || password == null)
35 HttpContext context = HttpContext.Current;
37 throw new HttpException ("Context is null!");
39 AuthConfig config = context.GetConfig (authConfigPath) as AuthConfig;
40 Hashtable users = config.CredentialUsers;
41 string stored = users [name] as string;
45 switch (config.PasswordFormat) {
46 case FormsAuthPasswordFormat.Clear:
49 case FormsAuthPasswordFormat.MD5:
50 stored = HashPasswordForStoringInConfigFile (stored, "MD5");
52 case FormsAuthPasswordFormat.SHA1:
53 stored = HashPasswordForStoringInConfigFile (stored, "SHA1");
57 return (password == stored);
60 public static FormsAuthenticationTicket Decrypt (string encryptedTicket)
62 if (encryptedTicket == null || encryptedTicket == String.Empty)
63 throw new ArgumentException ("Invalid encrypted ticket", "encryptedTicket");
66 byte [] bytes = MachineKeyConfigHandler.GetBytes (encryptedTicket, encryptedTicket.Length);
68 string decrypted = WebEncoding.Encoding.GetString (bytes);
69 FormsAuthenticationTicket ticket = null;
71 string [] values = decrypted.Split ((char) 1, (char) 2, (char) 3, (char) 4, (char) 5, (char) 6, (char) 7);
72 if (values.Length != 8)
73 throw new Exception (values.Length + " " + encryptedTicket);
75 ticket = new FormsAuthenticationTicket (Int32.Parse (values [0]),
77 new DateTime (Int64.Parse (values [2])),
78 new DateTime (Int64.Parse (values [3])),
82 } catch (Exception e) {
83 throw new ArgumentException ("Invalid encrypted ticket", "encryptedTicket", e);
89 public static string Encrypt (FormsAuthenticationTicket ticket)
92 throw new ArgumentNullException ("ticket");
95 StringBuilder allTicket = new StringBuilder ();
96 allTicket.Append (ticket.Version);
97 allTicket.Append ('\u0001');
98 allTicket.Append (ticket.Name);
99 allTicket.Append ('\u0002');
100 allTicket.Append (ticket.IssueDate.Ticks);
101 allTicket.Append ('\u0003');
102 allTicket.Append (ticket.Expiration.Ticks);
103 allTicket.Append ('\u0004');
104 allTicket.Append (ticket.IsPersistent ? '1' : '0');
105 allTicket.Append ('\u0005');
106 allTicket.Append (ticket.UserData);
107 allTicket.Append ('\u0006');
108 allTicket.Append (ticket.CookiePath);
109 allTicket.Append ('\u0007');
110 //if (protection == FormsProtectionEnum.None)
111 return GetHexString (allTicket.ToString ());
112 //TODO: encrypt and validate
115 public static HttpCookie GetAuthCookie (string userName, bool createPersistentCookie)
117 return GetAuthCookie (userName, createPersistentCookie, cookiePath);
120 public static HttpCookie GetAuthCookie (string userName, bool createPersistentCookie, string strCookiePath)
124 if (userName == null)
125 userName = String.Empty;
127 if (strCookiePath == null || strCookiePath.Length == 0)
128 strCookiePath = cookiePath;
130 DateTime now = DateTime.Now;
132 if (createPersistentCookie)
133 then = now.AddYears (50);
135 then = now.AddMinutes (timeout);
137 FormsAuthenticationTicket ticket = new FormsAuthenticationTicket (1,
141 createPersistentCookie,
145 if (!createPersistentCookie)
146 then = DateTime.MinValue;
148 return new HttpCookie (cookieName, Encrypt (ticket), strCookiePath, then);
152 public static string GetRedirectUrl (string userName, bool createPersistentCookie)
154 throw new NotImplementedException ();
157 static string GetHexString (string str)
159 return GetHexString (WebEncoding.Encoding.GetBytes (str));
162 static string GetHexString (byte [] bytes)
164 StringBuilder result = new StringBuilder (bytes.Length * 2);
165 foreach (byte b in bytes)
166 result.AppendFormat ("{0:x2}", (int) b);
168 return result.ToString ();
171 public static string HashPasswordForStoringInConfigFile (string password, string passwordFormat)
173 if (password == null)
174 throw new ArgumentNullException ("password");
176 if (passwordFormat == null)
177 throw new ArgumentNullException ("passwordFormat");
180 if (String.Compare (passwordFormat, "MD5", true) == 0) {
181 bytes = MD5.Create ().ComputeHash (WebEncoding.Encoding.GetBytes (password));
182 } else if (String.Compare (passwordFormat, "SHA1", true) == 0) {
183 bytes = SHA1.Create ().ComputeHash (WebEncoding.Encoding.GetBytes (password));
185 throw new ArgumentException ("The format must be either MD5 or SHA1", "passwordFormat");
188 return GetHexString (bytes);
191 public static void Initialize ()
196 lock (typeof (FormsAuthentication)) {
200 HttpContext context = HttpContext.Current;
202 throw new HttpException ("Context is null!");
204 AuthConfig authConfig = context.GetConfig (authConfigPath) as AuthConfig;
205 if (authConfig != null) {
206 cookieName = authConfig.CookieName;
207 timeout = authConfig.Timeout;
208 cookiePath = authConfig.CookiePath;
209 protection = authConfig.Protection;
211 cookieName = ".MONOAUTH";
214 protection = FormsProtectionEnum.All;
222 public static void RedirectFromLoginPage (string userName, bool createPersistentCookie)
224 throw new NotImplementedException ();
228 public static void RedirectFromLoginPage (string userName, bool createPersistentCookie, string strCookiePath)
230 throw new NotImplementedException ();
233 public static FormsAuthenticationTicket RenewTicketIfOld (FormsAuthenticationTicket tOld)
235 throw new NotImplementedException ();
238 public static void SetAuthCookie (string userName, bool createPersistentCookie)
240 SetAuthCookie (userName, createPersistentCookie, cookiePath);
243 public static void SetAuthCookie (string userName, bool createPersistentCookie, string strCookiePath)
245 HttpContext context = HttpContext.Current;
247 throw new HttpException ("Context is null!");
249 HttpResponse response = context.Response;
250 if (response == null)
251 throw new HttpException ("Response is null!");
253 response.Cookies.Add (GetAuthCookie (userName, createPersistentCookie, strCookiePath));
256 public static void SignOut ()
260 HttpContext context = HttpContext.Current;
262 throw new HttpException ("Context is null!");
264 HttpResponse response = context.Response;
265 if (response == null)
266 throw new HttpException ("Response is null!");
268 response.Cookies.MakeCookieExpire (cookieName, cookiePath);
271 public static string FormsCookieName
279 public static string FormsCookiePath