Add nullability to antiforgery (#22279)

* Add nullability to antiforgery

Addresses #5680

* Rebase
This commit is contained in:
Pranav K 2020-06-11 20:23:33 -07:00 committed by GitHub
parent 4c4351e11c
commit 20770811a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 154 additions and 141 deletions

View File

@ -0,0 +1,7 @@
<Project>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)..\, Directory.Build.props))\Directory.Build.props" />
<PropertyGroup>
<Nullable>annotations</Nullable>
</PropertyGroup>
</Project>

View File

@ -2,6 +2,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(DefaultNetCoreTargetFramework)</TargetFrameworks>
<Nullable>annotations</Nullable>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'">
<Compile Include="Microsoft.AspNetCore.Antiforgery.netcoreapp.cs" />

View File

@ -9,21 +9,21 @@ namespace Microsoft.AspNetCore.Antiforgery
public AntiforgeryOptions() { }
public Microsoft.AspNetCore.Http.CookieBuilder Cookie { get { throw null; } set { } }
public string FormFieldName { get { throw null; } set { } }
public string HeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public string? HeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public bool SuppressXFrameOptionsHeader { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
}
public partial class AntiforgeryTokenSet
{
public AntiforgeryTokenSet(string requestToken, string cookieToken, string formFieldName, string headerName) { }
public string CookieToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public AntiforgeryTokenSet(string? requestToken, string? cookieToken, string formFieldName, string? headerName) { }
public string? CookieToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public string FormFieldName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public string HeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public string RequestToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public string? HeaderName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public string? RequestToken { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
}
public partial class AntiforgeryValidationException : System.Exception
{
public AntiforgeryValidationException(string message) { }
public AntiforgeryValidationException(string message, System.Exception innerException) { }
public AntiforgeryValidationException(string message, System.Exception? innerException) { }
}
public partial interface IAntiforgery
{

View File

@ -73,7 +73,7 @@ namespace Microsoft.AspNetCore.Antiforgery
/// Specifies the name of the header value that is used by the antiforgery system. If <c>null</c> then
/// antiforgery validation will only consider form data.
/// </summary>
public string HeaderName { get; set; } = AntiforgeryTokenHeaderName;
public string? HeaderName { get; set; } = AntiforgeryTokenHeaderName;
/// <summary>
/// Specifies whether to suppress the generation of X-Frame-Options header

View File

@ -18,10 +18,10 @@ namespace Microsoft.AspNetCore.Antiforgery
/// <param name="formFieldName">The name of the form field used for the request token.</param>
/// <param name="headerName">The name of the header used for the request token.</param>
public AntiforgeryTokenSet(
string requestToken,
string cookieToken,
string? requestToken,
string? cookieToken,
string formFieldName,
string headerName)
string? headerName)
{
if (formFieldName == null)
{
@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Antiforgery
/// <summary>
/// Gets the request token.
/// </summary>
public string RequestToken { get; }
public string? RequestToken { get; }
/// <summary>
/// Gets the name of the form field used for the request token.
@ -47,11 +47,11 @@ namespace Microsoft.AspNetCore.Antiforgery
/// <summary>
/// Gets the name of the header used for the request token.
/// </summary>
public string HeaderName { get; }
public string? HeaderName { get; }
/// <summary>
/// Gets the cookie token.
/// </summary>
public string CookieToken { get; }
public string? CookieToken { get; }
}
}
}

View File

@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Antiforgery
/// </summary>
/// <param name="message">The message that describes the error.</param>
/// <param name="innerException">The inner <see cref="Exception"/>.</param>
public AntiforgeryValidationException(string message, Exception innerException)
public AntiforgeryValidationException(string message, Exception? innerException)
: base(message, innerException)
{
}

View File

