2010-06-21 Marek Habersack <mhabersack@novell.com>
[mcs.git] / class / System.Web.Mvc / System.Web.Mvc / AntiForgeryData.cs
blob2d2ee680979a19e76a657325b0811511ea57f38c
1 /* ****************************************************************************
3 * Copyright (c) Microsoft Corporation. All rights reserved.
5 * This software is subject to the Microsoft Public License (Ms-PL).
6 * A copy of the license can be found in the license.htm file included
7 * in this distribution.
9 * You must not remove this notice, or any other, from this software.
11 * ***************************************************************************/
13 namespace System.Web.Mvc {
14 using System;
15 using System.Security.Cryptography;
16 using System.Text;
18 internal sealed class AntiForgeryData {
20 private const string AntiForgeryTokenFieldName = "__RequestVerificationToken";
22 private const int TokenLength = 128 / 8;
23 private static RNGCryptoServiceProvider _prng = new RNGCryptoServiceProvider();
25 private string _salt;
26 private string _value;
28 public AntiForgeryData() {
31 // copy constructor
32 public AntiForgeryData(AntiForgeryData token) {
33 if (token == null) {
34 throw new ArgumentNullException("token");
37 CreationDate = token.CreationDate;
38 Salt = token.Salt;
39 Value = token.Value;
42 public DateTime CreationDate {
43 get;
44 set;
47 public string Salt {
48 get {
49 return _salt ?? String.Empty;
51 set {
52 _salt = value;
56 public string Value {
57 get {
58 return _value ?? String.Empty;
60 set {
61 _value = value;
65 private static string Base64EncodeForCookieName(string s) {
66 byte[] rawBytes = Encoding.UTF8.GetBytes(s);
67 string base64String = Convert.ToBase64String(rawBytes);
69 // replace base64-specific characters with characters that are safe for a cookie name
70 return base64String.Replace('+', '.').Replace('/', '-').Replace('=', '_');
73 private static string GenerateRandomTokenString() {
74 byte[] tokenBytes = new byte[TokenLength];
75 _prng.GetBytes(tokenBytes);
77 string token = Convert.ToBase64String(tokenBytes);
78 return token;
81 // If the app path is provided, we're generating a cookie name rather than a field name, and the cookie names should
82 // be unique so that a development server cookie and an IIS cookie - both running on localhost - don't stomp on
83 // each other.
84 internal static string GetAntiForgeryTokenName(string appPath) {
85 if (String.IsNullOrEmpty(appPath)) {
86 return AntiForgeryTokenFieldName;
88 else {
89 return AntiForgeryTokenFieldName + "_" + Base64EncodeForCookieName(appPath);
93 public static AntiForgeryData NewToken() {
94 string tokenString = GenerateRandomTokenString();
95 return new AntiForgeryData() {
96 CreationDate = DateTime.Now,
97 Value = tokenString