1 /* ****************************************************************************
\r
3 * Copyright (c) Microsoft Corporation. All rights reserved.
\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
9 * You must not remove this notice, or any other, from this software.
\r
11 * ***************************************************************************/
\r
13 namespace System.Web.Mvc {
\r
15 using System.Security.Cryptography;
\r
18 internal sealed class AntiForgeryData {
\r
20 private const string AntiForgeryTokenFieldName = "__RequestVerificationToken";
\r
22 private const int TokenLength = 128 / 8;
\r
23 private static RNGCryptoServiceProvider _prng = new RNGCryptoServiceProvider();
\r
25 private string _salt;
\r
26 private string _value;
\r
28 public AntiForgeryData() {
\r
32 public AntiForgeryData(AntiForgeryData token) {
\r
33 if (token == null) {
\r
34 throw new ArgumentNullException("token");
\r
37 CreationDate = token.CreationDate;
\r
39 Value = token.Value;
\r
42 public DateTime CreationDate {
\r
47 public string Salt {
\r
49 return _salt ?? String.Empty;
\r
56 public string Value {
\r
58 return _value ?? String.Empty;
\r
65 private static string Base64EncodeForCookieName(string s) {
\r
66 byte[] rawBytes = Encoding.UTF8.GetBytes(s);
\r
67 string base64String = Convert.ToBase64String(rawBytes);
\r
69 // replace base64-specific characters with characters that are safe for a cookie name
\r
70 return base64String.Replace('+', '.').Replace('/', '-').Replace('=', '_');
\r
73 private static string GenerateRandomTokenString() {
\r
74 byte[] tokenBytes = new byte[TokenLength];
\r
75 _prng.GetBytes(tokenBytes);
\r
77 string token = Convert.ToBase64String(tokenBytes);
\r
81 // If the app path is provided, we're generating a cookie name rather than a field name, and the cookie names should
\r
82 // be unique so that a development server cookie and an IIS cookie - both running on localhost - don't stomp on
\r
84 internal static string GetAntiForgeryTokenName(string appPath) {
\r
85 if (String.IsNullOrEmpty(appPath)) {
\r
86 return AntiForgeryTokenFieldName;
\r
89 return AntiForgeryTokenFieldName + "_" + Base64EncodeForCookieName(appPath);
\r
93 public static AntiForgeryData NewToken() {
\r
94 string tokenString = GenerateRandomTokenString();
\r
95 return new AntiForgeryData() {
\r
96 CreationDate = DateTime.Now,
\r