New tests.
[mono.git] / mcs / class / System.Web.Mvc2 / System.Web.Mvc / ValidateAntiForgeryTokenAttribute.cs
1 /* ****************************************************************************\r
2  *\r
3  * Copyright (c) Microsoft Corporation. All rights reserved.\r
4  *\r
5  * This software is subject to the Microsoft Public License (Ms-PL). \r
6  * A copy of the license can be found in the license.htm file included \r
7  * in this distribution.\r
8  *\r
9  * You must not remove this notice, or any other, from this software.\r
10  *\r
11  * ***************************************************************************/\r
12 \r
13 namespace System.Web.Mvc {\r
14     using System;\r
15     using System.Web;\r
16     using System.Web.Mvc.Resources;\r
17 \r
18     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]\r
19     public sealed class ValidateAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter {\r
20 \r
21         private string _salt;\r
22         private AntiForgeryDataSerializer _serializer;\r
23 \r
24         public string Salt {\r
25             get {\r
26                 return _salt ?? String.Empty;\r
27             }\r
28             set {\r
29                 _salt = value;\r
30             }\r
31         }\r
32 \r
33         internal AntiForgeryDataSerializer Serializer {\r
34             get {\r
35                 if (_serializer == null) {\r
36                     _serializer = new AntiForgeryDataSerializer();\r
37                 }\r
38                 return _serializer;\r
39             }\r
40             set {\r
41                 _serializer = value;\r
42             }\r
43         }\r
44 \r
45         private bool ValidateFormToken(AntiForgeryData token) {\r
46             return (String.Equals(Salt, token.Salt, StringComparison.Ordinal));\r
47         }\r
48 \r
49         private static HttpAntiForgeryException CreateValidationException() {\r
50             return new HttpAntiForgeryException(MvcResources.AntiForgeryToken_ValidationFailed);\r
51         }\r
52 \r
53         public void OnAuthorization(AuthorizationContext filterContext) {\r
54             if (filterContext == null) {\r
55                 throw new ArgumentNullException("filterContext");\r
56             }\r
57 \r
58             string fieldName = AntiForgeryData.GetAntiForgeryTokenName(null);\r
59             string cookieName = AntiForgeryData.GetAntiForgeryTokenName(filterContext.HttpContext.Request.ApplicationPath);\r
60 \r
61             HttpCookie cookie = filterContext.HttpContext.Request.Cookies[cookieName];\r
62             if (cookie == null || String.IsNullOrEmpty(cookie.Value)) {\r
63                 // error: cookie token is missing\r
64                 throw CreateValidationException();\r
65             }\r
66             AntiForgeryData cookieToken = Serializer.Deserialize(cookie.Value);\r
67 \r
68             string formValue = filterContext.HttpContext.Request.Form[fieldName];\r
69             if (String.IsNullOrEmpty(formValue)) {\r
70                 // error: form token is missing\r
71                 throw CreateValidationException();\r
72             }\r
73             AntiForgeryData formToken = Serializer.Deserialize(formValue);\r
74 \r
75             if (!String.Equals(cookieToken.Value, formToken.Value, StringComparison.Ordinal)) {\r
76                 // error: form token does not match cookie token\r
77                 throw CreateValidationException();\r
78             }\r
79 \r
80             string currentUsername = AntiForgeryData.GetUsername(filterContext.HttpContext.User);\r
81             if (!String.Equals(formToken.Username, currentUsername, StringComparison.OrdinalIgnoreCase)) {\r
82                 // error: form token is not valid for this user\r
83                 // (don't care about cookie token)\r
84                 throw CreateValidationException();\r
85             }\r
86 \r
87             if (!ValidateFormToken(formToken)) {\r
88                 // error: custom validation failed\r
89                 throw CreateValidationException();\r
90             }\r
91         }\r
92 \r
93     }\r
94 }\r