Skip to content
This repository was archived by the owner on Dec 14, 2018. It is now read-only.

Commit 2b0d472

Browse files
committed
Responding to Comments.
1 parent fb44694 commit 2b0d472

File tree

9 files changed

+93
-57
lines changed

9 files changed

+93
-57
lines changed
Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-

2-
using System.ComponentModel;
1+
using System.ComponentModel;
2+
using System.Threading.Tasks;
33
using Microsoft.AspNet.Abstractions;
44
using Microsoft.AspNet.Mvc.Rendering;
55
using Microsoft.AspNet.Security.DataProtection;
6-
using System.Threading.Tasks;
76

87
namespace Microsoft.AspNet.Mvc
98
{
@@ -16,9 +15,9 @@ public sealed class AntiForgery
1615
private static readonly string _purpose = "Microsoft.AspNet.Mvc.AntiXsrf.AntiForgeryToken.v1";
1716
private readonly AntiForgeryWorker _worker;
1817

19-
public AntiForgery(IClaimUidExtractor claimUidExtractor,
20-
IDataProtectionProvider dataProtectionProvider,
21-
IAntiForgeryAdditionalDataProvider additionalDataProvider)
18+
public AntiForgery([NotNull] IClaimUidExtractor claimUidExtractor,
19+
[NotNull] IDataProtectionProvider dataProtectionProvider,
20+
[NotNull] IAntiForgeryAdditionalDataProvider additionalDataProvider)
2221
{
2322
// TODO: This is temporary till we figure out how to flow configs using DI.
2423
var config = new AntiForgeryConfigWrapper();
@@ -32,16 +31,16 @@ public AntiForgery(IClaimUidExtractor claimUidExtractor,
3231
/// Generates an anti-forgery token for this request. This token can
3332
/// be validated by calling the Validate() method.
3433
/// </summary>
35-
/// <param name="context">The http context associated with the current call.</param>
34+
/// <param name="context">The HTTP context associated with the current call.</param>
3635
/// <returns>An HTML string corresponding to an &lt;input type="hidden"&gt;
3736
/// element. This element should be put inside a &lt;form&gt;.</returns>
3837
/// <remarks>
39-
/// This method has a side effect: it may set a response cookie.
38+
/// This method has a side effect: A response cookie is set if there is no valid cookie associated with the request.
4039
/// </remarks>
41-
public HtmlString GetHtml(HttpContext context)
40+
public HtmlString GetHtml([NotNull] HttpContext context)
4241
{
43-
TagBuilder retVal = _worker.GetFormInputElement(context);
44-
return retVal.ToHtmlString(TagRenderMode.SelfClosing);
42+
TagBuilder builder = _worker.GetFormInputElement(context);
43+
return builder.ToHtmlString(TagRenderMode.SelfClosing);
4544
}
4645

4746
/// <summary>
@@ -50,49 +49,45 @@ public HtmlString GetHtml(HttpContext context)
5049
/// over how to persist the returned values. To validate these tokens, call the
5150
/// appropriate overload of Validate.
5251
/// </summary>
53-
/// <param name="context">The http context associated with the current call.</param>
52+
/// <param name="context">The HTTP context associated with the current call.</param>
5453
/// <param name="oldCookieToken">The anti-forgery token - if any - that already existed
5554
/// for this request. May be null. The anti-forgery system will try to reuse this cookie
5655
/// value when generating a matching form token.</param>
5756
/// </remarks>
58-
public AntiForgeryTokenSet GetTokens(HttpContext context, string oldCookieToken)
57+
public AntiForgeryTokenSet GetTokens([NotNull] HttpContext context, string oldCookieToken)
5958
{
6059
// Will contain a new cookie value if the old cookie token
6160
// was null or invalid. If this value is non-null when the method completes, the caller
6261
// must persist this value in the form of a response cookie, and the existing cookie value
6362
// should be discarded. If this value is null when the method completes, the existing
6463
// cookie value was valid and needn't be modified.
65-
string newCookieToken;
66-
string formToken;
67-
_worker.GetTokens(context, oldCookieToken, out newCookieToken, out formToken);
68-
return new AntiForgeryTokenSet(formToken, newCookieToken);
64+
return _worker.GetTokens(context, oldCookieToken);
6965
}
7066

7167
/// <summary>
7268
/// Validates an anti-forgery token that was supplied for this request.
7369
/// The anti-forgery token may be generated by calling GetHtml().
7470
/// </summary>
75-
/// <param name="context">The http context associated with the current call.</param>
76-
public async Task ValidateAsync(HttpContext context)
71+
/// <param name="context">The HTTP context associated with the current call.</param>
72+
public async Task ValidateAsync([NotNull] HttpContext context)
7773
{
7874
await _worker.ValidateAsync(context);
7975
}
8076

8177
/// <summary>
8278
/// Validates an anti-forgery token pair that was generated by the GetTokens method.
8379
/// </summary>
84-
/// <param name="context">The http context associated with the current call.</param>
80+
/// <param name="context">The HTTP context associated with the current call.</param>
8581
/// <param name="cookieToken">The token that was supplied in the request cookie.</param>
8682
/// <param name="formToken">The token that was supplied in the request form body.</param>
87-
[EditorBrowsable(EditorBrowsableState.Advanced)]
88-
public void Validate(HttpContext context, string cookieToken, string formToken)
83+
public void Validate([NotNull] HttpContext context, string cookieToken, string formToken)
8984
{
9085
_worker.Validate(context, cookieToken, formToken);
9186
}
9287

93-
public void Validate(HttpContext context, AntiForgeryTokenSet antiforgeryTokenSet)
88+
public void Validate([NotNull] HttpContext context, AntiForgeryTokenSet antiForgeryTokenSet)
9489
{
95-
Validate(context, antiforgeryTokenSet.CookieToken, antiforgeryTokenSet.FormToken);
90+
Validate(context, antiForgeryTokenSet.CookieToken, antiForgeryTokenSet.FormToken);
9691
}
9792
}
9893
}

src/Microsoft.AspNet.Mvc.Core/AntiForgery/AntiForgeryConfig.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
public static class AntiForgeryConfig
77
{
88
internal const string AntiForgeryTokenFieldName = "__RequestVerificationToken";
9-
private const string AntiForgeryCookieTokenName = "__RequestVerificationCookieToken";
109
private static string _cookieName;
1110

1211
/// <summary>
@@ -59,7 +58,7 @@ public static bool SuppressXFrameOptionsHeader
5958
// TODO: Replace the stub.
6059
private static string GetAntiForgeryCookieName()
6160
{
62-
return AntiForgeryCookieTokenName;
61+
return AntiForgeryTokenFieldName;
6362
}
6463
}
6564
}

