FormsAuthentication.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. //
  2. // System.Web.Security.FormsAuthentication
  3. //
  4. // Authors:
  5. // Gonzalo Paniagua Javier ([email protected])
  6. //
  7. // (C) 2002,2003 Ximian, Inc (http://www.ximian.com)
  8. // Copyright (c) 2005 Novell, Inc (http://www.novell.com)
  9. //
  10. //
  11. // Permission is hereby granted, free of charge, to any person obtaining
  12. // a copy of this software and associated documentation files (the
  13. // "Software"), to deal in the Software without restriction, including
  14. // without limitation the rights to use, copy, modify, merge, publish,
  15. // distribute, sublicense, and/or sell copies of the Software, and to
  16. // permit persons to whom the Software is furnished to do so, subject to
  17. // the following conditions:
  18. //
  19. // The above copyright notice and this permission notice shall be
  20. // included in all copies or substantial portions of the Software.
  21. //
  22. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  23. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  24. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  25. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  26. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  27. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  28. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29. //
  30. using System.Collections;
  31. using System.IO;
  32. using System.Security.Cryptography;
  33. using System.Security.Permissions;
  34. using System.Text;
  35. using System.Web;
  36. using System.Web.Configuration;
  37. using System.Web.Util;
  38. namespace System.Web.Security
  39. {
  40. // CAS - no InheritanceDemand here as the class is sealed
  41. [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
  42. public sealed class FormsAuthentication
  43. {
  44. const int MD5_hash_size = 16;
  45. const int SHA1_hash_size = 20;
  46. static string authConfigPath = "system.web/authentication";
  47. static string machineKeyConfigPath = "system.web/machineKey";
  48. #if TARGET_J2EE
  49. const string Forms_initialized = "Forms.initialized";
  50. const string Forms_cookieName = "Forms.cookieName";
  51. const string Forms_cookiePath = "Forms.cookiePath";
  52. const string Forms_timeout = "Forms.timeout";
  53. const string Forms_protection = "Forms.protection";
  54. const string Forms_init_vector = "Forms.init_vector";
  55. static bool initialized
  56. {
  57. get {
  58. object o = AppDomain.CurrentDomain.GetData (Forms_initialized);
  59. return o != null ? (bool) o : false;
  60. }
  61. set { AppDomain.CurrentDomain.SetData (Forms_initialized, value); }
  62. }
  63. static string cookieName
  64. {
  65. get { return (string) AppDomain.CurrentDomain.GetData (Forms_cookieName); }
  66. set { AppDomain.CurrentDomain.SetData (Forms_cookieName, value); }
  67. }
  68. static string cookiePath
  69. {
  70. get { return (string) AppDomain.CurrentDomain.GetData (Forms_cookiePath); }
  71. set { AppDomain.CurrentDomain.SetData (Forms_cookiePath, value); }
  72. }
  73. static int timeout
  74. {
  75. get {
  76. object o = AppDomain.CurrentDomain.GetData (Forms_timeout);
  77. return o != null ? (int) o : 0;
  78. }
  79. set { AppDomain.CurrentDomain.SetData (Forms_timeout, value); }
  80. }
  81. static FormsProtectionEnum protection
  82. {
  83. get { return (FormsProtectionEnum) AppDomain.CurrentDomain.GetData (Forms_protection); }
  84. set { AppDomain.CurrentDomain.SetData (Forms_protection, value); }
  85. }
  86. static byte [] init_vector
  87. {
  88. get { return (byte []) AppDomain.CurrentDomain.GetData (Forms_init_vector); }
  89. set { AppDomain.CurrentDomain.SetData (Forms_init_vector, value); }
  90. }
  91. static object locker = new object ();
  92. #else
  93. static bool initialized;
  94. static string cookieName;
  95. static string cookiePath;
  96. static int timeout;
  97. static FormsProtectionEnum protection;
  98. static object locker = new object ();
  99. static byte [] init_vector; // initialization vector used for 3DES
  100. #endif
  101. #if NET_1_1
  102. #if TARGET_J2EE
  103. const string Forms_requireSSL = "Forms.requireSSL";
  104. const string Forms_slidingExpiration = "Forms.slidingExpiration";
  105. static bool requireSSL
  106. {
  107. get {
  108. object o = AppDomain.CurrentDomain.GetData (Forms_requireSSL);
  109. return o != null ? (bool) o : false;
  110. }
  111. set { AppDomain.CurrentDomain.SetData (Forms_requireSSL, value); }
  112. }
  113. static bool slidingExpiration
  114. {
  115. get {
  116. object o = AppDomain.CurrentDomain.GetData (Forms_slidingExpiration);
  117. return o != null ? (bool) o : false;
  118. }
  119. set { AppDomain.CurrentDomain.SetData (Forms_slidingExpiration, value); }
  120. }
  121. #else
  122. static bool requireSSL;
  123. static bool slidingExpiration;
  124. #endif
  125. #endif
  126. #if NET_2_0
  127. #if TARGET_J2EE
  128. const string Forms_cookie_domain = "Forms.cookie_domain";
  129. const string Forms_cookie_mode = "Forms.cookie_mode";
  130. const string Forms_cookies_supported = "Forms.cookies_supported";
  131. const string Forms_default_url = "Forms.default_url";
  132. const string Forms_enable_crossapp_redirects = "Forms.enable_crossapp_redirects";
  133. const string Forms_login_url = "Forms.login_url";
  134. static string cookie_domain
  135. {
  136. get { return (string) AppDomain.CurrentDomain.GetData (Forms_cookie_domain); }
  137. set { AppDomain.CurrentDomain.SetData (Forms_cookie_domain, value); }
  138. }
  139. static HttpCookieMode cookie_mode
  140. {
  141. get { return (HttpCookieMode) AppDomain.CurrentDomain.GetData (Forms_cookie_mode); }
  142. set { AppDomain.CurrentDomain.SetData (Forms_cookie_mode, value); }
  143. }
  144. static bool cookies_supported
  145. {
  146. get {
  147. object o = AppDomain.CurrentDomain.GetData (Forms_cookies_supported);
  148. return o != null ? (bool) o : false;
  149. }
  150. set { AppDomain.CurrentDomain.SetData (Forms_cookies_supported, value); }
  151. }
  152. static string default_url
  153. {
  154. get { return (string) AppDomain.CurrentDomain.GetData (Forms_default_url); }
  155. set { AppDomain.CurrentDomain.SetData (Forms_default_url, value); }
  156. }
  157. static bool enable_crossapp_redirects
  158. {
  159. get {
  160. object o = AppDomain.CurrentDomain.GetData (Forms_enable_crossapp_redirects);
  161. return o != null ? (bool) o : false;
  162. }
  163. set { AppDomain.CurrentDomain.SetData (Forms_enable_crossapp_redirects, value); }
  164. }
  165. static string login_url
  166. {
  167. get { return (string) AppDomain.CurrentDomain.GetData (Forms_login_url); }
  168. set { AppDomain.CurrentDomain.SetData (Forms_login_url, value); }
  169. }
  170. #else
  171. static string cookie_domain;
  172. static HttpCookieMode cookie_mode;
  173. static bool cookies_supported;
  174. static string default_url;
  175. static bool enable_crossapp_redirects;
  176. static string login_url;
  177. #endif
  178. #endif
  179. // same names and order used in xsp
  180. static string [] indexFiles = { "index.aspx",
  181. "Default.aspx",
  182. "default.aspx",
  183. "index.html",
  184. "index.htm" };
  185. public FormsAuthentication ()
  186. {
  187. }
  188. public static bool Authenticate (string name, string password)
  189. {
  190. if (name == null || password == null)
  191. return false;
  192. Initialize ();
  193. HttpContext context = HttpContext.Current;
  194. if (context == null)
  195. throw new HttpException ("Context is null!");
  196. #if NET_2_0
  197. AuthenticationSection section = (AuthenticationSection) WebConfigurationManager.GetSection (authConfigPath);
  198. FormsAuthenticationCredentials config = section.Forms.Credentials;
  199. FormsAuthenticationUser user = config.Users[name];
  200. string stored = null;
  201. if (user != null)
  202. stored = user.Password;
  203. #else
  204. AuthConfig config = context.GetConfig (authConfigPath) as AuthConfig;
  205. Hashtable users = config.CredentialUsers;
  206. string stored = users [name] as string;
  207. #endif
  208. if (stored == null)
  209. return false;
  210. switch (config.PasswordFormat) {
  211. case FormsAuthPasswordFormat.Clear:
  212. /* Do nothing */
  213. break;
  214. case FormsAuthPasswordFormat.MD5:
  215. password = HashPasswordForStoringInConfigFile (password, "MD5");
  216. break;
  217. case FormsAuthPasswordFormat.SHA1:
  218. password = HashPasswordForStoringInConfigFile (password, "SHA1");
  219. break;
  220. }
  221. return (password == stored);
  222. }
  223. static FormsAuthenticationTicket Decrypt2 (byte [] bytes)
  224. {
  225. if (protection == FormsProtectionEnum.None)
  226. return FormsAuthenticationTicket.FromByteArray (bytes);
  227. #if NET_2_0
  228. MachineKeySection config = (MachineKeySection) WebConfigurationManager.GetSection (machineKeyConfigPath);
  229. #else
  230. MachineKeyConfig config = HttpContext.GetAppConfig (machineKeyConfigPath) as MachineKeyConfig;
  231. #endif
  232. bool all = (protection == FormsProtectionEnum.All);
  233. byte [] result = bytes;
  234. if (all || protection == FormsProtectionEnum.Encryption) {
  235. ICryptoTransform decryptor;
  236. decryptor = TripleDES.Create ().CreateDecryptor (config.DecryptionKey192Bits, init_vector);
  237. result = decryptor.TransformFinalBlock (bytes, 0, bytes.Length);
  238. bytes = null;
  239. }
  240. if (all || protection == FormsProtectionEnum.Validation) {
  241. int count;
  242. MachineKeyValidation validationType;
  243. #if NET_2_0
  244. validationType = config.Validation;
  245. #else
  246. validationType = config.ValidationType;
  247. #endif
  248. if (validationType == MachineKeyValidation.MD5)
  249. count = MD5_hash_size;
  250. else
  251. count = SHA1_hash_size; // 3DES and SHA1
  252. #if NET_2_0
  253. byte [] vk = config.ValidationKeyBytes;
  254. #else
  255. byte [] vk = config.ValidationKey;
  256. #endif
  257. byte [] mix = new byte [result.Length - count + vk.Length];
  258. Buffer.BlockCopy (result, 0, mix, 0, result.Length - count);
  259. Buffer.BlockCopy (vk, 0, mix, result.Length - count, vk.Length);
  260. byte [] hash = null;
  261. switch (validationType) {
  262. case MachineKeyValidation.MD5:
  263. hash = MD5.Create ().ComputeHash (mix);
  264. break;
  265. // From MS docs: "When 3DES is specified, forms authentication defaults to SHA1"
  266. case MachineKeyValidation.TripleDES:
  267. case MachineKeyValidation.SHA1:
  268. hash = SHA1.Create ().ComputeHash (mix);
  269. break;
  270. }
  271. if (result.Length < count)
  272. throw new ArgumentException ("Error validating ticket (length).", "encryptedTicket");
  273. int i, k;
  274. for (i = result.Length - count, k = 0; k < count; i++, k++) {
  275. if (result [i] != hash [k])
  276. throw new ArgumentException ("Error validating ticket.", "encryptedTicket");
  277. }
  278. }
  279. return FormsAuthenticationTicket.FromByteArray (result);
  280. }
  281. public static FormsAuthenticationTicket Decrypt (string encryptedTicket)
  282. {
  283. if (encryptedTicket == null || encryptedTicket == String.Empty)
  284. throw new ArgumentException ("Invalid encrypted ticket", "encryptedTicket");
  285. Initialize ();
  286. FormsAuthenticationTicket ticket;
  287. #if NET_2_0
  288. byte [] bytes = MachineKeySection.GetBytes (encryptedTicket, encryptedTicket.Length);
  289. #else
  290. byte [] bytes = MachineKeyConfig.GetBytes (encryptedTicket, encryptedTicket.Length);
  291. #endif
  292. try {
  293. ticket = Decrypt2 (bytes);
  294. } catch (Exception) {
  295. ticket = null;
  296. }
  297. return ticket;
  298. }
  299. public static string Encrypt (FormsAuthenticationTicket ticket)
  300. {
  301. if (ticket == null)
  302. throw new ArgumentNullException ("ticket");
  303. Initialize ();
  304. byte [] ticket_bytes = ticket.ToByteArray ();
  305. if (protection == FormsProtectionEnum.None)
  306. return GetHexString (ticket_bytes);
  307. byte [] result = ticket_bytes;
  308. #if NET_2_0
  309. MachineKeySection config = (MachineKeySection) WebConfigurationManager.GetSection (machineKeyConfigPath);
  310. #else
  311. MachineKeyConfig config = HttpContext.GetAppConfig (machineKeyConfigPath) as MachineKeyConfig;
  312. #endif
  313. bool all = (protection == FormsProtectionEnum.All);
  314. if (all || protection == FormsProtectionEnum.Validation) {
  315. byte [] valid_bytes = null;
  316. #if NET_2_0
  317. byte [] vk = config.ValidationKeyBytes;
  318. #else
  319. byte [] vk = config.ValidationKey;
  320. #endif
  321. byte [] mix = new byte [ticket_bytes.Length + vk.Length];
  322. Buffer.BlockCopy (ticket_bytes, 0, mix, 0, ticket_bytes.Length);
  323. Buffer.BlockCopy (vk, 0, mix, result.Length, vk.Length);
  324. switch (
  325. #if NET_2_0
  326. config.Validation
  327. #else
  328. config.ValidationType
  329. #endif
  330. ) {
  331. case MachineKeyValidation.MD5:
  332. valid_bytes = MD5.Create ().ComputeHash (mix);
  333. break;
  334. // From MS docs: "When 3DES is specified, forms authentication defaults to SHA1"
  335. case MachineKeyValidation.TripleDES:
  336. case MachineKeyValidation.SHA1:
  337. valid_bytes = SHA1.Create ().ComputeHash (mix);
  338. break;
  339. }
  340. int tlen = ticket_bytes.Length;
  341. int vlen = valid_bytes.Length;
  342. result = new byte [tlen + vlen];
  343. Buffer.BlockCopy (ticket_bytes, 0, result, 0, tlen);
  344. Buffer.BlockCopy (valid_bytes, 0, result, tlen, vlen);
  345. }
  346. if (all || protection == FormsProtectionEnum.Encryption) {
  347. ICryptoTransform encryptor;
  348. encryptor = TripleDES.Create ().CreateEncryptor (config.DecryptionKey192Bits, init_vector);
  349. result = encryptor.TransformFinalBlock (result, 0, result.Length);
  350. }
  351. return GetHexString (result);
  352. }
  353. public static HttpCookie GetAuthCookie (string userName, bool createPersistentCookie)
  354. {
  355. return GetAuthCookie (userName, createPersistentCookie, null);
  356. }
  357. public static HttpCookie GetAuthCookie (string userName, bool createPersistentCookie, string strCookiePath)
  358. {
  359. Initialize ();
  360. if (userName == null)
  361. userName = String.Empty;
  362. if (strCookiePath == null || strCookiePath.Length == 0)
  363. strCookiePath = cookiePath;
  364. DateTime now = DateTime.Now;
  365. DateTime then;
  366. if (createPersistentCookie)
  367. then = now.AddYears (50);
  368. else
  369. then = now.AddMinutes (timeout);
  370. FormsAuthenticationTicket ticket = new FormsAuthenticationTicket (1,
  371. userName,
  372. now,
  373. then,
  374. createPersistentCookie,
  375. String.Empty,
  376. cookiePath);
  377. if (!createPersistentCookie)
  378. then = DateTime.MinValue;
  379. HttpCookie cookie = new HttpCookie (cookieName, Encrypt (ticket), strCookiePath, then);
  380. if (requireSSL)
  381. cookie.Secure = true;
  382. return cookie;
  383. }
  384. internal static string ReturnUrl
  385. {
  386. get { return HttpContext.Current.Request ["RETURNURL"]; }
  387. }
  388. public static string GetRedirectUrl (string userName, bool createPersistentCookie)
  389. {
  390. if (userName == null)
  391. return null;
  392. Initialize ();
  393. HttpRequest request = HttpContext.Current.Request;
  394. string returnUrl = ReturnUrl;
  395. if (returnUrl != null)
  396. return returnUrl;
  397. returnUrl = request.ApplicationPath;
  398. string apppath = request.PhysicalApplicationPath;
  399. bool found = false;
  400. foreach (string indexFile in indexFiles) {
  401. string filePath = Path.Combine (apppath, indexFile);
  402. if (File.Exists (filePath)) {
  403. returnUrl = UrlUtils.Combine (returnUrl, indexFile);
  404. found = true;
  405. break;
  406. }
  407. }
  408. if (!found)
  409. returnUrl = UrlUtils.Combine (returnUrl, "index.aspx");
  410. return returnUrl;
  411. }
  412. static string GetHexString (byte [] bytes)
  413. {
  414. StringBuilder result = new StringBuilder (bytes.Length * 2);
  415. foreach (byte b in bytes)
  416. result.AppendFormat ("{0:X2}", (int) b);
  417. return result.ToString ();
  418. }
  419. public static string HashPasswordForStoringInConfigFile (string password, string passwordFormat)
  420. {
  421. if (password == null)
  422. throw new ArgumentNullException ("password");
  423. if (passwordFormat == null)
  424. throw new ArgumentNullException ("passwordFormat");
  425. byte [] bytes;
  426. if (String.Compare (passwordFormat, "MD5", true) == 0) {
  427. bytes = MD5.Create ().ComputeHash (Encoding.UTF8.GetBytes (password));
  428. } else if (String.Compare (passwordFormat, "SHA1", true) == 0) {
  429. bytes = SHA1.Create ().ComputeHash (Encoding.UTF8.GetBytes (password));
  430. } else {
  431. throw new ArgumentException ("The format must be either MD5 or SHA1", "passwordFormat");
  432. }
  433. return GetHexString (bytes);
  434. }
  435. public static void Initialize ()
  436. {
  437. if (initialized)
  438. return;
  439. lock (locker) {
  440. if (initialized)
  441. return;
  442. #if NET_2_0
  443. AuthenticationSection section = (AuthenticationSection)WebConfigurationManager.GetSection (authConfigPath);
  444. FormsAuthenticationConfiguration config = section.Forms;
  445. cookieName = config.Name;
  446. timeout = (int)config.Timeout.TotalMinutes;
  447. cookiePath = config.Path;
  448. protection = config.Protection;
  449. requireSSL = config.RequireSSL;
  450. slidingExpiration = config.SlidingExpiration;
  451. cookie_domain = config.Domain;
  452. cookie_mode = config.Cookieless;
  453. cookies_supported = true; /* XXX ? */
  454. default_url = MapUrl(config.DefaultUrl);
  455. enable_crossapp_redirects = config.EnableCrossAppRedirects;
  456. login_url = MapUrl(config.LoginUrl);
  457. #else
  458. HttpContext context = HttpContext.Current;
  459. AuthConfig authConfig = context.GetConfig (authConfigPath) as AuthConfig;
  460. if (authConfig != null) {
  461. cookieName = authConfig.CookieName;
  462. timeout = authConfig.Timeout;
  463. cookiePath = authConfig.CookiePath;
  464. protection = authConfig.Protection;
  465. #if NET_1_1
  466. requireSSL = authConfig.RequireSSL;
  467. slidingExpiration = authConfig.SlidingExpiration;
  468. #endif
  469. } else {
  470. cookieName = ".MONOAUTH";
  471. timeout = 30;
  472. cookiePath = "/";
  473. protection = FormsProtectionEnum.All;
  474. #if NET_1_1
  475. slidingExpiration = true;
  476. #endif
  477. }
  478. #endif
  479. // IV is 8 bytes long for 3DES
  480. init_vector = new byte [8];
  481. int len = cookieName.Length;
  482. for (int i = 0; i < 8; i++) {
  483. if (i >= len)
  484. break;
  485. init_vector [i] = (byte) cookieName [i];
  486. }
  487. initialized = true;
  488. }
  489. }
  490. static string MapUrl (string url) {
  491. if (UrlUtils.IsRelativeUrl (url))
  492. return UrlUtils.Combine (HttpRuntime.AppDomainAppVirtualPath, url);
  493. else
  494. return UrlUtils.ResolveVirtualPathFromAppAbsolute (url);
  495. }
  496. public static void RedirectFromLoginPage (string userName, bool createPersistentCookie)
  497. {
  498. RedirectFromLoginPage (userName, createPersistentCookie, null);
  499. }
  500. public static void RedirectFromLoginPage (string userName, bool createPersistentCookie, string strCookiePath)
  501. {
  502. if (userName == null)
  503. return;
  504. Initialize ();
  505. SetAuthCookie (userName, createPersistentCookie, strCookiePath);
  506. Redirect (GetRedirectUrl (userName, createPersistentCookie), false);
  507. }
  508. public static FormsAuthenticationTicket RenewTicketIfOld (FormsAuthenticationTicket tOld)
  509. {
  510. if (tOld == null)
  511. return null;
  512. DateTime now = DateTime.Now;
  513. TimeSpan toIssue = now - tOld.IssueDate;
  514. TimeSpan toExpiration = tOld.Expiration - now;
  515. if (toExpiration > toIssue)
  516. return tOld;
  517. FormsAuthenticationTicket tNew = tOld.Clone ();
  518. tNew.SetDates (now, now + (tOld.Expiration - tOld.IssueDate));
  519. return tNew;
  520. }
  521. public static void SetAuthCookie (string userName, bool createPersistentCookie)
  522. {
  523. Initialize ();
  524. SetAuthCookie (userName, createPersistentCookie, cookiePath);
  525. }
  526. public static void SetAuthCookie (string userName, bool createPersistentCookie, string strCookiePath)
  527. {
  528. HttpContext context = HttpContext.Current;
  529. if (context == null)
  530. throw new HttpException ("Context is null!");
  531. HttpResponse response = context.Response;
  532. if (response == null)
  533. throw new HttpException ("Response is null!");
  534. response.Cookies.Add (GetAuthCookie (userName, createPersistentCookie, strCookiePath));
  535. }
  536. public static void SignOut ()
  537. {
  538. Initialize ();
  539. HttpContext context = HttpContext.Current;
  540. if (context == null)
  541. throw new HttpException ("Context is null!");
  542. HttpResponse response = context.Response;
  543. if (response == null)
  544. throw new HttpException ("Response is null!");
  545. HttpCookieCollection cc = response.Cookies;
  546. cc.Remove (cookieName);
  547. HttpCookie expiration_cookie = new HttpCookie (cookieName, "");
  548. expiration_cookie.Expires = new DateTime (1999, 10, 12);
  549. expiration_cookie.Path = cookiePath;
  550. cc.Add (expiration_cookie);
  551. }
  552. public static string FormsCookieName
  553. {
  554. get {
  555. Initialize ();
  556. return cookieName;
  557. }
  558. }
  559. public static string FormsCookiePath
  560. {
  561. get {
  562. Initialize ();
  563. return cookiePath;
  564. }
  565. }
  566. #if NET_1_1
  567. public static bool RequireSSL {
  568. get {
  569. Initialize ();
  570. return requireSSL;
  571. }
  572. }
  573. public static bool SlidingExpiration {
  574. get {
  575. Initialize ();
  576. return slidingExpiration;
  577. }
  578. }
  579. #endif
  580. #if NET_2_0
  581. public static string CookieDomain {
  582. get { Initialize (); return cookie_domain; }
  583. }
  584. public static HttpCookieMode CookieMode {
  585. get { Initialize (); return cookie_mode; }
  586. }
  587. public static bool CookiesSupported {
  588. get { Initialize (); return cookies_supported; }
  589. }
  590. public static string DefaultUrl {
  591. get { Initialize (); return default_url; }
  592. }
  593. public static bool EnableCrossAppRedirects {
  594. get { Initialize (); return enable_crossapp_redirects; }
  595. }
  596. public static string LoginUrl {
  597. get { Initialize (); return login_url; }
  598. }
  599. public static void RedirectToLoginPage ()
  600. {
  601. Redirect (LoginUrl);
  602. }
  603. [MonoTODO ("needs more tests")]
  604. public static void RedirectToLoginPage (string extraQueryString)
  605. {
  606. // TODO: if ? is in LoginUrl (legal?), ? in query (legal?) ...
  607. Redirect (LoginUrl + "?" + extraQueryString);
  608. }
  609. #endif
  610. private static void Redirect (string url)
  611. {
  612. HttpContext.Current.Response.Redirect (url);
  613. }
  614. private static void Redirect (string url, bool end)
  615. {
  616. HttpContext.Current.Response.Redirect (url, end);
  617. }
  618. }
  619. }