@ -10,23 +10,23 @@ namespace Microsoft.AspNetCore.Antiforgery
{
public bool HaveDeserializedCookieToken { get; set; }
public AntiforgeryToken CookieToken { get; set; }
public AntiforgeryToken? CookieToken { get; set; }
public bool HaveDeserializedRequestToken { get; set; }
public AntiforgeryToken RequestToken { get; set; }
public AntiforgeryToken? RequestToken { get; set; }
public bool HaveGeneratedNewCookieToken { get; set; }
// After HaveGeneratedNewCookieToken is true, remains null if CookieToken is valid.
public AntiforgeryToken NewCookieToken { get; set; }
public AntiforgeryToken? NewCookieToken { get; set; }
// After HaveGeneratedNewCookieToken is true, remains null if CookieToken is valid.
public string NewCookieTokenString { get; set; }
public string? NewCookieTokenString { get; set; }
public AntiforgeryToken NewRequestToken { get; set; }
public AntiforgeryToken? NewRequestToken { get; set; }
public string NewRequestTokenString { get; set; }
public string? NewRequestTokenString { get; set; }
// Always false if NewCookieToken is null. Never store null cookie token or re-store cookie token from request.
public bool HaveStoredNewCookieToken { get; set; }

View File

@ -8,15 +8,15 @@ namespace Microsoft.AspNetCore.Antiforgery
{
internal static class AntiforgeryLoggerExtensions
{
private static readonly Action<ILogger, Exception> _failedToDeserialzeTokens;
private static readonly Action<ILogger, string, Exception> _validationFailed;
private static readonly Action<ILogger, Exception> _validated;
private static readonly Action<ILogger, string, Exception> _missingCookieToken;
private static readonly Action<ILogger, string, string, Exception> _missingRequestToken;
private static readonly Action<ILogger, Exception> _newCookieToken;
private static readonly Action<ILogger, Exception> _reusedCookieToken;
private static readonly Action<ILogger, Exception> _tokenDeserializeException;
private static readonly Action<ILogger, Exception> _responseCacheHeadersOverridenToNoCache;
private static readonly Action<ILogger, Exception?> _failedToDeserialzeTokens;
private static readonly Action<ILogger, string, Exception?> _validationFailed;
private static readonly Action<ILogger, Exception?> _validated;
private static readonly Action<ILogger, string?, Exception?> _missingCookieToken;
private static readonly Action<ILogger, string, string?, Exception?> _missingRequestToken;
private static readonly Action<ILogger, Exception?> _newCookieToken;
private static readonly Action<ILogger, Exception?> _reusedCookieToken;
private static readonly Action<ILogger, Exception?> _tokenDeserializeException;
private static readonly Action<ILogger, Exception?> _responseCacheHeadersOverridenToNoCache;
static AntiforgeryLoggerExtensions()
{
@ -28,11 +28,11 @@ namespace Microsoft.AspNetCore.Antiforgery
LogLevel.Debug,
new EventId(2, "Validated"),
"Antiforgery successfully validated a request.");
_missingCookieToken = LoggerMessage.Define<string>(
_missingCookieToken = LoggerMessage.Define<string?>(
LogLevel.Warning,
new EventId(3, "MissingCookieToken"),
"The required antiforgery cookie '{CookieName}' is not present.");
_missingRequestToken = LoggerMessage.Define<string, string>(
_missingRequestToken = LoggerMessage.Define<string, string?>(
LogLevel.Warning,
new EventId(4, "MissingRequestToken"),
"The required antiforgery request token was not provided in either form field '{FormFieldName}' "
@ -71,12 +71,12 @@ namespace Microsoft.AspNetCore.Antiforgery
_validated(logger, null);
}
public static void MissingCookieToken(this ILogger logger, string cookieName)
public static void MissingCookieToken(this ILogger logger, string? cookieName)
{
_missingCookieToken(logger, cookieName, null);
}
public static void MissingRequestToken(this ILogger logger, string formFieldName, string headerName)
public static void MissingRequestToken(this ILogger logger, string formFieldName, string? headerName)
{
_missingRequestToken(logger, formFieldName, headerName, null);
}

View File

@ -23,11 +23,11 @@ namespace Microsoft.AspNetCore.Antiforgery
// Don't let _chars grow beyond 512k characters.
private const int MaximumCharsLength = 0x80000;
private char[] _chars;
private MemoryStream _stream;
private BinaryReader _reader;
private BinaryWriter _writer;
private SHA256 _sha256;
private char[]? _chars;
private MemoryStream? _stream;
private BinaryReader? _reader;
private BinaryWriter? _writer;
private SHA256? _sha256;
public MemoryStream Stream
{
@ -126,9 +126,9 @@ namespace Microsoft.AspNetCore.Antiforgery
{
if (Stream.Capacity > MaximumStreamSize)
{
Stream = null;
Reader = null;
Writer = null;
_stream = null;
_reader = null;
_writer = null;
}
else
{

View File

@ -10,7 +10,7 @@ namespace Microsoft.AspNetCore.Antiforgery
private string _additionalData = string.Empty;
private string _username = string.Empty;
private BinaryBlob _securityToken;
private BinaryBlob? _securityToken;
public string AdditionalData
{
@ -21,11 +21,11 @@ namespace Microsoft.AspNetCore.Antiforgery
}
}
public BinaryBlob ClaimUid { get; set; }
public BinaryBlob? ClaimUid { get; set; }
public bool IsCookieToken { get; set; }
public BinaryBlob SecurityToken
public BinaryBlob? SecurityToken
{
get
{
@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Antiforgery
}
}
public string Username
public string? Username
{
get { return _username; }
set

View File

@ -59,12 +59,12 @@ namespace Microsoft.AspNetCore.Antiforgery
}
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
return Equals(obj as BinaryBlob);
}
public bool Equals(BinaryBlob other)
public bool Equals(BinaryBlob? other)
{
if (other == null)
{

View File

@ -3,6 +3,7 @@
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
@ -125,9 +126,7 @@ namespace Microsoft.AspNetCore.Antiforgery
}
// Extract cookie & request tokens
AntiforgeryToken deserializedCookieToken;
AntiforgeryToken deserializedRequestToken;
if (!TryDeserializeTokens(httpContext, tokens, out deserializedCookieToken, out deserializedRequestToken))
if (!TryDeserializeTokens(httpContext, tokens, out var deserializedCookieToken, out var deserializedRequestToken))
{
return false;
}
@ -137,7 +136,7 @@ namespace Microsoft.AspNetCore.Antiforgery
httpContext,
deserializedCookieToken,
deserializedRequestToken,
out string message);
out var message);
if (result)
{
@ -145,7 +144,7 @@ namespace Microsoft.AspNetCore.Antiforgery
}
else
{
_logger.ValidationFailed(message);
_logger.ValidationFailed(message!);
}
return result;
@ -210,12 +209,11 @@ namespace Microsoft.AspNetCore.Antiforgery
out deserializedRequestToken);
// Validate
string message;
if (!_tokenGenerator.TryValidateTokenSet(
httpContext,
deserializedCookieToken,
deserializedRequestToken,
out message))
out var message))
{
throw new AntiforgeryValidationException(message);
}
@ -306,7 +304,7 @@ namespace Microsoft.AspNetCore.Antiforgery
return antiforgeryFeature;
}
AntiforgeryToken cookieToken;
AntiforgeryToken? cookieToken;
if (antiforgeryFeature.HaveDeserializedCookieToken)
{
cookieToken = antiforgeryFeature.CookieToken;
@ -319,7 +317,7 @@ namespace Microsoft.AspNetCore.Antiforgery
antiforgeryFeature.HaveDeserializedCookieToken = true;
}
AntiforgeryToken newCookieToken;
AntiforgeryToken? newCookieToken;
if (_tokenGenerator.IsCookieTokenValid(cookieToken))
{
// No need for the cookie token from the request after it has been verified.
@ -338,7 +336,7 @@ namespace Microsoft.AspNetCore.Antiforgery
return antiforgeryFeature;
}
private AntiforgeryToken GetCookieTokenDoesNotThrow(HttpContext httpContext)
private AntiforgeryToken? GetCookieTokenDoesNotThrow(HttpContext httpContext)
{
try
{
@ -367,7 +365,7 @@ namespace Microsoft.AspNetCore.Antiforgery
var cookieToken = antiforgeryFeature.NewCookieToken ?? antiforgeryFeature.CookieToken;
antiforgeryFeature.NewRequestToken = _tokenGenerator.GenerateRequestToken(
httpContext,
cookieToken);
cookieToken!);
}
return antiforgeryFeature;
@ -391,8 +389,7 @@ namespace Microsoft.AspNetCore.Antiforgery
private void LogCacheHeaderOverrideWarning(HttpResponse response)
{
var logWarning = false;
CacheControlHeaderValue cacheControlHeaderValue;
if (CacheControlHeaderValue.TryParse(response.Headers[HeaderNames.CacheControl].ToString(), out cacheControlHeaderValue))
if (CacheControlHeaderValue.TryParse(response.Headers[HeaderNames.CacheControl].ToString(), out var cacheControlHeaderValue))
{
if (!cacheControlHeaderValue.NoCache)
{
@ -434,7 +431,7 @@ namespace Microsoft.AspNetCore.Antiforgery
return new AntiforgeryTokenSet(
antiforgeryFeature.NewRequestTokenString,
antiforgeryFeature.NewCookieTokenString,
antiforgeryFeature.NewCookieTokenString!,
_options.FormFieldName,
_options.HeaderName);
}
@ -442,8 +439,8 @@ namespace Microsoft.AspNetCore.Antiforgery
private bool TryDeserializeTokens(
HttpContext httpContext,
AntiforgeryTokenSet antiforgeryTokenSet,
out AntiforgeryToken cookieToken,
out AntiforgeryToken requestToken)
[NotNullWhen(true)] out AntiforgeryToken? cookieToken,
[NotNullWhen(true)] out AntiforgeryToken? requestToken)
{
try
{
@ -470,11 +467,11 @@ namespace Microsoft.AspNetCore.Antiforgery
if (antiforgeryFeature.HaveDeserializedCookieToken)
{
cookieToken = antiforgeryFeature.CookieToken;
cookieToken = antiforgeryFeature.CookieToken!;
}
else
{
cookieToken = _tokenSerializer.Deserialize(antiforgeryTokenSet.CookieToken);
cookieToken = _tokenSerializer.Deserialize(antiforgeryTokenSet.CookieToken!);
antiforgeryFeature.CookieToken = cookieToken;
antiforgeryFeature.HaveDeserializedCookieToken = true;
@ -482,11 +479,11 @@ namespace Microsoft.AspNetCore.Antiforgery
if (antiforgeryFeature.HaveDeserializedRequestToken)
{
requestToken = antiforgeryFeature.RequestToken;
requestToken = antiforgeryFeature.RequestToken!;
}
else
{
requestToken = _tokenSerializer.Deserialize(antiforgeryTokenSet.RequestToken);
requestToken = _tokenSerializer.Deserialize(antiforgeryTokenSet.RequestToken!);
antiforgeryFeature.RequestToken = requestToken;
antiforgeryFeature.HaveDeserializedRequestToken = true;

View File

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Security.Claims;
using System.Security.Principal;
using Microsoft.AspNetCore.Http;
@ -89,7 +90,7 @@ namespace Microsoft.AspNetCore.Antiforgery
// Application says user is authenticated, but we have no identifier for the user.
throw new InvalidOperationException(
Resources.FormatAntiforgeryTokenValidator_AuthenticatedUserWithoutUsername(
authenticatedIdentity.GetType(),
authenticatedIdentity?.GetType() ?? typeof(ClaimsIdentity),
nameof(IIdentity.IsAuthenticated),
"true",
nameof(IIdentity.Name),
@ -101,7 +102,7 @@ namespace Microsoft.AspNetCore.Antiforgery
}
/// <inheritdoc />
public bool IsCookieTokenValid(AntiforgeryToken cookieToken)
public bool IsCookieTokenValid(AntiforgeryToken? cookieToken)
{
return cookieToken != null && cookieToken.IsCookieToken;
}
@ -111,7 +112,7 @@ namespace Microsoft.AspNetCore.Antiforgery
HttpContext httpContext,
AntiforgeryToken cookieToken,
AntiforgeryToken requestToken,
out string message)
[NotNullWhen(false)] out string? message)
{
if (httpContext == null)
{
@ -148,7 +149,7 @@ namespace Microsoft.AspNetCore.Antiforgery
// Is the incoming token meant for the current user?
var currentUsername = string.Empty;
BinaryBlob currentClaimUid = null;
BinaryBlob? currentClaimUid = null;
var authenticatedIdentity = GetAuthenticatedIdentity(httpContext.User);
if (authenticatedIdentity != null)
@ -193,7 +194,7 @@ namespace Microsoft.AspNetCore.Antiforgery
return true;
}
private static BinaryBlob GetClaimUidBlob(string base64ClaimUid)
private static BinaryBlob? GetClaimUidBlob(string? base64ClaimUid)
{
if (base64ClaimUid == null)
{
@ -203,7 +204,7 @@ namespace Microsoft.AspNetCore.Antiforgery
return new BinaryBlob(256, Convert.FromBase64String(base64ClaimUid));
}
private static ClaimsIdentity GetAuthenticatedIdentity(ClaimsPrincipal claimsPrincipal)
private static ClaimsIdentity? GetAuthenticatedIdentity(ClaimsPrincipal? claimsPrincipal)
{
if (claimsPrincipal == null)
{

View File

@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.Antiforgery
{
var serializationContext = _pool.Get();
Exception innerException = null;
Exception? innerException = null;
try
{
var count = serializedToken.Length;
@ -90,7 +90,7 @@ namespace Microsoft.AspNetCore.Antiforgery
* | `- Username: UTF-8 string with 7-bit integer length prefix
* `- AdditionalData: UTF-8 string with 7-bit integer length prefix
*/
private static AntiforgeryToken Deserialize(BinaryReader reader)
private static AntiforgeryToken? Deserialize(BinaryReader reader)
{
// we can only consume tokens of the same serialized version that we generate
var embeddedVersion = reader.ReadByte();
@ -144,7 +144,7 @@ namespace Microsoft.AspNetCore.Antiforgery
{
var writer = serializationContext.Writer;
writer.Write(TokenVersion);
writer.Write(token.SecurityToken.GetData());
writer.Write(token.SecurityToken!.GetData());
writer.Write(token.IsCookieToken);
if (!token.IsCookieToken)
@ -157,7 +157,7 @@ namespace Microsoft.AspNetCore.Antiforgery
else
{
writer.Write(false /* isClaimsBased */);
writer.Write(token.Username);
writer.Write(token.Username!);
}
writer.Write(token.AdditionalData);

View File

@ -24,11 +24,11 @@ namespace Microsoft.AspNetCore.Antiforgery
_options = optionsAccessor.Value;
}
public string GetCookieToken(HttpContext httpContext)
public string? GetCookieToken(HttpContext httpContext)
{
Debug.Assert(httpContext != null);
var requestCookie = httpContext.Request.Cookies[_options.Cookie.Name];
var requestCookie = httpContext.Request.Cookies[_options.Cookie.Name!];
if (string.IsNullOrEmpty(requestCookie))
{
// unable to find the cookie.
@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Antiforgery
{
Debug.Assert(httpContext != null);
var cookieToken = httpContext.Request.Cookies[_options.Cookie.Name];
var cookieToken = httpContext.Request.Cookies[_options.Cookie.Name!];
// We want to delay reading the form as much as possible, for example in case of large file uploads,
// request token could be part of the header.
@ -84,7 +84,7 @@ namespace Microsoft.AspNetCore.Antiforgery
}
}
httpContext.Response.Cookies.Append(_options.Cookie.Name, token, options);
httpContext.Response.Cookies.Append(_options.Cookie.Name!, token, options);
}
}
}

View File

@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Antiforgery
}
/// <inheritdoc />
public string ExtractClaimUid(ClaimsPrincipal claimsPrincipal)
public string? ExtractClaimUid(ClaimsPrincipal claimsPrincipal)
{
Debug.Assert(claimsPrincipal != null);
@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Antiforgery
return Convert.ToBase64String(claimUidBytes);
}
public static IList<string> GetUniqueIdentifierParameters(IEnumerable<ClaimsIdentity> claimsIdentities)
public static IList<string>? GetUniqueIdentifierParameters(IEnumerable<ClaimsIdentity> claimsIdentities)
{
var identitiesList = claimsIdentities as List<ClaimsIdentity>;
if (identitiesList == null)

View File

@ -1,8 +1,10 @@
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.AspNetCore.Antiforgery
{
internal interface IAntiforgeryFeature
{
AntiforgeryToken CookieToken { get; set; }
AntiforgeryToken? CookieToken { get; set; }
bool HaveDeserializedCookieToken { get; set; }
@ -12,14 +14,14 @@ namespace Microsoft.AspNetCore.Antiforgery
bool HaveStoredNewCookieToken { get; set; }
AntiforgeryToken NewCookieToken { get; set; }
AntiforgeryToken? NewCookieToken { get; set; }
string NewCookieTokenString { get; set; }
string? NewCookieTokenString { get; set; }
AntiforgeryToken NewRequestToken { get; set; }
AntiforgeryToken? NewRequestToken { get; set; }
string NewRequestTokenString { get; set; }
string? NewRequestTokenString { get; set; }
AntiforgeryToken RequestToken { get; set; }
AntiforgeryToken? RequestToken { get; set; }
}
}

View File

@ -1,6 +1,7 @@
// 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.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Http;
namespace Microsoft.AspNetCore.Antiforgery
@ -29,7 +30,7 @@ namespace Microsoft.AspNetCore.Antiforgery
/// </summary>
/// <param name="cookieToken">A valid cookie token.</param>
/// <returns><c>true</c> if the cookie token is valid, otherwise <c>false</c>.</returns>
bool IsCookieTokenValid(AntiforgeryToken cookieToken);
bool IsCookieTokenValid(AntiforgeryToken? cookieToken);
/// <summary>
/// Attempts to validate a cookie and request token set for the given <paramref name="httpContext"/>.
@ -45,6 +46,6 @@ namespace Microsoft.AspNetCore.Antiforgery
HttpContext httpContext,
AntiforgeryToken cookieToken,
AntiforgeryToken requestToken,
out string message);
[NotNullWhen(false)] out string? message);
}
}

View File

@ -8,7 +8,7 @@ namespace Microsoft.AspNetCore.Antiforgery
{
internal interface IAntiforgeryTokenStore
{
string GetCookieToken(HttpContext httpContext);
string? GetCookieToken(HttpContext httpContext);
/// <summary>
/// Gets the cookie and request tokens from the request.

View File

@ -15,6 +15,6 @@ namespace Microsoft.AspNetCore.Antiforgery
/// </summary>
/// <param name="claimsPrincipal">The <see cref="ClaimsPrincipal"/>.</param>
/// <returns>The claims identifier.</returns>
string ExtractClaimUid(ClaimsPrincipal claimsPrincipal);
string? ExtractClaimUid(ClaimsPrincipal claimsPrincipal);
}
}

View File

@ -7,6 +7,7 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>aspnetcore;antiforgery</PackageTags>
<IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>

View File

@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
Assert.Equal("additional data", token.AdditionalData);
// Act & assert - 3
token.AdditionalData = null;
token.AdditionalData = null!;
Assert.Equal("", token.AdditionalData);
}
@ -91,7 +91,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
// Assert
Assert.NotNull(securityToken);
Assert.Equal(AntiforgeryToken.SecurityTokenBitLength, securityToken.BitLength);
Assert.Equal(AntiforgeryToken.SecurityTokenBitLength, securityToken!.BitLength);
// check that we're not making a new one each property call
Assert.Equal(securityToken, token.SecurityToken);
@ -123,10 +123,10 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
// Assert
Assert.NotNull(securityToken);
Assert.Equal(AntiforgeryToken.SecurityTokenBitLength, securityToken.BitLength);
Assert.Equal(AntiforgeryToken.SecurityTokenBitLength, securityToken!.BitLength);
// check that we're not making a new one each property call
Assert.Equal(securityToken, token.SecurityToken);
}
}
}
}

View File

@ -57,7 +57,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
}
[Theory]
[InlineData((object[])null)]
[InlineData((object[]?)null)]
[InlineData(new byte[] { 0x01, 0x02, 0x03 })]
public void Ctor_Data_Bad(byte[] data)
{
@ -93,7 +93,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
{
// Arrange
object blobA = new BinaryBlob(32);
object blobB = null;
object? blobB = null;
// Act & assert
Assert.NotEqual(blobA, blobB);
@ -126,4 +126,4 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
Assert.Equal(expectedHashCode, actualHashCode);
}
}
}
}