src/Microsoft.AspNet.Mvc.Core/AntiForgery/AntiForgeryTokenSerializer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ internal sealed class AntiForgeryTokenSerializer : IAntiForgeryTokenSerializer
1212
private readonly IDataProtector _cryptoSystem;
1313
private const byte TokenVersion = 0x01;
1414

15-
internal AntiForgeryTokenSerializer(IDataProtector cryptoSystem)
15+
internal AntiForgeryTokenSerializer([NotNull] IDataProtector cryptoSystem)
1616
{
1717
_cryptoSystem = cryptoSystem;
1818
}

src/Microsoft.AspNet.Mvc.Core/AntiForgery/AntiForgeryTokenStore.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ internal sealed class AntiForgeryTokenStore : ITokenStore
1111
private readonly IAntiForgeryConfig _config;
1212
private readonly IAntiForgeryTokenSerializer _serializer;
1313

14-
internal AntiForgeryTokenStore(IAntiForgeryConfig config, IAntiForgeryTokenSerializer serializer)
14+
internal AntiForgeryTokenStore([NotNull] IAntiForgeryConfig config,
15+
[NotNull] IAntiForgeryTokenSerializer serializer)
1516
{
1617
_config = config;
1718
_serializer = serializer;

src/Microsoft.AspNet.Mvc.Core/AntiForgery/AntiForgeryWorker.cs

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22
using System;
33
using System.Diagnostics.CodeAnalysis;
44
using System.Diagnostics.Contracts;
5-
using System.Security.Principal;
5+
using System.Security.Claims;
6+
using System.Threading.Tasks;
67
using Microsoft.AspNet.Abstractions;
78
using Microsoft.AspNet.Mvc.Core;
89
using Microsoft.AspNet.Mvc.Rendering;
9-
using System.Security.Claims;
10-
using System.Threading.Tasks;
1110

1211
namespace Microsoft.AspNet.Mvc
1312
{
@@ -19,7 +18,11 @@ internal sealed class AntiForgeryWorker
1918
private readonly ITokenValidator _validator;
2019
private readonly ITokenGenerator _generator;
2120

22-
internal AntiForgeryWorker(IAntiForgeryTokenSerializer serializer, IAntiForgeryConfig config, ITokenStore tokenStore, ITokenGenerator generator, ITokenValidator validator)
21+
internal AntiForgeryWorker([NotNull] IAntiForgeryTokenSerializer serializer,
22+
[NotNull] IAntiForgeryConfig config,
23+
[NotNull] ITokenStore tokenStore,
24+
[NotNull] ITokenGenerator generator,
25+
[NotNull] ITokenValidator validator)
2326
{
2427
_serializer = serializer;
2528
_config = config;
@@ -62,12 +65,12 @@ private static ClaimsIdentity ExtractIdentity(HttpContext httpContext)
6265
if (httpContext != null)
6366
{
6467
ClaimsPrincipal user = httpContext.User;
65-
68+
6669
if (user != null)
6770
{
6871
// We only support ClaimsIdentity.
6972
// Todo remove this once httpContext.User moves to ClaimsIdentity.
70-
return user.Identity as ClaimsIdentity;
73+
return user.Identity as ClaimsIdentity;
7174
}
7275
}
7376

@@ -93,14 +96,14 @@ private AntiForgeryToken GetCookieTokenNoThrow(HttpContext httpContext)
9396
// value is the hidden input form element that should be rendered in
9497
// the <form>. This method has a side effect: it may set a response
9598
// cookie.
96-
public TagBuilder GetFormInputElement(HttpContext httpContext)
99+
public TagBuilder GetFormInputElement([NotNull] HttpContext httpContext)
97100
{
98101
CheckSSLConfig(httpContext);
99102

100-
AntiForgeryToken oldCookieToken = GetCookieTokenNoThrow(httpContext);
101-
AntiForgeryToken newCookieToken, formToken;
102-
GetTokens(httpContext, oldCookieToken, out newCookieToken, out formToken);
103-
103+
var oldCookieToken = GetCookieTokenNoThrow(httpContext);
104+
var tokenSet = GetTokens(httpContext, oldCookieToken);
105+
var newCookieToken = tokenSet.CookieToken;
106+
var formToken = tokenSet.FormToken;
104107
if (newCookieToken != null)
105108
{
106109
// If a new cookie was generated, persist it.
@@ -129,29 +132,39 @@ public TagBuilder GetFormInputElement(HttpContext httpContext)
129132
// 'new cookie value' out param is non-null, the caller *must* persist
130133
// the new value to cookie storage since the original value was null or
131134
// invalid. This method is side-effect free.
132-
public void GetTokens(HttpContext httpContext, string serializedOldCookieToken, out string serializedNewCookieToken, out string serializedFormToken)
135+
public AntiForgeryTokenSet GetTokens([NotNull] HttpContext httpContext, string serializedOldCookieToken)
133136
{
134137
CheckSSLConfig(httpContext);
135-
136138
AntiForgeryToken oldCookieToken = DeserializeTokenNoThrow(serializedOldCookieToken);
137139
AntiForgeryToken newCookieToken, formToken;
138-
GetTokens(httpContext, oldCookieToken, out newCookieToken, out formToken);
140+
var tokenSet = GetTokens(httpContext, oldCookieToken);
139141

140-
serializedNewCookieToken = Serialize(newCookieToken);
141-
serializedFormToken = Serialize(formToken);
142+
var serializedNewCookieToken = Serialize(tokenSet.CookieToken);
143+
var serializedFormToken = Serialize(tokenSet.FormToken);
144+
return new AntiForgeryTokenSet(serializedFormToken, serializedNewCookieToken);
142145
}
143146

144-
private void GetTokens(HttpContext httpContext, AntiForgeryToken oldCookieToken, out AntiForgeryToken newCookieToken, out AntiForgeryToken formToken)
147+
private AntiForgeryTokenSetInternal GetTokens(HttpContext httpContext, AntiForgeryToken oldCookieToken)
145148
{
146-
newCookieToken = null;
149+
AntiForgeryToken newCookieToken = null;
147150
if (!_validator.IsCookieTokenValid(oldCookieToken))
148151
{
149152
// Need to make sure we're always operating with a good cookie token.
150153
oldCookieToken = newCookieToken = _generator.GenerateCookieToken();
151154
}
152155

153156
Contract.Assert(_validator.IsCookieTokenValid(oldCookieToken));
154-
formToken = _generator.GenerateFormToken(httpContext, ExtractIdentity(httpContext), oldCookieToken);
157+
158+
AntiForgeryToken formToken = _generator.
159+
GenerateFormToken(httpContext,
160+
ExtractIdentity(httpContext),
161+
oldCookieToken);
162+
163+
return new AntiForgeryTokenSetInternal()
164+
{
165+
CookieToken = newCookieToken,
166+
FormToken = formToken
167+
};
155168
}
156169

157170
private string Serialize(AntiForgeryToken token)
@@ -162,7 +175,7 @@ private string Serialize(AntiForgeryToken token)
162175
// [ ENTRY POINT ]
163176
// Given an HttpContext, validates that the anti-XSRF tokens contained
164177
// in the cookies & form are OK for this request.
165-
public async Task ValidateAsync(HttpContext httpContext)
178+
public async Task ValidateAsync([NotNull] HttpContext httpContext)
166179
{
167180
CheckSSLConfig(httpContext);
168181

@@ -177,7 +190,7 @@ public async Task ValidateAsync(HttpContext httpContext)
177190
// [ ENTRY POINT ]
178191
// Given the serialized string representations of a cookie & form token,
179192
// validates that the pair is OK for this request.
180-
public void Validate(HttpContext httpContext, string cookieToken, string formToken)
193+
public void Validate([NotNull] HttpContext httpContext, string cookieToken, string formToken)
181194
{
182195
CheckSSLConfig(httpContext);
183196

@@ -188,5 +201,12 @@ public void Validate(HttpContext httpContext, string cookieToken, string formTok
188201
// Validate
189202
_validator.ValidateTokens(httpContext, ExtractIdentity(httpContext), deserializedCookieToken, deserializedFormToken);
190203
}
204+
205+
private class AntiForgeryTokenSetInternal
206+
{
207+
public AntiForgeryToken FormToken { get; set; }
208+
209+
public AntiForgeryToken CookieToken { get; set; }
210+
}
191211
}
192212
}

src/Microsoft.AspNet.Mvc.Core/AntiForgery/TokenProvider.cs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ internal sealed class TokenProvider : ITokenValidator, ITokenGenerator
1313
private readonly IAntiForgeryConfig _config;
1414
private readonly IAntiForgeryAdditionalDataProvider _additionalDataProvider;
1515

16-
internal TokenProvider(IAntiForgeryConfig config, IClaimUidExtractor claimUidExtractor, IAntiForgeryAdditionalDataProvider additionalDataProvider)
16+
internal TokenProvider(IAntiForgeryConfig config,
17+
IClaimUidExtractor claimUidExtractor,
18+
IAntiForgeryAdditionalDataProvider additionalDataProvider)
1719
{
1820
_config = config;
1921
_claimUidExtractor = claimUidExtractor;
@@ -29,7 +31,9 @@ public AntiForgeryToken GenerateCookieToken()
2931
};
3032
}
3133

32-
public AntiForgeryToken GenerateFormToken(HttpContext httpContext, ClaimsIdentity identity, AntiForgeryToken cookieToken)
34+
public AntiForgeryToken GenerateFormToken(HttpContext httpContext,
35+
ClaimsIdentity identity,
36+
AntiForgeryToken cookieToken)
3337
{
3438
Contract.Assert(IsCookieTokenValid(cookieToken));
3539

@@ -38,10 +42,13 @@ public AntiForgeryToken GenerateFormToken(HttpContext httpContext, ClaimsIdentit
3842
SecurityToken = cookieToken.SecurityToken,
3943
IsSessionToken = false
4044
};
41-
45+
46+
bool isIdentityAuthenticated = false;
47+
4248
// populate Username and ClaimUid
4349
if (identity != null && identity.IsAuthenticated)
4450
{
51+
isIdentityAuthenticated = true;
4552
formToken.ClaimUid = GetClaimUidBlob(_claimUidExtractor.ExtractClaimUid(identity));
4653
if (formToken.ClaimUid == null)
4754
{
@@ -55,12 +62,15 @@ public AntiForgeryToken GenerateFormToken(HttpContext httpContext, ClaimsIdentit
5562
formToken.AdditionalData = _additionalDataProvider.GetAdditionalData(httpContext);
5663
}
5764

58-
if (string.IsNullOrEmpty(formToken.Username)
65+
if (isIdentityAuthenticated
66+
&& string.IsNullOrEmpty(formToken.Username)
5967
&& formToken.ClaimUid == null
6068
&& string.IsNullOrEmpty(formToken.AdditionalData))
6169
{
6270
// Application says user is authenticated, but we have no identifier for the user.
63-
throw new InvalidOperationException(Resources.FormatTokenValidator_AuthenticatedUserWithoutUsername(identity.GetType()));
71+
throw new InvalidOperationException(
72+
Resources.
73+
FormatTokenValidator_AuthenticatedUserWithoutUsername(identity.GetType()));
6474
}
6575

6676
return formToken;
@@ -138,6 +148,11 @@ public void ValidateTokens(HttpContext httpContext, ClaimsIdentity identity, Ant
138148

139149
private static BinaryBlob GetClaimUidBlob(string base64ClaimUid)
140150
{
151+
if (base64ClaimUid == null)
152+
{
153+
return null;
154+
}
155+
141156
return new BinaryBlob(256, Convert.FromBase64String(base64ClaimUid));
142157
}
143158
}

src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)