diff --git a/src/Microsoft.AspNetCore.Antiforgery/Internal/AntiforgeryContext.cs b/src/Microsoft.AspNetCore.Antiforgery/Internal/AntiforgeryFeature.cs similarity index 95% rename from src/Microsoft.AspNetCore.Antiforgery/Internal/AntiforgeryContext.cs rename to src/Microsoft.AspNetCore.Antiforgery/Internal/AntiforgeryFeature.cs index d3f81c694d..ad2a38501d 100644 --- a/src/Microsoft.AspNetCore.Antiforgery/Internal/AntiforgeryContext.cs +++ b/src/Microsoft.AspNetCore.Antiforgery/Internal/AntiforgeryFeature.cs @@ -6,7 +6,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal /// /// Used to hold per-request state. /// - public class AntiforgeryContext + public class AntiforgeryFeature : IAntiforgeryFeature { public bool HaveDeserializedCookieToken { get; set; } diff --git a/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgery.cs b/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgery.cs index 95f0208054..c832a378be 100644 --- a/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgery.cs +++ b/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgery.cs @@ -48,18 +48,18 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal CheckSSLConfig(httpContext); - var antiforgeryContext = GetTokensInternal(httpContext); - var tokenSet = Serialize(antiforgeryContext); + var antiforgeryFeature = GetTokensInternal(httpContext); + var tokenSet = Serialize(antiforgeryFeature); - if (!antiforgeryContext.HaveStoredNewCookieToken) + if (!antiforgeryFeature.HaveStoredNewCookieToken) { - if (antiforgeryContext.NewCookieToken != null) + if (antiforgeryFeature.NewCookieToken != null) { // Serialize handles the new cookie token string. - Debug.Assert(antiforgeryContext.NewCookieTokenString != null); + Debug.Assert(antiforgeryFeature.NewCookieTokenString != null); - SaveCookieTokenAndHeader(httpContext, antiforgeryContext.NewCookieTokenString); - antiforgeryContext.HaveStoredNewCookieToken = true; + SaveCookieTokenAndHeader(httpContext, antiforgeryFeature.NewCookieTokenString); + antiforgeryFeature.HaveStoredNewCookieToken = true; _logger.NewCookieToken(); } else @@ -81,8 +81,8 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal CheckSSLConfig(httpContext); - var antiforgeryContext = GetTokensInternal(httpContext); - return Serialize(antiforgeryContext); + var antiforgeryFeature = GetTokensInternal(httpContext); + return Serialize(antiforgeryFeature); } /// @@ -263,17 +263,17 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal CheckSSLConfig(httpContext); - var antiforgeryContext = GetCookieTokens(httpContext); - if (!antiforgeryContext.HaveStoredNewCookieToken && antiforgeryContext.NewCookieToken != null) + var antiforgeryFeature = GetCookieTokens(httpContext); + if (!antiforgeryFeature.HaveStoredNewCookieToken && antiforgeryFeature.NewCookieToken != null) { - if (antiforgeryContext.NewCookieTokenString == null) + if (antiforgeryFeature.NewCookieTokenString == null) { - antiforgeryContext.NewCookieTokenString = - _tokenSerializer.Serialize(antiforgeryContext.NewCookieToken); + antiforgeryFeature.NewCookieTokenString = + _tokenSerializer.Serialize(antiforgeryFeature.NewCookieToken); } - SaveCookieTokenAndHeader(httpContext, antiforgeryContext.NewCookieTokenString); - antiforgeryContext.HaveStoredNewCookieToken = true; + SaveCookieTokenAndHeader(httpContext, antiforgeryFeature.NewCookieTokenString); + antiforgeryFeature.HaveStoredNewCookieToken = true; _logger.NewCookieToken(); } else @@ -325,35 +325,41 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal return true; } - private AntiforgeryContext GetCookieTokens(HttpContext httpContext) + private static IAntiforgeryFeature GetAntiforgeryFeature(HttpContext httpContext) { - var services = httpContext.RequestServices; - var contextAccessor = services.GetRequiredService(); - if (contextAccessor.Value == null) + var antiforgeryFeature = httpContext.Features.Get(); + if (antiforgeryFeature == null) { - contextAccessor.Value = new AntiforgeryContext(); + antiforgeryFeature = new AntiforgeryFeature(); + httpContext.Features.Set(antiforgeryFeature); } - var antiforgeryContext = contextAccessor.Value; - if (antiforgeryContext.HaveGeneratedNewCookieToken) + return antiforgeryFeature; + } + + private IAntiforgeryFeature GetCookieTokens(HttpContext httpContext) + { + var antiforgeryFeature = GetAntiforgeryFeature(httpContext); + + if (antiforgeryFeature.HaveGeneratedNewCookieToken) { - Debug.Assert(antiforgeryContext.HaveDeserializedCookieToken); + Debug.Assert(antiforgeryFeature.HaveDeserializedCookieToken); // Have executed this method earlier in the context of this request. - return antiforgeryContext; + return antiforgeryFeature; } AntiforgeryToken cookieToken; - if (antiforgeryContext.HaveDeserializedCookieToken) + if (antiforgeryFeature.HaveDeserializedCookieToken) { - cookieToken = antiforgeryContext.CookieToken; + cookieToken = antiforgeryFeature.CookieToken; } else { cookieToken = GetCookieTokenDoesNotThrow(httpContext); - antiforgeryContext.CookieToken = cookieToken; - antiforgeryContext.HaveDeserializedCookieToken = true; + antiforgeryFeature.CookieToken = cookieToken; + antiforgeryFeature.HaveDeserializedCookieToken = true; } AntiforgeryToken newCookieToken; @@ -369,10 +375,10 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal Debug.Assert(_tokenGenerator.IsCookieTokenValid(newCookieToken)); } - antiforgeryContext.HaveGeneratedNewCookieToken = true; - antiforgeryContext.NewCookieToken = newCookieToken; + antiforgeryFeature.HaveGeneratedNewCookieToken = true; + antiforgeryFeature.NewCookieToken = newCookieToken; - return antiforgeryContext; + return antiforgeryFeature; } private AntiforgeryToken GetCookieTokenDoesNotThrow(HttpContext httpContext) @@ -391,42 +397,42 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal } } - private AntiforgeryContext GetTokensInternal(HttpContext httpContext) + private IAntiforgeryFeature GetTokensInternal(HttpContext httpContext) { - var antiforgeryContext = GetCookieTokens(httpContext); - if (antiforgeryContext.NewRequestToken == null) + var antiforgeryFeature = GetCookieTokens(httpContext); + if (antiforgeryFeature.NewRequestToken == null) { - var cookieToken = antiforgeryContext.NewCookieToken ?? antiforgeryContext.CookieToken; - antiforgeryContext.NewRequestToken = _tokenGenerator.GenerateRequestToken( - httpContext, + var cookieToken = antiforgeryFeature.NewCookieToken ?? antiforgeryFeature.CookieToken; + antiforgeryFeature.NewRequestToken = _tokenGenerator.GenerateRequestToken( + httpContext, httpContext.User, cookieToken); } - return antiforgeryContext; + return antiforgeryFeature; } - private AntiforgeryTokenSet Serialize(AntiforgeryContext antiforgeryContext) + private AntiforgeryTokenSet Serialize(IAntiforgeryFeature antiforgeryFeature) { // Should only be called after new tokens have been generated. - Debug.Assert(antiforgeryContext.HaveGeneratedNewCookieToken); - Debug.Assert(antiforgeryContext.NewRequestToken != null); + Debug.Assert(antiforgeryFeature.HaveGeneratedNewCookieToken); + Debug.Assert(antiforgeryFeature.NewRequestToken != null); - if (antiforgeryContext.NewRequestTokenString == null) + if (antiforgeryFeature.NewRequestTokenString == null) { - antiforgeryContext.NewRequestTokenString = - _tokenSerializer.Serialize(antiforgeryContext.NewRequestToken); + antiforgeryFeature.NewRequestTokenString = + _tokenSerializer.Serialize(antiforgeryFeature.NewRequestToken); } - if (antiforgeryContext.NewCookieTokenString == null && antiforgeryContext.NewCookieToken != null) + if (antiforgeryFeature.NewCookieTokenString == null && antiforgeryFeature.NewCookieToken != null) { - antiforgeryContext.NewCookieTokenString = - _tokenSerializer.Serialize(antiforgeryContext.NewCookieToken); + antiforgeryFeature.NewCookieTokenString = + _tokenSerializer.Serialize(antiforgeryFeature.NewCookieToken); } return new AntiforgeryTokenSet( - antiforgeryContext.NewRequestTokenString, - antiforgeryContext.NewCookieTokenString, + antiforgeryFeature.NewRequestTokenString, + antiforgeryFeature.NewCookieTokenString, _options.FormFieldName, _options.HeaderName); } @@ -437,36 +443,30 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal out AntiforgeryToken cookieToken, out AntiforgeryToken requestToken) { - var services = httpContext.RequestServices; - var contextAccessor = services.GetRequiredService(); - if (contextAccessor.Value == null) - { - contextAccessor.Value = new AntiforgeryContext(); - } + var antiforgeryFeature = GetAntiforgeryFeature(httpContext); - var antiforgeryContext = contextAccessor.Value; - if (antiforgeryContext.HaveDeserializedCookieToken) + if (antiforgeryFeature.HaveDeserializedCookieToken) { - cookieToken = antiforgeryContext.CookieToken; + cookieToken = antiforgeryFeature.CookieToken; } else { cookieToken = _tokenSerializer.Deserialize(antiforgeryTokenSet.CookieToken); - antiforgeryContext.CookieToken = cookieToken; - antiforgeryContext.HaveDeserializedCookieToken = true; + antiforgeryFeature.CookieToken = cookieToken; + antiforgeryFeature.HaveDeserializedCookieToken = true; } - if (antiforgeryContext.HaveDeserializedRequestToken) + if (antiforgeryFeature.HaveDeserializedRequestToken) { - requestToken = antiforgeryContext.RequestToken; + requestToken = antiforgeryFeature.RequestToken; } else { requestToken = _tokenSerializer.Deserialize(antiforgeryTokenSet.RequestToken); - antiforgeryContext.RequestToken = requestToken; - antiforgeryContext.HaveDeserializedRequestToken = true; + antiforgeryFeature.RequestToken = requestToken; + antiforgeryFeature.HaveDeserializedRequestToken = true; } } } diff --git a/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgeryContextAccessor.cs b/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgeryContextAccessor.cs deleted file mode 100644 index ab2df64fa1..0000000000 --- a/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgeryContextAccessor.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace Microsoft.AspNetCore.Antiforgery.Internal -{ - public class DefaultAntiforgeryContextAccessor : IAntiforgeryContextAccessor - { - public AntiforgeryContext Value { get; set; } - } -} diff --git a/src/Microsoft.AspNetCore.Antiforgery/Internal/IAntiforgeryContextAccessor.cs b/src/Microsoft.AspNetCore.Antiforgery/Internal/IAntiforgeryContextAccessor.cs deleted file mode 100644 index 238f2a082e..0000000000 --- a/src/Microsoft.AspNetCore.Antiforgery/Internal/IAntiforgeryContextAccessor.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace Microsoft.AspNetCore.Antiforgery.Internal -{ - public interface IAntiforgeryContextAccessor - { - AntiforgeryContext Value { get; set; } - } -} diff --git a/src/Microsoft.AspNetCore.Antiforgery/Internal/IAntiforgeryFeature.cs b/src/Microsoft.AspNetCore.Antiforgery/Internal/IAntiforgeryFeature.cs new file mode 100644 index 0000000000..2404359de7 --- /dev/null +++ b/src/Microsoft.AspNetCore.Antiforgery/Internal/IAntiforgeryFeature.cs @@ -0,0 +1,25 @@ +namespace Microsoft.AspNetCore.Antiforgery.Internal +{ + public interface IAntiforgeryFeature + { + AntiforgeryToken CookieToken { get; set; } + + bool HaveDeserializedCookieToken { get; set; } + + bool HaveDeserializedRequestToken { get; set; } + + bool HaveGeneratedNewCookieToken { get; set; } + + bool HaveStoredNewCookieToken { get; set; } + + AntiforgeryToken NewCookieToken { get; set; } + + string NewCookieTokenString { get; set; } + + AntiforgeryToken NewRequestToken { get; set; } + + string NewRequestTokenString { get; set; } + + AntiforgeryToken RequestToken { get; set; } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Antiforgery/ServiceCollectionExtensions.cs b/src/Microsoft.AspNetCore.Antiforgery/ServiceCollectionExtensions.cs index 2d5b2b808c..bc07489e2c 100644 --- a/src/Microsoft.AspNetCore.Antiforgery/ServiceCollectionExtensions.cs +++ b/src/Microsoft.AspNetCore.Antiforgery/ServiceCollectionExtensions.cs @@ -37,7 +37,6 @@ namespace Microsoft.Extensions.DependencyInjection services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); - services.TryAddScoped(); services.TryAddSingleton(); services.TryAddSingleton(new DefaultObjectPoolProvider()); diff --git a/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTest.cs b/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTest.cs index 2d10221a41..776284ff72 100644 --- a/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTest.cs +++ b/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTest.cs @@ -5,6 +5,7 @@ using System; using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http.Internal; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -181,13 +182,13 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal public void GetTokens_ExistingInvalidCookieToken_GeneratesANewCookieTokenAndANewFormToken() { // Arrange - var contextAccessor = new DefaultAntiforgeryContextAccessor(); + var antiforgeryFeature = new AntiforgeryFeature(); // Generate a new cookie. var context = CreateMockContext( new AntiforgeryOptions(), useOldCookie: false, isOldCookieValid: false, - contextAccessor: contextAccessor); + antiforgeryFeature: antiforgeryFeature); var antiforgery = GetAntiforgery(context); // Act @@ -197,14 +198,14 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal Assert.Equal(context.TestTokenSet.NewCookieTokenString, tokenset.CookieToken); Assert.Equal(context.TestTokenSet.FormTokenString, tokenset.RequestToken); - Assert.NotNull(contextAccessor.Value); - Assert.True(contextAccessor.Value.HaveDeserializedCookieToken); - Assert.Equal(context.TestTokenSet.OldCookieToken, contextAccessor.Value.CookieToken); - Assert.True(contextAccessor.Value.HaveGeneratedNewCookieToken); - Assert.Equal(context.TestTokenSet.NewCookieToken, contextAccessor.Value.NewCookieToken); - Assert.Equal(context.TestTokenSet.NewCookieTokenString, contextAccessor.Value.NewCookieTokenString); - Assert.Equal(context.TestTokenSet.RequestToken, contextAccessor.Value.NewRequestToken); - Assert.Equal(context.TestTokenSet.FormTokenString, contextAccessor.Value.NewRequestTokenString); + Assert.NotNull(antiforgeryFeature); + Assert.True(antiforgeryFeature.HaveDeserializedCookieToken); + Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken); + Assert.True(antiforgeryFeature.HaveGeneratedNewCookieToken); + Assert.Equal(context.TestTokenSet.NewCookieToken, antiforgeryFeature.NewCookieToken); + Assert.Equal(context.TestTokenSet.NewCookieTokenString, antiforgeryFeature.NewCookieTokenString); + Assert.Equal(context.TestTokenSet.RequestToken, antiforgeryFeature.NewRequestToken); + Assert.Equal(context.TestTokenSet.FormTokenString, antiforgeryFeature.NewRequestTokenString); } [Fact] @@ -239,12 +240,12 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal public void GetTokens_ExistingValidCookieToken_GeneratesANewFormToken() { // Arrange - var contextAccessor = new DefaultAntiforgeryContextAccessor(); + var antiforgeryFeature = new AntiforgeryFeature(); var context = CreateMockContext( new AntiforgeryOptions(), useOldCookie: true, isOldCookieValid: true, - contextAccessor: contextAccessor); + antiforgeryFeature: antiforgeryFeature); var antiforgery = GetAntiforgery(context); // Act @@ -254,34 +255,31 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal Assert.Null(tokenset.CookieToken); Assert.Equal(context.TestTokenSet.FormTokenString, tokenset.RequestToken); - Assert.NotNull(contextAccessor.Value); - Assert.True(contextAccessor.Value.HaveDeserializedCookieToken); - Assert.Equal(context.TestTokenSet.OldCookieToken, contextAccessor.Value.CookieToken); - Assert.True(contextAccessor.Value.HaveGeneratedNewCookieToken); - Assert.Null(contextAccessor.Value.NewCookieToken); - Assert.Equal(context.TestTokenSet.RequestToken, contextAccessor.Value.NewRequestToken); - Assert.Equal(context.TestTokenSet.FormTokenString, contextAccessor.Value.NewRequestTokenString); + Assert.NotNull(antiforgeryFeature); + Assert.True(antiforgeryFeature.HaveDeserializedCookieToken); + Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken); + Assert.True(antiforgeryFeature.HaveGeneratedNewCookieToken); + Assert.Null(antiforgeryFeature.NewCookieToken); + Assert.Equal(context.TestTokenSet.RequestToken, antiforgeryFeature.NewRequestToken); + Assert.Equal(context.TestTokenSet.FormTokenString, antiforgeryFeature.NewRequestTokenString); } [Fact] public void GetTokens_DoesNotSerializeTwice() { // Arrange - var contextAccessor = new DefaultAntiforgeryContextAccessor + var antiforgeryFeature = new AntiforgeryFeature { - Value = new AntiforgeryContext - { - HaveDeserializedCookieToken = true, - HaveGeneratedNewCookieToken = true, - NewRequestToken = new AntiforgeryToken(), - NewRequestTokenString = "serialized-form-token-from-context", - }, + HaveDeserializedCookieToken = true, + HaveGeneratedNewCookieToken = true, + NewRequestToken = new AntiforgeryToken(), + NewRequestTokenString = "serialized-form-token-from-context", }; var context = CreateMockContext( new AntiforgeryOptions(), useOldCookie: true, isOldCookieValid: true, - contextAccessor: contextAccessor); + antiforgeryFeature: antiforgeryFeature); var antiforgery = GetAntiforgery(context); @@ -292,7 +290,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal Assert.Null(tokenset.CookieToken); Assert.Equal("serialized-form-token-from-context", tokenset.RequestToken); - Assert.Null(contextAccessor.Value.NewCookieToken); + Assert.Null(antiforgeryFeature.NewCookieToken); // Token serializer not used. context.TokenSerializer.Verify( @@ -307,12 +305,12 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal public void GetAndStoreTokens_ExistingValidCookieToken_NotOverriden() { // Arrange - var contextAccessor = new DefaultAntiforgeryContextAccessor(); + var antiforgeryFeature = new AntiforgeryFeature(); var context = CreateMockContext( new AntiforgeryOptions(), useOldCookie: true, isOldCookieValid: true, - contextAccessor: contextAccessor); + antiforgeryFeature: antiforgeryFeature); var antiforgery = GetAntiforgery(context); // Act @@ -327,25 +325,25 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal Assert.Null(tokenSet.CookieToken); Assert.Equal(context.TestTokenSet.FormTokenString, tokenSet.RequestToken); - Assert.NotNull(contextAccessor.Value); - Assert.True(contextAccessor.Value.HaveDeserializedCookieToken); - Assert.Equal(context.TestTokenSet.OldCookieToken, contextAccessor.Value.CookieToken); - Assert.True(contextAccessor.Value.HaveGeneratedNewCookieToken); - Assert.Null(contextAccessor.Value.NewCookieToken); - Assert.Equal(context.TestTokenSet.RequestToken, contextAccessor.Value.NewRequestToken); - Assert.Equal(context.TestTokenSet.FormTokenString, contextAccessor.Value.NewRequestTokenString); + Assert.NotNull(antiforgeryFeature); + Assert.True(antiforgeryFeature.HaveDeserializedCookieToken); + Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken); + Assert.True(antiforgeryFeature.HaveGeneratedNewCookieToken); + Assert.Null(antiforgeryFeature.NewCookieToken); + Assert.Equal(context.TestTokenSet.RequestToken, antiforgeryFeature.NewRequestToken); + Assert.Equal(context.TestTokenSet.FormTokenString, antiforgeryFeature.NewRequestTokenString); } [Fact] public void GetAndStoreTokens_NoExistingCookieToken_Saved() { // Arrange - var contextAccessor = new DefaultAntiforgeryContextAccessor(); + var antiforgeryFeature = new AntiforgeryFeature(); var context = CreateMockContext( new AntiforgeryOptions(), useOldCookie: false, isOldCookieValid: false, - contextAccessor: contextAccessor); + antiforgeryFeature: antiforgeryFeature); var antiforgery = GetAntiforgery(context); // Act @@ -359,38 +357,35 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal Assert.Equal(context.TestTokenSet.NewCookieTokenString, tokenSet.CookieToken); Assert.Equal(context.TestTokenSet.FormTokenString, tokenSet.RequestToken); - Assert.NotNull(contextAccessor.Value); - Assert.True(contextAccessor.Value.HaveDeserializedCookieToken); - Assert.Equal(context.TestTokenSet.OldCookieToken, contextAccessor.Value.CookieToken); - Assert.True(contextAccessor.Value.HaveGeneratedNewCookieToken); - Assert.Equal(context.TestTokenSet.NewCookieToken, contextAccessor.Value.NewCookieToken); - Assert.Equal(context.TestTokenSet.NewCookieTokenString, contextAccessor.Value.NewCookieTokenString); - Assert.Equal(context.TestTokenSet.RequestToken, contextAccessor.Value.NewRequestToken); - Assert.Equal(context.TestTokenSet.FormTokenString, contextAccessor.Value.NewRequestTokenString); - Assert.True(contextAccessor.Value.HaveStoredNewCookieToken); + Assert.NotNull(antiforgeryFeature); + Assert.True(antiforgeryFeature.HaveDeserializedCookieToken); + Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken); + Assert.True(antiforgeryFeature.HaveGeneratedNewCookieToken); + Assert.Equal(context.TestTokenSet.NewCookieToken, antiforgeryFeature.NewCookieToken); + Assert.Equal(context.TestTokenSet.NewCookieTokenString, antiforgeryFeature.NewCookieTokenString); + Assert.Equal(context.TestTokenSet.RequestToken, antiforgeryFeature.NewRequestToken); + Assert.Equal(context.TestTokenSet.FormTokenString, antiforgeryFeature.NewRequestTokenString); + Assert.True(antiforgeryFeature.HaveStoredNewCookieToken); } [Fact] public void GetAndStoreTokens_DoesNotSerializeTwice() { // Arrange - var contextAccessor = new DefaultAntiforgeryContextAccessor + var antiforgeryFeature = new AntiforgeryFeature { - Value = new AntiforgeryContext - { - HaveDeserializedCookieToken = true, - HaveGeneratedNewCookieToken = true, - NewCookieToken = new AntiforgeryToken(), - NewCookieTokenString = "serialized-cookie-token-from-context", - NewRequestToken = new AntiforgeryToken(), - NewRequestTokenString = "serialized-form-token-from-context", - }, + HaveDeserializedCookieToken = true, + HaveGeneratedNewCookieToken = true, + NewCookieToken = new AntiforgeryToken(), + NewCookieTokenString = "serialized-cookie-token-from-context", + NewRequestToken = new AntiforgeryToken(), + NewRequestTokenString = "serialized-form-token-from-context", }; var context = CreateMockContext( new AntiforgeryOptions(), useOldCookie: true, isOldCookieValid: true, - contextAccessor: contextAccessor); + antiforgeryFeature: antiforgeryFeature); var antiforgery = GetAntiforgery(context); context.TokenStore @@ -418,31 +413,28 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal Assert.Equal("serialized-cookie-token-from-context", tokenset.CookieToken); Assert.Equal("serialized-form-token-from-context", tokenset.RequestToken); - Assert.True(contextAccessor.Value.HaveStoredNewCookieToken); + Assert.True(antiforgeryFeature.HaveStoredNewCookieToken); } [Fact] public void GetAndStoreTokens_DoesNotStoreTwice() { // Arrange - var contextAccessor = new DefaultAntiforgeryContextAccessor + var antiforgeryFeature = new AntiforgeryFeature { - Value = new AntiforgeryContext - { - HaveDeserializedCookieToken = true, - HaveGeneratedNewCookieToken = true, - HaveStoredNewCookieToken = true, - NewCookieToken = new AntiforgeryToken(), - NewCookieTokenString = "serialized-cookie-token-from-context", - NewRequestToken = new AntiforgeryToken(), - NewRequestTokenString = "serialized-form-token-from-context", - }, + HaveDeserializedCookieToken = true, + HaveGeneratedNewCookieToken = true, + HaveStoredNewCookieToken = true, + NewCookieToken = new AntiforgeryToken(), + NewCookieTokenString = "serialized-cookie-token-from-context", + NewRequestToken = new AntiforgeryToken(), + NewRequestTokenString = "serialized-form-token-from-context", }; var context = CreateMockContext( new AntiforgeryOptions(), useOldCookie: true, isOldCookieValid: true, - contextAccessor: contextAccessor); + antiforgeryFeature: antiforgeryFeature); var antiforgery = GetAntiforgery(context); // Act @@ -470,8 +462,8 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal public async Task IsRequestValidAsync_FromStore_Failure() { // Arrange - var contextAccessor = new DefaultAntiforgeryContextAccessor(); - var context = CreateMockContext(new AntiforgeryOptions(), contextAccessor: contextAccessor); + var antiforgeryFeature = new AntiforgeryFeature(); + var context = CreateMockContext(new AntiforgeryOptions(), antiforgeryFeature: antiforgeryFeature); string message; context.TokenGenerator @@ -493,19 +485,19 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal context.TokenGenerator.Verify(); // Failed _after_ updating the AntiforgeryContext. - Assert.NotNull(contextAccessor.Value); - Assert.True(contextAccessor.Value.HaveDeserializedCookieToken); - Assert.Equal(context.TestTokenSet.OldCookieToken, contextAccessor.Value.CookieToken); - Assert.True(contextAccessor.Value.HaveDeserializedRequestToken); - Assert.Equal(context.TestTokenSet.RequestToken, contextAccessor.Value.RequestToken); + Assert.NotNull(antiforgeryFeature); + Assert.True(antiforgeryFeature.HaveDeserializedCookieToken); + Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken); + Assert.True(antiforgeryFeature.HaveDeserializedRequestToken); + Assert.Equal(context.TestTokenSet.RequestToken, antiforgeryFeature.RequestToken); } [Fact] public async Task IsRequestValidAsync_FromStore_Success() { // Arrange - var contextAccessor = new DefaultAntiforgeryContextAccessor(); - var context = CreateMockContext(new AntiforgeryOptions(), contextAccessor: contextAccessor); + var antiforgeryFeature = new AntiforgeryFeature(); + var context = CreateMockContext(new AntiforgeryOptions(), antiforgeryFeature: antiforgeryFeature); context.HttpContext.Request.Method = "POST"; string message; @@ -528,28 +520,25 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal Assert.True(result); context.TokenGenerator.Verify(); - Assert.NotNull(contextAccessor.Value); - Assert.True(contextAccessor.Value.HaveDeserializedCookieToken); - Assert.Equal(context.TestTokenSet.OldCookieToken, contextAccessor.Value.CookieToken); - Assert.True(contextAccessor.Value.HaveDeserializedRequestToken); - Assert.Equal(context.TestTokenSet.RequestToken, contextAccessor.Value.RequestToken); + Assert.NotNull(antiforgeryFeature); + Assert.True(antiforgeryFeature.HaveDeserializedCookieToken); + Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken); + Assert.True(antiforgeryFeature.HaveDeserializedRequestToken); + Assert.Equal(context.TestTokenSet.RequestToken, antiforgeryFeature.RequestToken); } [Fact] public async Task IsRequestValidAsync_DoesNotDeserializeTwice() { // Arrange - var contextAccessor = new DefaultAntiforgeryContextAccessor + var antiforgeryFeature = new AntiforgeryFeature { - Value = new AntiforgeryContext - { - HaveDeserializedCookieToken = true, - CookieToken = new AntiforgeryToken(), - HaveDeserializedRequestToken = true, - RequestToken = new AntiforgeryToken(), - }, + HaveDeserializedCookieToken = true, + CookieToken = new AntiforgeryToken(), + HaveDeserializedRequestToken = true, + RequestToken = new AntiforgeryToken(), }; - var context = CreateMockContext(new AntiforgeryOptions(), contextAccessor: contextAccessor); + var context = CreateMockContext(new AntiforgeryOptions(), antiforgeryFeature: antiforgeryFeature); context.HttpContext.Request.Method = "POST"; string message; @@ -557,8 +546,8 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal .Setup(o => o.TryValidateTokenSet( context.HttpContext, It.IsAny(), - contextAccessor.Value.CookieToken, - contextAccessor.Value.RequestToken, + antiforgeryFeature.CookieToken, + antiforgeryFeature.RequestToken, out message)) .Returns(true) .Verifiable(); @@ -712,8 +701,8 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal public async Task ValidateRequestAsync_FromStore_Failure() { // Arrange - var contextAccessor = new DefaultAntiforgeryContextAccessor(); - var context = CreateMockContext(new AntiforgeryOptions(), contextAccessor: contextAccessor); + var antiforgeryFeature = new AntiforgeryFeature(); + var context = CreateMockContext(new AntiforgeryOptions(), antiforgeryFeature: antiforgeryFeature); var message = "my-message"; context.TokenGenerator @@ -734,19 +723,19 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal context.TokenGenerator.Verify(); // Failed _after_ updating the AntiforgeryContext. - Assert.NotNull(contextAccessor.Value); - Assert.True(contextAccessor.Value.HaveDeserializedCookieToken); - Assert.Equal(context.TestTokenSet.OldCookieToken, contextAccessor.Value.CookieToken); - Assert.True(contextAccessor.Value.HaveDeserializedRequestToken); - Assert.Equal(context.TestTokenSet.RequestToken, contextAccessor.Value.RequestToken); + Assert.NotNull(antiforgeryFeature); + Assert.True(antiforgeryFeature.HaveDeserializedCookieToken); + Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken); + Assert.True(antiforgeryFeature.HaveDeserializedRequestToken); + Assert.Equal(context.TestTokenSet.RequestToken, antiforgeryFeature.RequestToken); } [Fact] public async Task ValidateRequestAsync_FromStore_Success() { // Arrange - var contextAccessor = new DefaultAntiforgeryContextAccessor(); - var context = CreateMockContext(new AntiforgeryOptions(), contextAccessor: contextAccessor); + var antiforgeryFeature = new AntiforgeryFeature(); + var context = CreateMockContext(new AntiforgeryOptions(), antiforgeryFeature: antiforgeryFeature); string message; context.TokenGenerator @@ -767,11 +756,11 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Assert context.TokenGenerator.Verify(); - Assert.NotNull(contextAccessor.Value); - Assert.True(contextAccessor.Value.HaveDeserializedCookieToken); - Assert.Equal(context.TestTokenSet.OldCookieToken, contextAccessor.Value.CookieToken); - Assert.True(contextAccessor.Value.HaveDeserializedRequestToken); - Assert.Equal(context.TestTokenSet.RequestToken, contextAccessor.Value.RequestToken); + Assert.NotNull(antiforgeryFeature); + Assert.True(antiforgeryFeature.HaveDeserializedCookieToken); + Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken); + Assert.True(antiforgeryFeature.HaveDeserializedRequestToken); + Assert.Equal(context.TestTokenSet.RequestToken, antiforgeryFeature.RequestToken); } [Fact] @@ -881,25 +870,22 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal public async Task ValidateRequestAsync_DoesNotDeserializeTwice() { // Arrange - var contextAccessor = new DefaultAntiforgeryContextAccessor + var antiforgeryFeature = new AntiforgeryFeature { - Value = new AntiforgeryContext - { - HaveDeserializedCookieToken = true, - CookieToken = new AntiforgeryToken(), - HaveDeserializedRequestToken = true, - RequestToken = new AntiforgeryToken(), - }, + HaveDeserializedCookieToken = true, + CookieToken = new AntiforgeryToken(), + HaveDeserializedRequestToken = true, + RequestToken = new AntiforgeryToken(), }; - var context = CreateMockContext(new AntiforgeryOptions(), contextAccessor: contextAccessor); + var context = CreateMockContext(new AntiforgeryOptions(), antiforgeryFeature: antiforgeryFeature); string message; context.TokenGenerator .Setup(o => o.TryValidateTokenSet( context.HttpContext, It.IsAny(), - contextAccessor.Value.CookieToken, - contextAccessor.Value.RequestToken, + antiforgeryFeature.CookieToken, + antiforgeryFeature.RequestToken, out message)) .Returns(true) .Verifiable(); @@ -1056,14 +1042,14 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal { SuppressXFrameOptionsHeader = suppressXFrameOptions }; - var contextAccessor = new DefaultAntiforgeryContextAccessor(); + var antiforgeryFeature = new AntiforgeryFeature(); // Generate a new cookie. var context = CreateMockContext( options, useOldCookie: false, isOldCookieValid: false, - contextAccessor: contextAccessor); + antiforgeryFeature: antiforgeryFeature); var antiforgery = GetAntiforgery(context); // Act @@ -1073,36 +1059,33 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal var xFrameOptions = context.HttpContext.Response.Headers["X-Frame-Options"]; Assert.Equal(expectedHeaderValue, xFrameOptions); - Assert.NotNull(contextAccessor.Value); - Assert.True(contextAccessor.Value.HaveDeserializedCookieToken); - Assert.Equal(context.TestTokenSet.OldCookieToken, contextAccessor.Value.CookieToken); - Assert.True(contextAccessor.Value.HaveGeneratedNewCookieToken); - Assert.Equal(context.TestTokenSet.NewCookieToken, contextAccessor.Value.NewCookieToken); - Assert.Equal(context.TestTokenSet.NewCookieTokenString, contextAccessor.Value.NewCookieTokenString); - Assert.True(contextAccessor.Value.HaveStoredNewCookieToken); + Assert.NotNull(antiforgeryFeature); + Assert.True(antiforgeryFeature.HaveDeserializedCookieToken); + Assert.Equal(context.TestTokenSet.OldCookieToken, antiforgeryFeature.CookieToken); + Assert.True(antiforgeryFeature.HaveGeneratedNewCookieToken); + Assert.Equal(context.TestTokenSet.NewCookieToken, antiforgeryFeature.NewCookieToken); + Assert.Equal(context.TestTokenSet.NewCookieTokenString, antiforgeryFeature.NewCookieTokenString); + Assert.True(antiforgeryFeature.HaveStoredNewCookieToken); } [Fact] public void SetCookieTokenAndHeader_DoesNotDeserializeTwice() { // Arrange - var contextAccessor = new DefaultAntiforgeryContextAccessor + var antiforgeryFeature = new AntiforgeryFeature { - Value = new AntiforgeryContext - { - HaveDeserializedCookieToken = true, - HaveGeneratedNewCookieToken = true, - NewCookieToken = new AntiforgeryToken(), - NewCookieTokenString = "serialized-cookie-token-from-context", - NewRequestToken = new AntiforgeryToken(), - NewRequestTokenString = "serialized-form-token-from-context", - }, + HaveDeserializedCookieToken = true, + HaveGeneratedNewCookieToken = true, + NewCookieToken = new AntiforgeryToken(), + NewCookieTokenString = "serialized-cookie-token-from-context", + NewRequestToken = new AntiforgeryToken(), + NewRequestTokenString = "serialized-form-token-from-context", }; var context = CreateMockContext( new AntiforgeryOptions(), useOldCookie: true, isOldCookieValid: true, - contextAccessor: contextAccessor); + antiforgeryFeature: antiforgeryFeature); var antiforgery = GetAntiforgery(context); context.TokenStore @@ -1132,24 +1115,21 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal public void SetCookieTokenAndHeader_DoesNotStoreTwice() { // Arrange - var contextAccessor = new DefaultAntiforgeryContextAccessor + var antiforgeryFeature = new AntiforgeryFeature { - Value = new AntiforgeryContext - { - HaveDeserializedCookieToken = true, - HaveGeneratedNewCookieToken = true, - HaveStoredNewCookieToken = true, - NewCookieToken = new AntiforgeryToken(), - NewCookieTokenString = "serialized-cookie-token-from-context", - NewRequestToken = new AntiforgeryToken(), - NewRequestTokenString = "serialized-form-token-from-context", - }, + HaveDeserializedCookieToken = true, + HaveGeneratedNewCookieToken = true, + HaveStoredNewCookieToken = true, + NewCookieToken = new AntiforgeryToken(), + NewCookieTokenString = "serialized-cookie-token-from-context", + NewRequestToken = new AntiforgeryToken(), + NewRequestTokenString = "serialized-form-token-from-context", }; var context = CreateMockContext( new AntiforgeryOptions(), useOldCookie: true, isOldCookieValid: true, - contextAccessor: contextAccessor); + antiforgeryFeature: antiforgeryFeature); var antiforgery = GetAntiforgery(context); // Act @@ -1192,21 +1172,20 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal loggerFactory: loggerFactory); } - private IServiceProvider GetServices(IAntiforgeryContextAccessor contextAccessor) + private IServiceProvider GetServices() { var builder = new ServiceCollection(); - builder.AddSingleton(contextAccessor); builder.AddSingleton(new LoggerFactory()); return builder.BuildServiceProvider(); } - private HttpContext GetHttpContext(IAntiforgeryContextAccessor contextAccessor = null) + private HttpContext GetHttpContext(IAntiforgeryFeature antiforgeryFeature = null) { var httpContext = new DefaultHttpContext(); - contextAccessor = contextAccessor ?? new DefaultAntiforgeryContextAccessor(); - httpContext.RequestServices = GetServices(contextAccessor); - + antiforgeryFeature = antiforgeryFeature ?? new AntiforgeryFeature(); + httpContext.Features.Set(antiforgeryFeature); + httpContext.RequestServices = GetServices(); httpContext.User = new ClaimsPrincipal(new ClaimsIdentity("some-auth")); return httpContext; @@ -1276,10 +1255,10 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal AntiforgeryOptions options, bool useOldCookie = false, bool isOldCookieValid = true, - IAntiforgeryContextAccessor contextAccessor = null) + IAntiforgeryFeature antiforgeryFeature = null) { // Arrange - var httpContext = GetHttpContext(contextAccessor); + var httpContext = GetHttpContext(antiforgeryFeature); var testTokenSet = GetTokenSet(); var mockSerializer = GetTokenSerializer(testTokenSet);