diff --git a/src/Microsoft.AspNetCore.Antiforgery/AntiforgeryBuilderExtensions.cs b/src/Microsoft.AspNetCore.Antiforgery/AntiforgeryBuilderExtensions.cs deleted file mode 100644 index 7181518dfb..0000000000 --- a/src/Microsoft.AspNetCore.Antiforgery/AntiforgeryBuilderExtensions.cs +++ /dev/null @@ -1,29 +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. - -using System; -using Microsoft.AspNetCore.Antiforgery; - -namespace Microsoft.AspNetCore.Builder -{ - /// - /// Extension methods for configuring the antiforgery middleware. - /// - public static class AntiforgeryBuilderExtensions - { - /// - /// Adds the antiforgery middleware. - /// - /// The . - /// The . - public static IApplicationBuilder UseAntiforgery(this IApplicationBuilder app) - { - if (app == null) - { - throw new ArgumentNullException(nameof(app)); - } - - return app.UseMiddleware(); - } - } -} diff --git a/src/Microsoft.AspNetCore.Antiforgery/AntiforgeryMiddleware.cs b/src/Microsoft.AspNetCore.Antiforgery/AntiforgeryMiddleware.cs deleted file mode 100644 index eccadfd699..0000000000 --- a/src/Microsoft.AspNetCore.Antiforgery/AntiforgeryMiddleware.cs +++ /dev/null @@ -1,65 +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. - -using System; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Antiforgery.Internal; -using Microsoft.AspNetCore.Http; - -namespace Microsoft.AspNetCore.Antiforgery -{ - /// - /// A middleware implementation of antiforgery validation. - /// - public class AntiforgeryMiddleware - { - private readonly IAntiforgery _antiforgery; - private readonly RequestDelegate _next; - - /// - /// Creates a new . - /// - /// The for the next middleware. - /// The . - public AntiforgeryMiddleware(RequestDelegate next, IAntiforgery antiforgery) - { - if (next == null) - { - throw new ArgumentNullException(nameof(next)); - } - - if (antiforgery == null) - { - throw new ArgumentNullException(nameof(antiforgery)); - } - - _next = next; - _antiforgery = antiforgery; - } - - /// - /// Invokes the middleware for the given . - /// - /// The associated with the current request. - /// A which will be completed when execution of the middleware completes. - public async Task Invoke(HttpContext httpContext) - { - if (httpContext == null) - { - throw new ArgumentNullException(nameof(httpContext)); - } - - var handler = new AntiforgeryAuthenticationHandler(_antiforgery); - await handler.InitializeAsync(httpContext); - - try - { - await _next(httpContext); - } - finally - { - handler.Teardown(); - } - } - } -} diff --git a/src/Microsoft.AspNetCore.Antiforgery/IAntiforgery.cs b/src/Microsoft.AspNetCore.Antiforgery/IAntiforgery.cs index d22828ef31..6ac2e44e37 100644 --- a/src/Microsoft.AspNetCore.Antiforgery/IAntiforgery.cs +++ b/src/Microsoft.AspNetCore.Antiforgery/IAntiforgery.cs @@ -1,7 +1,6 @@ // 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. -using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; @@ -47,18 +46,6 @@ namespace Microsoft.AspNetCore.Antiforgery /// Task IsRequestValidAsync(HttpContext httpContext); - /// - /// Asynchronously returns a value indicating whether the request passes antiforgery validation. If the - /// request uses a safe HTTP method (GET, HEAD, OPTIONS, TRACE), the antiforgery token is not validated. - /// - /// The associated with the current request. - /// The claims-based principal to validate. - /// - /// A that, when completed, returns true if the is requst uses a safe HTTP - /// method or contains a value antiforgery token, otherwise returns false. - /// - Task IsRequestValidAsync(HttpContext httpContext, ClaimsPrincipal principal); - /// /// Validates an antiforgery token that was supplied as part of the request. /// @@ -68,16 +55,6 @@ namespace Microsoft.AspNetCore.Antiforgery /// Task ValidateRequestAsync(HttpContext httpContext); - /// - /// Validates an antiforgery token that was supplied as part of the request. - /// - /// The associated with the current request. - /// The claims-based principal to validate. - /// - /// Thrown when the request does not include a valid antiforgery token. - /// - Task ValidateRequestAsync(HttpContext httpContext, ClaimsPrincipal principal); - /// /// Generates and stores an antiforgery cookie token if one is not available or not valid. /// diff --git a/src/Microsoft.AspNetCore.Antiforgery/Internal/AntiforgeryAuthenticationHandler.cs b/src/Microsoft.AspNetCore.Antiforgery/Internal/AntiforgeryAuthenticationHandler.cs deleted file mode 100644 index cffa86c5e4..0000000000 --- a/src/Microsoft.AspNetCore.Antiforgery/Internal/AntiforgeryAuthenticationHandler.cs +++ /dev/null @@ -1,160 +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. - -using System; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Features.Authentication; - -namespace Microsoft.AspNetCore.Antiforgery.Internal -{ - public class AntiforgeryAuthenticationHandler : IAuthenticationHandler - { - private readonly IAntiforgery _antiforgery; - private HttpContext _httpContext; - private IAuthenticationHandler _priorHandler; - - public AntiforgeryAuthenticationHandler(IAntiforgery antiforgery) - { - if (antiforgery == null) - { - throw new ArgumentNullException(nameof(antiforgery)); - } - - _antiforgery = antiforgery; - } - - public async Task InitializeAsync(HttpContext httpContext) - { - if (httpContext == null) - { - throw new ArgumentNullException(nameof(httpContext)); - } - - _httpContext = httpContext; - - var authentication = GetAuthenticationFeature(_httpContext); - - _priorHandler = authentication.Handler; - authentication.Handler = this; - - if (authentication.User != null) - { - if (!await _antiforgery.IsRequestValidAsync(_httpContext)) - { - // Wipe out any existing principal if we can't validate this request. - authentication.User = null; - return; - } - } - } - - public void Teardown() - { - var authentication = GetAuthenticationFeature(_httpContext); - authentication.Handler = _priorHandler; - } - - /// - public async Task AuthenticateAsync(AuthenticateContext context) - { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - if (_priorHandler != null) - { - await _priorHandler.AuthenticateAsync(context); - - var authentication = GetAuthenticationFeature(_httpContext); - if (context.Principal != null) - { - try - { - await _antiforgery.ValidateRequestAsync(_httpContext, context.Principal); - } - catch (AntiforgeryValidationException ex) - { - context.Failed(ex); - return; - } - } - } - } - - /// - public Task ChallengeAsync(ChallengeContext context) - { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - if (_priorHandler != null) - { - return _priorHandler.ChallengeAsync(context); - } - - return TaskCache.CompletedTask; - } - - /// - public void GetDescriptions(DescribeSchemesContext context) - { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - if (_priorHandler != null) - { - _priorHandler.GetDescriptions(context); - } - } - - /// - public Task SignInAsync(SignInContext context) - { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - if (_priorHandler != null) - { - return _priorHandler.SignInAsync(context); - } - - return TaskCache.CompletedTask; - } - - /// - public Task SignOutAsync(SignOutContext context) - { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - if (_priorHandler != null) - { - return _priorHandler.SignOutAsync(context); - } - - return TaskCache.CompletedTask; - } - - private static IHttpAuthenticationFeature GetAuthenticationFeature(HttpContext httpContext) - { - var authentication = httpContext.Features.Get(); - if (authentication == null) - { - authentication = new HttpAuthenticationFeature(); - httpContext.Features.Set(authentication); - } - - return authentication; - } - } -} diff --git a/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgery.cs b/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgery.cs index c832a378be..9227bd6b78 100644 --- a/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgery.cs +++ b/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgery.cs @@ -3,7 +3,6 @@ using System; using System.Diagnostics; -using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; @@ -86,7 +85,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal } /// - public Task IsRequestValidAsync(HttpContext httpContext) + public async Task IsRequestValidAsync(HttpContext httpContext) { if (httpContext == null) { @@ -95,26 +94,13 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal CheckSSLConfig(httpContext); - return IsRequestValidAsync(httpContext, httpContext.User); - } - - /// - public async Task IsRequestValidAsync(HttpContext httpContext, ClaimsPrincipal principal) - { - if (httpContext == null) - { - throw new ArgumentNullException(nameof(httpContext)); - } - - if (principal == null) - { - throw new ArgumentNullException(nameof(principal)); - } - - CheckSSLConfig(httpContext); - - if (!IsValidationRequired(httpContext)) + var method = httpContext.Request.Method; + if (string.Equals(method, "GET", StringComparison.OrdinalIgnoreCase) || + string.Equals(method, "HEAD", StringComparison.OrdinalIgnoreCase) || + string.Equals(method, "OPTIONS", StringComparison.OrdinalIgnoreCase) || + string.Equals(method, "TRACE", StringComparison.OrdinalIgnoreCase)) { + // Validation not needed for these request types. return true; } @@ -140,7 +126,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal string message; var result = _tokenGenerator.TryValidateTokenSet( httpContext, - principal, deserializedCookieToken, deserializedRequestToken, out message); @@ -158,7 +143,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal } /// - public Task ValidateRequestAsync(HttpContext httpContext) + public async Task ValidateRequestAsync(HttpContext httpContext) { if (httpContext == null) { @@ -167,29 +152,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal CheckSSLConfig(httpContext); - return ValidateRequestAsync(httpContext, httpContext.User); - } - - /// - public async Task ValidateRequestAsync(HttpContext httpContext, ClaimsPrincipal principal) - { - if (httpContext == null) - { - throw new ArgumentNullException(nameof(httpContext)); - } - - if (principal == null) - { - throw new ArgumentNullException(nameof(principal)); - } - - CheckSSLConfig(httpContext); - - if (!IsValidationRequired(httpContext)) - { - return; - } - var tokens = await _tokenStore.GetRequestTokensAsync(httpContext); if (tokens.CookieToken == null) { @@ -218,15 +180,12 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal } } - ValidateTokens(httpContext, principal, tokens); + ValidateTokens(httpContext, tokens); _logger.ValidatedAntiforgeryToken(); } - private void ValidateTokens( - HttpContext httpContext, - ClaimsPrincipal principal, - AntiforgeryTokenSet antiforgeryTokenSet) + private void ValidateTokens(HttpContext httpContext, AntiforgeryTokenSet antiforgeryTokenSet) { Debug.Assert(!string.IsNullOrEmpty(antiforgeryTokenSet.CookieToken)); Debug.Assert(!string.IsNullOrEmpty(antiforgeryTokenSet.RequestToken)); @@ -244,7 +203,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal string message; if (!_tokenGenerator.TryValidateTokenSet( httpContext, - principal, deserializedCookieToken, deserializedRequestToken, out message)) @@ -310,21 +268,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal } } - private bool IsValidationRequired(HttpContext httpContext) - { - var method = httpContext.Request.Method; - if (string.Equals(method, "GET", StringComparison.OrdinalIgnoreCase) || - string.Equals(method, "HEAD", StringComparison.OrdinalIgnoreCase) || - string.Equals(method, "OPTIONS", StringComparison.OrdinalIgnoreCase) || - string.Equals(method, "TRACE", StringComparison.OrdinalIgnoreCase)) - { - // Validation not needed for HTTP methods that don't mutate any state. - return false; - } - - return true; - } - private static IAntiforgeryFeature GetAntiforgeryFeature(HttpContext httpContext) { var antiforgeryFeature = httpContext.Features.Get(); @@ -405,7 +348,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal var cookieToken = antiforgeryFeature.NewCookieToken ?? antiforgeryFeature.CookieToken; antiforgeryFeature.NewRequestToken = _tokenGenerator.GenerateRequestToken( httpContext, - httpContext.User, cookieToken); } diff --git a/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgeryTokenGenerator.cs b/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgeryTokenGenerator.cs index 14c102bb51..872f7ed18c 100644 --- a/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgeryTokenGenerator.cs +++ b/src/Microsoft.AspNetCore.Antiforgery/Internal/DefaultAntiforgeryTokenGenerator.cs @@ -35,7 +35,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal /// public AntiforgeryToken GenerateRequestToken( HttpContext httpContext, - ClaimsPrincipal principal, AntiforgeryToken cookieToken) { if (httpContext == null) @@ -64,11 +63,11 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal var isIdentityAuthenticated = false; // populate Username and ClaimUid - var authenticatedIdentity = GetAuthenticatedIdentity(principal); + var authenticatedIdentity = GetAuthenticatedIdentity(httpContext.User); if (authenticatedIdentity != null) { isIdentityAuthenticated = true; - requestToken.ClaimUid = GetClaimUidBlob(_claimUidExtractor.ExtractClaimUid(principal)); + requestToken.ClaimUid = GetClaimUidBlob(_claimUidExtractor.ExtractClaimUid(httpContext.User)); if (requestToken.ClaimUid == null) { @@ -110,7 +109,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal /// public bool TryValidateTokenSet( HttpContext httpContext, - ClaimsPrincipal principal, AntiforgeryToken cookieToken, AntiforgeryToken requestToken, out string message) @@ -152,10 +150,10 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal var currentUsername = string.Empty; BinaryBlob currentClaimUid = null; - var authenticatedIdentity = GetAuthenticatedIdentity(principal); + var authenticatedIdentity = GetAuthenticatedIdentity(httpContext.User); if (authenticatedIdentity != null) { - currentClaimUid = GetClaimUidBlob(_claimUidExtractor.ExtractClaimUid(principal)); + currentClaimUid = GetClaimUidBlob(_claimUidExtractor.ExtractClaimUid(httpContext.User)); if (currentClaimUid == null) { currentUsername = authenticatedIdentity.Name ?? string.Empty; diff --git a/src/Microsoft.AspNetCore.Antiforgery/Internal/IAntiforgeryTokenGenerator.cs b/src/Microsoft.AspNetCore.Antiforgery/Internal/IAntiforgeryTokenGenerator.cs index 8c5d22cf31..c0dff86047 100644 --- a/src/Microsoft.AspNetCore.Antiforgery/Internal/IAntiforgeryTokenGenerator.cs +++ b/src/Microsoft.AspNetCore.Antiforgery/Internal/IAntiforgeryTokenGenerator.cs @@ -1,7 +1,6 @@ // 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. -using System.Security.Claims; using Microsoft.AspNetCore.Http; namespace Microsoft.AspNetCore.Antiforgery.Internal @@ -21,13 +20,9 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal /// Generates a request token corresponding to . /// /// The associated with the current request. - /// The claims-based principal to use for token generation. /// A valid cookie token. /// An . - AntiforgeryToken GenerateRequestToken( - HttpContext httpContext, - ClaimsPrincipal principal, - AntiforgeryToken cookieToken); + AntiforgeryToken GenerateRequestToken(HttpContext httpContext, AntiforgeryToken cookieToken); /// /// Attempts to validate a cookie token. @@ -40,7 +35,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal /// Attempts to validate a cookie and request token set for the given . /// /// The associated with the current request. - /// The claims-based principal to use for token validation. /// A cookie token. /// A request token. /// @@ -49,7 +43,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal /// true if the tokens are valid, otherwise false. bool TryValidateTokenSet( HttpContext httpContext, - ClaimsPrincipal principal, AntiforgeryToken cookieToken, AntiforgeryToken requestToken, out string message); diff --git a/src/Microsoft.AspNetCore.Antiforgery/Internal/TaskCache.cs b/src/Microsoft.AspNetCore.Antiforgery/Internal/TaskCache.cs deleted file mode 100644 index d21d2e7a76..0000000000 --- a/src/Microsoft.AspNetCore.Antiforgery/Internal/TaskCache.cs +++ /dev/null @@ -1,12 +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. - -using System.Threading.Tasks; - -namespace Microsoft.AspNetCore.Antiforgery.Internal -{ - public static class TaskCache - { - public static readonly Task CompletedTask = Task.FromResult(0); - } -} diff --git a/src/Microsoft.AspNetCore.Antiforgery/project.json b/src/Microsoft.AspNetCore.Antiforgery/project.json index b207394d87..9d0fd780b5 100644 --- a/src/Microsoft.AspNetCore.Antiforgery/project.json +++ b/src/Microsoft.AspNetCore.Antiforgery/project.json @@ -19,7 +19,9 @@ }, "dependencies": { "Microsoft.AspNetCore.DataProtection": "1.0.0-*", - "Microsoft.AspNetCore.Http": "1.0.0-*" + "Microsoft.AspNetCore.Http.Abstractions": "1.0.0-*", + "Microsoft.AspNetCore.WebUtilities": "1.0.0-*", + "Microsoft.Extensions.ObjectPool": "1.0.0-*" }, "frameworks": { "netstandard1.3": { diff --git a/test/Microsoft.AspNetCore.Antiforgery.Test/AntiforgeryMiddlewareTest.cs b/test/Microsoft.AspNetCore.Antiforgery.Test/AntiforgeryMiddlewareTest.cs deleted file mode 100644 index 54e40e7d93..0000000000 --- a/test/Microsoft.AspNetCore.Antiforgery.Test/AntiforgeryMiddlewareTest.cs +++ /dev/null @@ -1,380 +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. - -using System; -using System.Security.Claims; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Antiforgery.Internal; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Builder.Internal; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Features.Authentication; -using Microsoft.Extensions.DependencyInjection; -using Moq; -using Xunit; - -namespace Microsoft.AspNetCore.Antiforgery -{ - // These are really more like integration tests and just verify a bunch of different - // reasonable combinations of authN middleware. - public class AntiforgeryMiddlewareTest - { - private readonly ClaimsPrincipal LoggedInUser = new ClaimsPrincipal(new ClaimsIdentity[] - { - new ClaimsIdentity("Test"), - }); - - private readonly ClaimsPrincipal LoggedInUser2 = new ClaimsPrincipal(new ClaimsIdentity[] - { - new ClaimsIdentity("Test"), - }); - - [Fact] - public async Task AutomaticAuthentication_Anonymous() - { - // Arrange - var context = Setup((app) => - { - app.Use(next => new AutomaticAuthenticationMiddleware(next, null).Invoke); - app.UseAntiforgery(); - }); - - var httpContext = new DefaultHttpContext(); - - await context.AppFunc(httpContext); - - Assert.Null(context.Principal); - } - - [Fact] - public async Task AutomaticAuthentication_LoggedIn_WithoutToken() - { - // Arrange - var context = Setup((app) => - { - app.UseMiddleware(LoggedInUser); - app.UseAntiforgery(); - }); - - context.Antiforgery - .Setup(a => a.IsRequestValidAsync(It.IsAny())) - .ReturnsAsync(false); - - var httpContext = new DefaultHttpContext(); - - await context.AppFunc(httpContext); - - Assert.Null(context.Principal); - } - - [Fact] - public async Task AutomaticAuthentication_LoggedIn_WithValidToken() - { - // Arrange - var context = Setup((app) => - { - app.UseMiddleware(LoggedInUser); - app.UseAntiforgery(); - }); - - context.Antiforgery - .Setup(a => a.IsRequestValidAsync(It.IsAny())) - .ReturnsAsync(true); - - var httpContext = new DefaultHttpContext(); - - await context.AppFunc(httpContext); - - Assert.Same(LoggedInUser, context.Principal); - } - - // A middleware after antiforgery in the pipeline can authenticate without going through token - // validation. - [Fact] - public async Task AutomaticAuthentication_LoggedIn_WithoutToken_AuthenticatedBySubsequentMiddleware() - { - // Arrange - var context = Setup((app) => - { - app.UseMiddleware(LoggedInUser); - app.UseAntiforgery(); - app.UseMiddleware(LoggedInUser2); - }); - - context.Antiforgery - .Setup(a => a.IsRequestValidAsync(It.IsAny())) - .ReturnsAsync(false); - - var httpContext = new DefaultHttpContext(); - - await context.AppFunc(httpContext); - - Assert.Same(LoggedInUser2, context.Principal); - } - - [Fact] - public async Task PasiveAuthentication_Anonymous() - { - // Arrange - var context = Setup((app) => - { - app.Use(next => new AuthenticationHandlerMiddleware(next, null).Invoke); - app.UseAntiforgery(); - app.UseMiddleware(); - }); - - var httpContext = new DefaultHttpContext(); - - await context.AppFunc(httpContext); - - Assert.Null(context.Principal); - } - - [Fact] - public async Task PassiveAuthentication_LoggedIn_WithoutToken() - { - // Arrange - var context = Setup((app) => - { - app.UseMiddleware(LoggedInUser); - app.UseAntiforgery(); - app.UseMiddleware(); - }); - - context.Antiforgery - .Setup(a => a.ValidateRequestAsync(It.IsAny(), LoggedInUser)) - .Throws(new AntiforgeryValidationException("error")); - - var httpContext = new DefaultHttpContext(); - - await context.AppFunc(httpContext); - - Assert.Null(context.Principal); - } - - [Fact] - public async Task PassiveAuthentication_LoggedIn_WithValidToken() - { - // Arrange - var context = Setup((app) => - { - app.UseMiddleware(LoggedInUser); - app.UseAntiforgery(); - app.UseMiddleware(); - }); - - context.Antiforgery - .Setup(a => a.ValidateRequestAsync(It.IsAny(), LoggedInUser)) - .Returns(TaskCache.CompletedTask); - - var httpContext = new DefaultHttpContext(); - - await context.AppFunc(httpContext); - - Assert.Same(LoggedInUser, context.Principal); - } - - // A middleware after antiforgery in the pipeline can authenticate without going through token - // validation. - [Fact] - public async Task PassiveAuthentication_LoggedIn_WithoutToken_AuthenticatedBySubsequentMiddleware() - { - // Arrange - var context = Setup((app) => - { - app.UseMiddleware(LoggedInUser); - app.UseAntiforgery(); - app.UseMiddleware(LoggedInUser2); - app.UseMiddleware(); - }); - - var httpContext = new DefaultHttpContext(); - - await context.AppFunc(httpContext); - - Assert.Same(LoggedInUser2, context.Principal); - } - - private static IHttpAuthenticationFeature GetAuthenticationFeature(HttpContext httpContext) - { - var authentication = httpContext.Features.Get(); - if (authentication == null) - { - authentication = new HttpAuthenticationFeature(); - httpContext.Features.Set(authentication); - } - - return authentication; - } - - private static TestContext Setup(Action action) - { - var services = new ServiceCollection(); - services.AddLogging(); - services.AddOptions(); - - var antiforgery = new Mock(MockBehavior.Strict); - services.AddSingleton(antiforgery.Object); - - var result = new TestContext(); - result.Antiforgery = antiforgery; - - var app = new ApplicationBuilder(services.BuildServiceProvider()); - action(app); - - // Capture the logged in user 'after' the middleware so we can validate it. - app.Run(c => - { - result.Principal = GetAuthenticationFeature(c).User; - return TaskCache.CompletedTask; - }); - - result.AppFunc = app.Build(); - return result; - } - - private class TestContext - { - public Mock Antiforgery { get; set; } - - public RequestDelegate AppFunc { get; set; } - - public ClaimsPrincipal Principal { get; set; } - } - - private class AutomaticAuthenticationMiddleware - { - private readonly RequestDelegate _next; - private readonly ClaimsPrincipal _principal; - - public AutomaticAuthenticationMiddleware(RequestDelegate next, ClaimsPrincipal principal) - { - _next = next; - _principal = principal; - } - - public Task Invoke(HttpContext httpContext) - { - GetAuthenticationFeature(httpContext).User = _principal; - return _next(httpContext); - } - } - - private class AuthenticationHandlerMiddleware - { - private readonly RequestDelegate _next; - private readonly ClaimsPrincipal _principal; - - public AuthenticationHandlerMiddleware(RequestDelegate next, ClaimsPrincipal principal) - { - _next = next; - _principal = principal; - } - - public async Task Invoke(HttpContext httpContext) - { - var handler = new AuthenticationHandler(_principal); - await handler.InitializeAsync(httpContext); - - try - { - await _next(httpContext); - } - finally - { - await handler.TeardownAsync(); - } - } - } - - private class AuthenticationHandler : IAuthenticationHandler - { - private readonly ClaimsPrincipal _principal; - private IAuthenticationHandler _priorHandler; - private HttpContext _httpContext; - - public AuthenticationHandler(ClaimsPrincipal principal) - { - _principal = principal; - } - - public Task InitializeAsync(HttpContext httpContext) - { - _httpContext = httpContext; - - var authenticationFeature = GetAuthenticationFeature(_httpContext); - _priorHandler = authenticationFeature.Handler; - authenticationFeature.Handler = this; - - return TaskCache.CompletedTask; - } - - public Task TeardownAsync() - { - var authenticationFeature = GetAuthenticationFeature(_httpContext); - authenticationFeature.Handler = _priorHandler; - - return TaskCache.CompletedTask; - } - - public Task AuthenticateAsync(AuthenticateContext context) - { - if (_principal == null) - { - context.NotAuthenticated(); - } - else - { - context.Authenticated(_principal, null, null); - } - - return TaskCache.CompletedTask; - } - - public Task ChallengeAsync(ChallengeContext context) - { - throw new NotImplementedException(); - } - - public void GetDescriptions(DescribeSchemesContext context) - { - throw new NotImplementedException(); - } - - public Task SignInAsync(SignInContext context) - { - throw new NotImplementedException(); - } - - public Task SignOutAsync(SignOutContext context) - { - throw new NotImplementedException(); - } - } - - private class CallAuthenticateMiddleware - { - private readonly RequestDelegate _next; - - public CallAuthenticateMiddleware(RequestDelegate next) - { - _next = next; - } - - public async Task Invoke(HttpContext httpContext) - { - var authenticationFeature = GetAuthenticationFeature(httpContext); - - var authenticateContext = new AuthenticateContext("Test"); - await httpContext.Authentication.AuthenticateAsync(authenticateContext); - - if (authenticateContext.Accepted) - { - authenticationFeature.User = authenticateContext.Principal; - } - - await _next(httpContext); - } - } - } -} diff --git a/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/AntiforgeryAuthenticationHandlerTest.cs b/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/AntiforgeryAuthenticationHandlerTest.cs deleted file mode 100644 index 331cef1be4..0000000000 --- a/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/AntiforgeryAuthenticationHandlerTest.cs +++ /dev/null @@ -1,291 +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. - -using System.Security.Claims; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Features.Authentication; -using Moq; -using Xunit; - -namespace Microsoft.AspNetCore.Antiforgery.Internal -{ - public class AntiforgeryAuthenticationHandlerTest - { - [Fact] - public async Task IntializeAsync_NoOp_WhenAnonymous() - { - // Arrange - var antiforgery = new Mock(MockBehavior.Strict); - var handler = new AntiforgeryAuthenticationHandler(antiforgery.Object); - - antiforgery - .Setup(a => a.IsRequestValidAsync(It.IsAny())) - .ReturnsAsync(false) - .Verifiable(); - - var httpContext = new DefaultHttpContext(); - - // Act - await handler.InitializeAsync(httpContext); - - // Assert - antiforgery.Verify(a => a.IsRequestValidAsync(It.IsAny()), Times.Never()); - } - - [Fact] - public async Task IntializeAsync_ValidatesRequest_WhenLoggedIn() - { - // Arrange - var antiforgery = new Mock(MockBehavior.Strict); - var handler = new AntiforgeryAuthenticationHandler(antiforgery.Object); - - antiforgery - .Setup(a => a.IsRequestValidAsync(It.IsAny())) - .ReturnsAsync(true) - .Verifiable(); - - var httpContext = new DefaultHttpContext(); - - var authenticationFeature = new HttpAuthenticationFeature(); - httpContext.Features.Set(authenticationFeature); - authenticationFeature.User = new ClaimsPrincipal(); - - // Act - await handler.InitializeAsync(httpContext); - - // Assert - antiforgery.Verify(a => a.IsRequestValidAsync(It.IsAny()), Times.Once()); - } - - [Fact] - public async Task IntializeAsync_ClearsUser_WhenInvalid() - { - // Arrange - var antiforgery = new Mock(MockBehavior.Strict); - var handler = new AntiforgeryAuthenticationHandler(antiforgery.Object); - - antiforgery - .Setup(a => a.IsRequestValidAsync(It.IsAny())) - .ReturnsAsync(false) - .Verifiable(); - - var httpContext = new DefaultHttpContext(); - - var authenticationFeature = new HttpAuthenticationFeature(); - httpContext.Features.Set(authenticationFeature); - authenticationFeature.User = new ClaimsPrincipal(); - - // Act - await handler.InitializeAsync(httpContext); - - // Assert - Assert.Null(authenticationFeature.User); - antiforgery.Verify(a => a.IsRequestValidAsync(It.IsAny()), Times.Once()); - } - - [Fact] - public async Task IntializeAsync_AttachesAuthorizationHandler() - { - // Arrange - var antiforgery = new Mock(MockBehavior.Strict); - var handler = new AntiforgeryAuthenticationHandler(antiforgery.Object); - - antiforgery - .Setup(a => a.IsRequestValidAsync(It.IsAny())) - .ReturnsAsync(false) - .Verifiable(); - - var httpContext = new DefaultHttpContext(); - - var authenticationFeature = new HttpAuthenticationFeature(); - httpContext.Features.Set(authenticationFeature); - - // Act - await handler.InitializeAsync(httpContext); - - // Assert - Assert.Same(handler, authenticationFeature.Handler); - antiforgery.Verify(a => a.IsRequestValidAsync(It.IsAny()), Times.Never()); - } - - [Fact] - public async Task AuthenticateAsync_NoPriorHandler_NoOp() - { - // Arrange - var antiforgery = new Mock(MockBehavior.Strict); - var handler = new AntiforgeryAuthenticationHandler(antiforgery.Object); - - antiforgery - .Setup(a => a.IsRequestValidAsync(It.IsAny())) - .ReturnsAsync(false) - .Verifiable(); - - antiforgery - .Setup(a => a.ValidateRequestAsync(It.IsAny(), It.IsAny())) - .Verifiable(); - - var httpContext = new DefaultHttpContext(); - - var authenticationFeature = new HttpAuthenticationFeature(); - httpContext.Features.Set(authenticationFeature); - - await handler.InitializeAsync(httpContext); - - var authenticateContext = new AuthenticateContext("Test"); - - // Act - await handler.AuthenticateAsync(authenticateContext); - - // Assert - Assert.False(authenticateContext.Accepted); - - antiforgery.Verify(a => a.IsRequestValidAsync(It.IsAny()), Times.Never()); - antiforgery.Verify( - a => a.ValidateRequestAsync(It.IsAny(), It.IsAny()), - Times.Never()); - } - - [Fact] - public async Task AuthenticateAsync_PriorHandlerDoesNotAuthenticate_NoOp() - { - // Arrange - var antiforgery = new Mock(MockBehavior.Strict); - var handler = new AntiforgeryAuthenticationHandler(antiforgery.Object); - - antiforgery - .Setup(a => a.IsRequestValidAsync(It.IsAny())) - .ReturnsAsync(false) - .Verifiable(); - - antiforgery - .Setup(a => a.ValidateRequestAsync(It.IsAny(), It.IsAny())) - .Verifiable(); - - var httpContext = new DefaultHttpContext(); - - var authenticationFeature = new HttpAuthenticationFeature(); - httpContext.Features.Set(authenticationFeature); - var priorHandler = new Mock(MockBehavior.Strict); - authenticationFeature.Handler = priorHandler.Object; - - priorHandler - .Setup(h => h.AuthenticateAsync(It.IsAny())) - .Returns(TaskCache.CompletedTask) - .Callback(c => c.NotAuthenticated()); - - await handler.InitializeAsync(httpContext); - - var authenticateContext = new AuthenticateContext("Test"); - - // Act - await handler.AuthenticateAsync(authenticateContext); - - // Assert - Assert.True(authenticateContext.Accepted); - Assert.Null(authenticateContext.Principal); - - antiforgery.Verify(a => a.IsRequestValidAsync(It.IsAny()), Times.Never()); - antiforgery.Verify( - a => a.ValidateRequestAsync(It.IsAny(), It.IsAny()), - Times.Never()); - } - - [Fact] - public async Task AuthenticateAsync_PriorHandlerSetsPrincipal_Valid() - { - // Arrange - var antiforgery = new Mock(MockBehavior.Strict); - var handler = new AntiforgeryAuthenticationHandler(antiforgery.Object); - - var principal = new ClaimsPrincipal(); - - antiforgery - .Setup(a => a.IsRequestValidAsync(It.IsAny())) - .ReturnsAsync(false) - .Verifiable(); - - antiforgery - .Setup(a => a.ValidateRequestAsync(It.IsAny(), principal)) - .Returns(TaskCache.CompletedTask) - .Verifiable(); - - var httpContext = new DefaultHttpContext(); - - var authenticationFeature = new HttpAuthenticationFeature(); - httpContext.Features.Set(authenticationFeature); - var priorHandler = new Mock(MockBehavior.Strict); - authenticationFeature.Handler = priorHandler.Object; - - priorHandler - .Setup(h => h.AuthenticateAsync(It.IsAny())) - .Returns(TaskCache.CompletedTask) - .Callback(c => c.Authenticated(principal, null, null)); - - await handler.InitializeAsync(httpContext); - - var authenticateContext = new AuthenticateContext("Test"); - - // Act - await handler.AuthenticateAsync(authenticateContext); - - // Assert - Assert.True(authenticateContext.Accepted); - Assert.Same(principal, authenticateContext.Principal); - - antiforgery.Verify(a => a.IsRequestValidAsync(It.IsAny()), Times.Never()); - antiforgery.Verify( - a => a.ValidateRequestAsync(It.IsAny(), principal), - Times.Once()); - } - - [Fact] - public async Task AuthenticateAsync_PriorHandlerSetsPrincipal_Invalid() - { - // Arrange - var antiforgery = new Mock(MockBehavior.Strict); - var handler = new AntiforgeryAuthenticationHandler(antiforgery.Object); - - var principal = new ClaimsPrincipal(); - - antiforgery - .Setup(a => a.IsRequestValidAsync(It.IsAny())) - .ReturnsAsync(false) - .Verifiable(); - - antiforgery - .Setup(a => a.ValidateRequestAsync(It.IsAny(), principal)) - .Throws(new AntiforgeryValidationException("invalid")) - .Verifiable(); - - var httpContext = new DefaultHttpContext(); - - var authenticationFeature = new HttpAuthenticationFeature(); - httpContext.Features.Set(authenticationFeature); - var priorHandler = new Mock(MockBehavior.Strict); - authenticationFeature.Handler = priorHandler.Object; - - priorHandler - .Setup(h => h.AuthenticateAsync(It.IsAny())) - .Returns(TaskCache.CompletedTask) - .Callback(c => c.Authenticated(principal, null, null)); - - await handler.InitializeAsync(httpContext); - - var authenticateContext = new AuthenticateContext("Test"); - - // Act - await handler.AuthenticateAsync(authenticateContext); - - // Assert - Assert.True(authenticateContext.Accepted); - Assert.Null(authenticateContext.Principal); - Assert.NotNull(authenticateContext.Error); - - antiforgery.Verify(a => a.IsRequestValidAsync(It.IsAny()), Times.Never()); - antiforgery.Verify( - a => a.ValidateRequestAsync(It.IsAny(), principal), - Times.Once()); - } - } -} diff --git a/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTest.cs b/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTest.cs index 0677d73a0d..45bd0236ba 100644 --- a/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTest.cs +++ b/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTest.cs @@ -15,22 +15,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal { public class DefaultAntiforgeryTest { - public static TheoryData SafeHttpMethods => new TheoryData() - { - "GeT", - "HEAD", - "options", - "TrAcE", - }; - - public static TheoryData UnsafeHttpMethods => new TheoryData() - { - "PUT", - "post", - "Delete", - "Custom", - }; - [Fact] public async Task ChecksSSL_ValidateRequestAsync_Throws() { @@ -51,26 +35,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal exception.Message); } - [Fact] - public async Task ChecksSSL_ValidateRequestAsync_WithPrincipal_Throws() - { - // Arrange - var httpContext = GetHttpContext(); - var options = new AntiforgeryOptions() - { - RequireSsl = true - }; - var antiforgery = GetAntiforgery(httpContext, options); - - // Act & Assert - var exception = await Assert.ThrowsAsync( - () => antiforgery.ValidateRequestAsync(httpContext, new ClaimsPrincipal())); - Assert.Equal( - @"The antiforgery system has the configuration value AntiforgeryOptions.RequireSsl = true, " + - "but the current request is not an SSL request.", - exception.Message); - } - [Fact] public async Task ChecksSSL_IsRequestValidAsync_Throws() { @@ -92,27 +56,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal exception.Message); } - [Fact] - public async Task ChecksSSL_IsRequestValidAsync_WithPrincipal_Throws() - { - // Arrange - var httpContext = GetHttpContext(); - var options = new AntiforgeryOptions() - { - RequireSsl = true - }; - - var antiforgery = GetAntiforgery(httpContext, options); - - // Act & Assert - var exception = await Assert.ThrowsAsync( - () => antiforgery.IsRequestValidAsync(httpContext, new ClaimsPrincipal())); - Assert.Equal( - @"The antiforgery system has the configuration value AntiforgeryOptions.RequireSsl = true, " + - "but the current request is not an SSL request.", - exception.Message); - } - [Fact] public void ChecksSSL_GetAndStoreTokens_Throws() { @@ -467,7 +410,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal context.TokenGenerator .Setup(o => o.TryValidateTokenSet( context.HttpContext, - It.IsAny(), context.TestTokenSet.OldCookieToken, context.TestTokenSet.RequestToken, out message)) @@ -502,7 +444,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal context.TokenGenerator .Setup(o => o.TryValidateTokenSet( context.HttpContext, - It.IsAny(), context.TestTokenSet.OldCookieToken, context.TestTokenSet.RequestToken, out message)) @@ -543,7 +484,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal context.TokenGenerator .Setup(o => o.TryValidateTokenSet( context.HttpContext, - It.IsAny(), antiforgeryFeature.CookieToken, antiforgeryFeature.RequestToken, out message)) @@ -569,7 +509,10 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal } [Theory] - [MemberData(nameof(SafeHttpMethods))] + [InlineData("GeT")] + [InlineData("HEAD")] + [InlineData("options")] + [InlineData("TrAcE")] public async Task IsRequestValidAsync_SkipsAntiforgery_ForSafeHttpMethods(string httpMethod) { // Arrange @@ -580,7 +523,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal context.TokenGenerator .Setup(o => o.TryValidateTokenSet( context.HttpContext, - It.IsAny(), It.IsAny(), It.IsAny(), out message)) @@ -597,7 +539,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal context.TokenGenerator .Verify(o => o.TryValidateTokenSet( context.HttpContext, - It.IsAny(), It.IsAny(), It.IsAny(), out message), @@ -605,7 +546,10 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal } [Theory] - [MemberData(nameof(UnsafeHttpMethods))] + [InlineData("PUT")] + [InlineData("post")] + [InlineData("Delete")] + [InlineData("Custom")] public async Task IsRequestValidAsync_ValidatesAntiforgery_ForNonSafeHttpMethods(string httpMethod) { // Arrange @@ -616,7 +560,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal context.TokenGenerator .Setup(o => o.TryValidateTokenSet( context.HttpContext, - It.IsAny(), It.IsAny(), It.IsAny(), out message)) @@ -633,68 +576,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal context.TokenGenerator.Verify(); } - [Fact] - public async Task IsRequestValidAsync_UsesPrincipalFromHttpContext() - { - // Arrange - var context = CreateMockContext(new AntiforgeryOptions()); - context.HttpContext.Request.Method = "POST"; - - var principal = new ClaimsPrincipal(); - context.HttpContext.User = principal; - - string message; - context.TokenGenerator - .Setup(o => o.TryValidateTokenSet( - context.HttpContext, - principal, - It.IsAny(), - It.IsAny(), - out message)) - .Returns(true) - .Verifiable(); - - var antiforgery = GetAntiforgery(context); - - // Act - var result = await antiforgery.IsRequestValidAsync(context.HttpContext); - - // Assert - Assert.True(result); - context.TokenGenerator.Verify(); - } - - [Fact] - public async Task IsRequestValidAsync_UsesPassedInPrincipal() - { - // Arrange - var context = CreateMockContext(new AntiforgeryOptions()); - context.HttpContext.Request.Method = "POST"; - - var principal = new ClaimsPrincipal(); - context.HttpContext.User = new ClaimsPrincipal(); // This should be ignored. - - string message; - context.TokenGenerator - .Setup(o => o.TryValidateTokenSet( - context.HttpContext, - principal, - It.IsAny(), - It.IsAny(), - out message)) - .Returns(true) - .Verifiable(); - - var antiforgery = GetAntiforgery(context); - - // Act - var result = await antiforgery.IsRequestValidAsync(context.HttpContext, principal); - - // Assert - Assert.True(result); - context.TokenGenerator.Verify(); - } - [Fact] public async Task ValidateRequestAsync_FromStore_Failure() { @@ -706,7 +587,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal context.TokenGenerator .Setup(o => o.TryValidateTokenSet( context.HttpContext, - It.IsAny(), context.TestTokenSet.OldCookieToken, context.TestTokenSet.RequestToken, out message)) @@ -739,7 +619,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal context.TokenGenerator .Setup(o => o.TryValidateTokenSet( context.HttpContext, - It.IsAny(), context.TestTokenSet.OldCookieToken, context.TestTokenSet.RequestToken, out message)) @@ -881,7 +760,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal context.TokenGenerator .Setup(o => o.TryValidateTokenSet( context.HttpContext, - It.IsAny(), antiforgeryFeature.CookieToken, antiforgeryFeature.RequestToken, out message)) @@ -905,129 +783,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal Times.Never); } - [Theory] - [MemberData(nameof(SafeHttpMethods))] - public async Task ValidateRequestAsync_SkipsAntiforgery_ForSafeHttpMethods(string httpMethod) - { - // Arrange - var context = CreateMockContext(new AntiforgeryOptions()); - context.HttpContext.Request.Method = httpMethod; - - string message; - context.TokenGenerator - .Setup(o => o.TryValidateTokenSet( - context.HttpContext, - It.IsAny(), - It.IsAny(), - It.IsAny(), - out message)) - .Returns(false) - .Verifiable(); - - var antiforgery = GetAntiforgery(context); - - // Act - await antiforgery.ValidateRequestAsync(context.HttpContext); - - // Assert - context.TokenGenerator - .Verify(o => o.TryValidateTokenSet( - context.HttpContext, - It.IsAny(), - It.IsAny(), - It.IsAny(), - out message), - Times.Never); - } - - [Theory] - [MemberData(nameof(UnsafeHttpMethods))] - public async Task ValidateRequestAsync_ValidatesAntiforgery_ForNonSafeHttpMethods(string httpMethod) - { - // Arrange - var context = CreateMockContext(new AntiforgeryOptions()); - context.HttpContext.Request.Method = httpMethod; - - string message; - context.TokenGenerator - .Setup(o => o.TryValidateTokenSet( - context.HttpContext, - It.IsAny(), - It.IsAny(), - It.IsAny(), - out message)) - .Returns(true) - .Verifiable(); - - var antiforgery = GetAntiforgery(context); - - // Act - await antiforgery.ValidateRequestAsync(context.HttpContext); - - // Assert - context.TokenGenerator.Verify(); - } - - [Fact] - public async Task ValidateRequestAsync_UsesPrincipalFromHttpContext() - { - // Arrange - var context = CreateMockContext(new AntiforgeryOptions()); - context.HttpContext.Request.Method = "POST"; - - var principal = new ClaimsPrincipal(); - context.HttpContext.User = principal; - - string message; - context.TokenGenerator - .Setup(o => o.TryValidateTokenSet( - context.HttpContext, - principal, - It.IsAny(), - It.IsAny(), - out message)) - .Returns(true) - .Verifiable(); - - var antiforgery = GetAntiforgery(context); - - // Act - await antiforgery.ValidateRequestAsync(context.HttpContext); - - // Assert - context.TokenGenerator.Verify(); - } - - [Fact] - public async Task ValidateRequestAsync_UsesPassedInPrincipal() - { - // Arrange - var context = CreateMockContext(new AntiforgeryOptions()); - context.HttpContext.Request.Method = "POST"; - - var principal = new ClaimsPrincipal(); - context.HttpContext.User = new ClaimsPrincipal(); // This should be ignored. - - string message; - context.TokenGenerator - .Setup(o => o.TryValidateTokenSet( - context.HttpContext, - principal, - It.IsAny(), - It.IsAny(), - out message)) - .Returns(true) - .Verifiable(); - - var antiforgery = GetAntiforgery(context); - - // Act - await antiforgery.ValidateRequestAsync(context.HttpContext, principal); - - // Assert - context.TokenGenerator.Verify(); - } - [Theory] [InlineData(false, "SAMEORIGIN")] [InlineData(true, null)] @@ -1267,7 +1022,6 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal mockGenerator .Setup(o => o.GenerateRequestToken( httpContext, - It.IsAny(), useOldCookie ? testTokenSet.OldCookieToken : testTokenSet.NewCookieToken)) .Returns(testTokenSet.RequestToken); diff --git a/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTokenGeneratorTest.cs b/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTokenGeneratorTest.cs index 94379071c5..981de8e94c 100644 --- a/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTokenGeneratorTest.cs +++ b/test/Microsoft.AspNetCore.Antiforgery.Test/Internal/DefaultAntiforgeryTokenGeneratorTest.cs @@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Arrange var cookieToken = new AntiforgeryToken() { IsCookieToken = false }; var httpContext = new DefaultHttpContext(); - var principal = new ClaimsPrincipal(new ClaimsIdentity()); + httpContext.User = new ClaimsPrincipal(new ClaimsIdentity()); Assert.False(httpContext.User.Identity.IsAuthenticated); var tokenProvider = new DefaultAntiforgeryTokenGenerator( @@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Act & Assert ExceptionAssert.ThrowsArgument( - () => tokenProvider.GenerateRequestToken(httpContext, principal, cookieToken), + () => tokenProvider.GenerateRequestToken(httpContext, cookieToken), "cookieToken", "The antiforgery cookie token is invalid."); } @@ -54,7 +54,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Arrange var cookieToken = new AntiforgeryToken() { IsCookieToken = true }; var httpContext = new DefaultHttpContext(); - var principal = new ClaimsPrincipal(new ClaimsIdentity()); + httpContext.User = new ClaimsPrincipal(new ClaimsIdentity()); Assert.False(httpContext.User.Identity.IsAuthenticated); var tokenProvider = new DefaultAntiforgeryTokenGenerator( @@ -62,7 +62,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal additionalDataProvider: null); // Act - var fieldToken = tokenProvider.GenerateRequestToken(httpContext, principal, cookieToken); + var fieldToken = tokenProvider.GenerateRequestToken(httpContext, cookieToken); // Assert Assert.NotNull(fieldToken); @@ -83,7 +83,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal }; var httpContext = new DefaultHttpContext(); - var principal = new ClaimsPrincipal(new MyAuthenticatedIdentityWithoutUsername()); + httpContext.User = new ClaimsPrincipal(new MyAuthenticatedIdentityWithoutUsername()); var options = new AntiforgeryOptions(); var claimUidExtractor = new Mock().Object; @@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Act & assert var exception = Assert.Throws( - () => tokenProvider.GenerateRequestToken(httpContext, principal, cookieToken)); + () => tokenProvider.GenerateRequestToken(httpContext, cookieToken)); Assert.Equal( "The provided identity of type " + $"'{typeof(MyAuthenticatedIdentityWithoutUsername).FullName}' " + @@ -114,7 +114,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal var cookieToken = new AntiforgeryToken() { IsCookieToken = true }; var httpContext = new DefaultHttpContext(); - var principal = new ClaimsPrincipal(new MyAuthenticatedIdentityWithoutUsername()); + httpContext.User = new ClaimsPrincipal(new MyAuthenticatedIdentityWithoutUsername()); var mockAdditionalDataProvider = new Mock(); mockAdditionalDataProvider.Setup(o => o.GetAdditionalData(httpContext)) @@ -127,7 +127,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal additionalDataProvider: mockAdditionalDataProvider.Object); // Act - var fieldToken = tokenProvider.GenerateRequestToken(httpContext, principal, cookieToken); + var fieldToken = tokenProvider.GenerateRequestToken(httpContext, cookieToken); // Assert Assert.NotNull(fieldToken); @@ -146,7 +146,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal var identity = GetAuthenticatedIdentity("some-identity"); var httpContext = new DefaultHttpContext(); - var principal = new ClaimsPrincipal(identity); + httpContext.User = new ClaimsPrincipal(identity); byte[] data = new byte[256 / 8]; using (var rng = RandomNumberGenerator.Create()) @@ -165,7 +165,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal additionalDataProvider: null); // Act - var fieldToken = tokenProvider.GenerateRequestToken(httpContext, principal, cookieToken); + var fieldToken = tokenProvider.GenerateRequestToken(httpContext, cookieToken); // Assert Assert.NotNull(fieldToken); @@ -189,7 +189,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal mockIdentity.Setup(o => o.Name) .Returns("my-username"); - var principal = new ClaimsPrincipal(mockIdentity.Object); + httpContext.User = new ClaimsPrincipal(mockIdentity.Object); var claimUidExtractor = new Mock().Object; @@ -198,7 +198,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal additionalDataProvider: null); // Act - var fieldToken = tokenProvider.GenerateRequestToken(httpContext, principal, cookieToken); + var fieldToken = tokenProvider.GenerateRequestToken(httpContext, cookieToken); // Assert Assert.NotNull(fieldToken); @@ -271,7 +271,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal { // Arrange var httpContext = new DefaultHttpContext(); - var principal = new ClaimsPrincipal(new ClaimsIdentity()); + httpContext.User = new ClaimsPrincipal(new ClaimsIdentity()); var fieldtoken = new AntiforgeryToken() { IsCookieToken = false }; @@ -282,7 +282,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Act & Assert string message; var ex = Assert.Throws( - () => tokenProvider.TryValidateTokenSet(httpContext, principal, null, fieldtoken, out message)); + () => tokenProvider.TryValidateTokenSet(httpContext, null, fieldtoken, out message)); var trimmed = ex.Message.Substring(0, ex.Message.IndexOf(Environment.NewLine)); Assert.Equal(@"The required antiforgery cookie token must be provided.", trimmed); @@ -293,7 +293,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal { // Arrange var httpContext = new DefaultHttpContext(); - var principal = new ClaimsPrincipal(new ClaimsIdentity()); + httpContext.User = new ClaimsPrincipal(new ClaimsIdentity()); var cookieToken = new AntiforgeryToken() { IsCookieToken = true }; @@ -305,7 +305,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Act & Assert string message; var ex = Assert.Throws( - () => tokenProvider.TryValidateTokenSet(httpContext, principal, cookieToken, null, out message)); + () => tokenProvider.TryValidateTokenSet(httpContext, cookieToken, null, out message)); var trimmed = ex.Message.Substring(0, ex.Message.IndexOf(Environment.NewLine)); Assert.Equal("The required antiforgery request token must be provided.", trimmed); @@ -316,7 +316,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal { // Arrange var httpContext = new DefaultHttpContext(); - var principal = new ClaimsPrincipal(new ClaimsIdentity()); + httpContext.User = new ClaimsPrincipal(new ClaimsIdentity()); var cookieToken = new AntiforgeryToken() { IsCookieToken = true }; var fieldtoken = new AntiforgeryToken() { IsCookieToken = false }; @@ -331,7 +331,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Act string message; - var result = tokenProvider.TryValidateTokenSet(httpContext, principal, fieldtoken, fieldtoken, out message); + var result = tokenProvider.TryValidateTokenSet(httpContext, fieldtoken, fieldtoken, out message); // Assert Assert.False(result); @@ -343,7 +343,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal { // Arrange var httpContext = new DefaultHttpContext(); - var principal = new ClaimsPrincipal(new ClaimsIdentity()); + httpContext.User = new ClaimsPrincipal(new ClaimsIdentity()); var cookieToken = new AntiforgeryToken() { IsCookieToken = true }; var fieldtoken = new AntiforgeryToken() { IsCookieToken = false }; @@ -358,7 +358,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Act string message; - var result = tokenProvider.TryValidateTokenSet(httpContext, principal, cookieToken, cookieToken, out message); + var result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, cookieToken, out message); // Assert Assert.False(result); @@ -370,7 +370,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal { // Arrange var httpContext = new DefaultHttpContext(); - var principal = new ClaimsPrincipal(new ClaimsIdentity()); + httpContext.User = new ClaimsPrincipal(new ClaimsIdentity()); var cookieToken = new AntiforgeryToken() { IsCookieToken = true }; var fieldtoken = new AntiforgeryToken() { IsCookieToken = false }; @@ -383,7 +383,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Act string message; - var result = tokenProvider.TryValidateTokenSet(httpContext, principal, cookieToken, fieldtoken, out message); + var result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message); // Assert Assert.False(result); @@ -399,7 +399,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Arrange var httpContext = new DefaultHttpContext(); var identity = GetAuthenticatedIdentity(identityUsername); - var principal = new ClaimsPrincipal(identity); + httpContext.User = new ClaimsPrincipal(identity); var cookieToken = new AntiforgeryToken() { IsCookieToken = true }; var fieldtoken = new AntiforgeryToken() @@ -423,7 +423,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Act string message; - var result = tokenProvider.TryValidateTokenSet(httpContext, principal, cookieToken, fieldtoken, out message); + var result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message); // Assert Assert.False(result); @@ -436,7 +436,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Arrange var httpContext = new DefaultHttpContext(); var identity = GetAuthenticatedIdentity("the-user"); - var principal = new ClaimsPrincipal(identity); + httpContext.User = new ClaimsPrincipal(identity); var cookieToken = new AntiforgeryToken() { IsCookieToken = true }; var fieldtoken = new AntiforgeryToken() @@ -461,7 +461,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Act string message; - var result = tokenProvider.TryValidateTokenSet(httpContext, principal, cookieToken, fieldtoken, out message); + var result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message); // Assert Assert.False(result); @@ -474,7 +474,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Arrange var httpContext = new DefaultHttpContext(); var identity = new ClaimsIdentity(); - var principal = new ClaimsPrincipal(identity); + httpContext.User = new ClaimsPrincipal(identity); var cookieToken = new AntiforgeryToken() { IsCookieToken = true }; var fieldtoken = new AntiforgeryToken() @@ -498,7 +498,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Act string message; - var result = tokenProvider.TryValidateTokenSet(httpContext, principal, cookieToken, fieldtoken, out message); + var result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message); // Assert Assert.False(result); @@ -511,7 +511,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Arrange var httpContext = new DefaultHttpContext(); var identity = new ClaimsIdentity(); - var principal = new ClaimsPrincipal(identity); + httpContext.User = new ClaimsPrincipal(identity); var cookieToken = new AntiforgeryToken() { IsCookieToken = true }; var fieldtoken = new AntiforgeryToken() @@ -532,7 +532,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Act string message; - var result = tokenProvider.TryValidateTokenSet(httpContext, principal, cookieToken, fieldtoken, out message); + var result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message); // Assert Assert.True(result); @@ -545,7 +545,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Arrange var httpContext = new DefaultHttpContext(); var identity = GetAuthenticatedIdentity("the-user"); - var principal = new ClaimsPrincipal(identity); + httpContext.User = new ClaimsPrincipal(identity); var cookieToken = new AntiforgeryToken() { IsCookieToken = true }; var fieldtoken = new AntiforgeryToken() @@ -566,7 +566,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Act string message; - var result = tokenProvider.TryValidateTokenSet(httpContext, principal, cookieToken, fieldtoken, out message); + var result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message); // Assert Assert.True(result); @@ -579,7 +579,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Arrange var httpContext = new DefaultHttpContext(); var identity = GetAuthenticatedIdentity("the-user"); - var principal = new ClaimsPrincipal(identity); + httpContext.User = new ClaimsPrincipal(identity); var cookieToken = new AntiforgeryToken() { IsCookieToken = true }; var fieldtoken = new AntiforgeryToken() @@ -599,7 +599,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal // Act string message; - var result = tokenProvider.TryValidateTokenSet(httpContext, principal, cookieToken, fieldtoken, out message); + var result = tokenProvider.TryValidateTokenSet(httpContext, cookieToken, fieldtoken, out message); // Assert Assert.True(result);