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
16 using System.Security.Principal;
\r
19 internal sealed class AntiForgeryData {
\r
21 private const string AntiForgeryTokenFieldName = "__RequestVerificationToken";
\r
23 private const int TokenLength = 128 / 8;
\r
24 private readonly static RNGCryptoServiceProvider _prng = new RNGCryptoServiceProvider();
\r
26 private DateTime _creationDate = DateTime.UtcNow;
\r
27 private string _salt;
\r
28 private string _username;
\r
29 private string _value;
\r
31 public AntiForgeryData() {
\r
35 public AntiForgeryData(AntiForgeryData token) {
\r
36 if (token == null) {
\r
37 throw new ArgumentNullException("token");
\r
40 CreationDate = token.CreationDate;
\r
42 Username = token.Username;
\r
43 Value = token.Value;
\r
46 public DateTime CreationDate {
\r
48 return _creationDate;
\r
51 _creationDate = value;
\r
55 public string Salt {
\r
57 return _salt ?? String.Empty;
\r
64 public string Username {
\r
66 return _username ?? String.Empty;
\r
73 public string Value {
\r
75 return _value ?? String.Empty;
\r
82 private static string Base64EncodeForCookieName(string s) {
\r
83 byte[] rawBytes = Encoding.UTF8.GetBytes(s);
\r
84 string base64String = Convert.ToBase64String(rawBytes);
\r
86 // replace base64-specific characters with characters that are safe for a cookie name
\r
87 return base64String.Replace('+', '.').Replace('/', '-').Replace('=', '_');
\r
90 private static string GenerateRandomTokenString() {
\r
91 byte[] tokenBytes = new byte[TokenLength];
\r
92 _prng.GetBytes(tokenBytes);
\r
94 string token = Convert.ToBase64String(tokenBytes);
\r
98 // If the app path is provided, we're generating a cookie name rather than a field name, and the cookie names should
\r
99 // be unique so that a development server cookie and an IIS cookie - both running on localhost - don't stomp on
\r
101 internal static string GetAntiForgeryTokenName(string appPath) {
\r
102 if (String.IsNullOrEmpty(appPath)) {
\r
103 return AntiForgeryTokenFieldName;
\r
106 return AntiForgeryTokenFieldName + "_" + Base64EncodeForCookieName(appPath);
\r
110 internal static string GetUsername(IPrincipal user) {
\r
111 if (user != null) {
\r
112 IIdentity identity = user.Identity;
\r
113 if (identity != null && identity.IsAuthenticated) {
\r
114 return identity.Name;
\r
118 return String.Empty;
\r
121 public static AntiForgeryData NewToken() {
\r
122 string tokenString = GenerateRandomTokenString();
\r
123 return new AntiForgeryData() {
\r
124 Value = tokenString
\r