View File

@ -509,7 +509,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
var antiforgeryFeature = new AntiforgeryFeature();
var context = CreateMockContext(new AntiforgeryOptions(), antiforgeryFeature: antiforgeryFeature);
string message;
string? message;
context.TokenGenerator
.Setup(o => o.TryValidateTokenSet(
context.HttpContext,
@ -543,7 +543,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
var context = CreateMockContext(new AntiforgeryOptions(), antiforgeryFeature: antiforgeryFeature);
context.HttpContext.Request.Method = "POST";
string message;
string? message;
context.TokenGenerator
.Setup(o => o.TryValidateTokenSet(
context.HttpContext,
@ -583,7 +583,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
var context = CreateMockContext(new AntiforgeryOptions(), antiforgeryFeature: antiforgeryFeature);
context.HttpContext.Request.Method = "POST";
string message;
string? message;
context.TokenGenerator
.Setup(o => o.TryValidateTokenSet(
context.HttpContext,
@ -622,7 +622,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
var context = CreateMockContext(new AntiforgeryOptions());
context.HttpContext.Request.Method = httpMethod;
string message;
string? message;
context.TokenGenerator
.Setup(o => o.TryValidateTokenSet(
context.HttpContext,
@ -659,7 +659,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
var context = CreateMockContext(new AntiforgeryOptions());
context.HttpContext.Request.Method = httpMethod;
string message;
string? message;
context.TokenGenerator
.Setup(o => o.TryValidateTokenSet(
context.HttpContext,
@ -718,7 +718,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
var antiforgeryFeature = new AntiforgeryFeature();
var context = CreateMockContext(new AntiforgeryOptions(), antiforgeryFeature: antiforgeryFeature);
string message;
string? message;
context.TokenGenerator
.Setup(o => o.TryValidateTokenSet(
context.HttpContext,
@ -859,7 +859,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
};
var context = CreateMockContext(new AntiforgeryOptions(), antiforgeryFeature: antiforgeryFeature);
string message;
string? message;
context.TokenGenerator
.Setup(o => o.TryValidateTokenSet(
context.HttpContext,
@ -1122,7 +1122,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
antiforgeryFeature: antiforgeryFeature);
var testTokenSet = new TestTokenSet
{
OldCookieTokenString = null
OldCookieTokenString = null!
};
var nullTokenStore = GetTokenStore(context.HttpContext, testTokenSet, false);
@ -1135,7 +1135,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
antiforgery.SetCookieTokenAndHeader(context.HttpContext);
// Assert
context.TokenSerializer.Verify(s => s.Deserialize(null), Times.Never);
context.TokenSerializer.Verify(s => s.Deserialize(null!), Times.Never);
}
[Fact]
@ -1159,7 +1159,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
antiforgeryFeature: antiforgeryFeature);
var testTokenSet = new TestTokenSet
{
OldCookieTokenString = null
OldCookieTokenString = null!
};
var nullTokenStore = GetTokenStore(context.HttpContext, testTokenSet, false);
@ -1285,10 +1285,10 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
private DefaultAntiforgery GetAntiforgery(
HttpContext httpContext,
AntiforgeryOptions options = null,
IAntiforgeryTokenGenerator tokenGenerator = null,
IAntiforgeryTokenSerializer tokenSerializer = null,
IAntiforgeryTokenStore tokenStore = null)
AntiforgeryOptions? options = null,
IAntiforgeryTokenGenerator? tokenGenerator = null,
IAntiforgeryTokenSerializer? tokenSerializer = null,
IAntiforgeryTokenStore? tokenStore = null)
{
var optionsManager = new TestOptionsManager();
if (options != null)
@ -1299,9 +1299,9 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
var loggerFactory = httpContext.RequestServices.GetRequiredService<ILoggerFactory>();
return new DefaultAntiforgery(
antiforgeryOptionsAccessor: optionsManager,
tokenGenerator: tokenGenerator,
tokenSerializer: tokenSerializer,
tokenStore: tokenStore,
tokenGenerator: tokenGenerator!,
tokenSerializer: tokenSerializer!,
tokenStore: tokenStore!,
loggerFactory: loggerFactory);
}
@ -1313,7 +1313,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
return builder.BuildServiceProvider();
}
private HttpContext GetHttpContext(IAntiforgeryFeature antiforgeryFeature = null)
private HttpContext GetHttpContext(IAntiforgeryFeature? antiforgeryFeature = null)
{
var httpContext = new DefaultHttpContext();
antiforgeryFeature = antiforgeryFeature ?? new AntiforgeryFeature();
@ -1388,7 +1388,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
AntiforgeryOptions options,
bool useOldCookie = false,
bool isOldCookieValid = true,
IAntiforgeryFeature antiforgeryFeature = null)
IAntiforgeryFeature? antiforgeryFeature = null)
{
// Arrange
var httpContext = GetHttpContext(antiforgeryFeature);
@ -1445,32 +1445,32 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
private class TestTokenSet
{
public AntiforgeryToken RequestToken { get; set; }
public AntiforgeryToken RequestToken { get; set; } = default!;
public string FormTokenString { get; set; }
public string FormTokenString { get; set; } = default!;
public AntiforgeryToken OldCookieToken { get; set; }
public AntiforgeryToken OldCookieToken { get; set; } = default!;
public string OldCookieTokenString { get; set; }
public string OldCookieTokenString { get; set; } = default!;
public AntiforgeryToken NewCookieToken { get; set; }
public AntiforgeryToken NewCookieToken { get; set; } = default!;
public string NewCookieTokenString { get; set; }
public string NewCookieTokenString { get; set; } = default!;
}
private class AntiforgeryMockContext
{
public AntiforgeryOptions Options { get; set; }
public AntiforgeryOptions Options { get; set; } = default!;
public TestTokenSet TestTokenSet { get; set; }
public TestTokenSet TestTokenSet { get; set; } = default!;
public HttpContext HttpContext { get; set; }
public HttpContext HttpContext { get; set; } = default!;
public Mock<IAntiforgeryTokenGenerator> TokenGenerator { get; set; }
public Mock<IAntiforgeryTokenGenerator> TokenGenerator { get; set; } = default!;
public Mock<IAntiforgeryTokenStore> TokenStore { get; set; }
public Mock<IAntiforgeryTokenStore> TokenStore { get; set; } = default!;
public Mock<IAntiforgeryTokenSerializer> TokenSerializer { get; set; }
public Mock<IAntiforgeryTokenSerializer> TokenSerializer { get; set; } = default!;
}
private class TestOptionsManager : IOptions<AntiforgeryOptions>

View File

@ -1,6 +1,7 @@
// 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.
#nullable disable
using System;
using System.Security.Claims;
using System.Security.Cryptography;
@ -621,3 +622,4 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
}
}
}
#nullable restore

View File

@ -282,7 +282,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
Assert.NotNull(cookies);
Assert.Equal(_cookieName, cookies.Key);
Assert.Equal("serialized-value", cookies.Value);
Assert.True(cookies.Options.HttpOnly);
Assert.True(cookies.Options!.HttpOnly);
Assert.Equal(defaultCookieSecureValue, cookies.Options.Secure);
}
@ -321,7 +321,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
Assert.NotNull(cookies);
Assert.Equal(_cookieName, cookies.Key);
Assert.Equal("serialized-value", cookies.Value);
Assert.True(cookies.Options.HttpOnly);
Assert.True(cookies.Options!.HttpOnly);
Assert.Equal(expectedCookiePath, cookies.Options.Path);
}
@ -361,7 +361,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
Assert.NotNull(cookies);
Assert.Equal(_cookieName, cookies.Key);
Assert.Equal("serialized-value", cookies.Value);
Assert.True(cookies.Options.HttpOnly);
Assert.True(cookies.Options!.HttpOnly);
Assert.Equal(expectedCookiePath, cookies.Options.Path);
}
@ -400,7 +400,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
Assert.NotNull(cookies);
Assert.Equal(_cookieName, cookies.Key);
Assert.Equal("serialized-value", cookies.Value);
Assert.True(cookies.Options.HttpOnly);
Assert.True(cookies.Options!.HttpOnly);
Assert.Equal("/vdir1", cookies.Options.Path);
Assert.Equal(expectedCookieDomain, cookies.Options.Domain);
}
@ -421,9 +421,9 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
private class MockResponseCookieCollection : IResponseCookies
{
public string Key { get; set; }
public string Value { get; set; }
public CookieOptions Options { get; set; }
public string? Key { get; set; }
public string? Value { get; set; }
public CookieOptions? Options { get; set; }
public int Count { get; set; }
public void Append(string key, string value, CookieOptions options)

View File

@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
var claimsIdentity = (ClaimsIdentity)identity;
// Act
var identiferParameters = DefaultClaimUidExtractor.GetUniqueIdentifierParameters(new ClaimsIdentity[] { claimsIdentity })
var identiferParameters = DefaultClaimUidExtractor.GetUniqueIdentifierParameters(new ClaimsIdentity[] { claimsIdentity })!
.ToArray();
var claims = claimsIdentity.Claims.ToList();
claims.Sort((a, b) => string.Compare(a.Type, b.Type, StringComparison.Ordinal));
@ -258,4 +258,4 @@ namespace Microsoft.AspNetCore.Antiforgery.Internal
}, uniqueIdentifierParameters);
}
}
}
}

View File

@ -2,6 +2,7 @@
<PropertyGroup>
<TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>