Move GenerateCorrelationId and ValidateCorrelationId to RemoteAuthenticationHandler
This commit is contained in:
parent
bafb097e9f
commit
bbcabc0212
|
|
@ -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.
|
|
||||||
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Authentication.OAuth
|
|
||||||
{
|
|
||||||
internal static class Constants
|
|
||||||
{
|
|
||||||
internal const string SecurityAuthenticate = "security.Authenticate";
|
|
||||||
internal const string CorrelationPrefix = ".AspNetCore.Correlation.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -7,15 +7,12 @@ using System.Globalization;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Http.Authentication;
|
using Microsoft.AspNetCore.Http.Authentication;
|
||||||
using Microsoft.AspNetCore.Http.Extensions;
|
using Microsoft.AspNetCore.Http.Extensions;
|
||||||
using Microsoft.AspNetCore.Http.Features.Authentication;
|
using Microsoft.AspNetCore.Http.Features.Authentication;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.Primitives;
|
using Microsoft.Extensions.Primitives;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
|
@ -23,8 +20,6 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
||||||
{
|
{
|
||||||
public class OAuthHandler<TOptions> : RemoteAuthenticationHandler<TOptions> where TOptions : OAuthOptions
|
public class OAuthHandler<TOptions> : RemoteAuthenticationHandler<TOptions> where TOptions : OAuthOptions
|
||||||
{
|
{
|
||||||
private static readonly RandomNumberGenerator CryptoRandom = RandomNumberGenerator.Create();
|
|
||||||
|
|
||||||
public OAuthHandler(HttpClient backchannel)
|
public OAuthHandler(HttpClient backchannel)
|
||||||
{
|
{
|
||||||
Backchannel = backchannel;
|
Backchannel = backchannel;
|
||||||
|
|
@ -177,7 +172,11 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
||||||
throw new ArgumentNullException(nameof(context));
|
throw new ArgumentNullException(nameof(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
var properties = new AuthenticationProperties(context.Properties);
|
var properties = new AuthenticationProperties(context.Properties)
|
||||||
|
{
|
||||||
|
ExpiresUtc = Options.SystemClock.UtcNow.Add(Options.RemoteAuthenticationTimeout)
|
||||||
|
};
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(properties.RedirectUri))
|
if (string.IsNullOrEmpty(properties.RedirectUri))
|
||||||
{
|
{
|
||||||
properties.RedirectUri = CurrentUri;
|
properties.RedirectUri = CurrentUri;
|
||||||
|
|
@ -216,71 +215,5 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
||||||
// OAuth2 3.3 space separated
|
// OAuth2 3.3 space separated
|
||||||
return string.Join(" ", Options.Scope);
|
return string.Join(" ", Options.Scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void GenerateCorrelationId(AuthenticationProperties properties)
|
|
||||||
{
|
|
||||||
if (properties == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(properties));
|
|
||||||
}
|
|
||||||
|
|
||||||
var correlationKey = Constants.CorrelationPrefix + Options.AuthenticationScheme;
|
|
||||||
|
|
||||||
var nonceBytes = new byte[32];
|
|
||||||
CryptoRandom.GetBytes(nonceBytes);
|
|
||||||
var correlationId = Base64UrlTextEncoder.Encode(nonceBytes);
|
|
||||||
|
|
||||||
var cookieOptions = new CookieOptions
|
|
||||||
{
|
|
||||||
HttpOnly = true,
|
|
||||||
Secure = Request.IsHttps
|
|
||||||
};
|
|
||||||
|
|
||||||
properties.Items[correlationKey] = correlationId;
|
|
||||||
|
|
||||||
Response.Cookies.Append(correlationKey, correlationId, cookieOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected bool ValidateCorrelationId(AuthenticationProperties properties)
|
|
||||||
{
|
|
||||||
if (properties == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(properties));
|
|
||||||
}
|
|
||||||
|
|
||||||
var correlationKey = Constants.CorrelationPrefix + Options.AuthenticationScheme;
|
|
||||||
var correlationCookie = Request.Cookies[correlationKey];
|
|
||||||
if (string.IsNullOrEmpty(correlationCookie))
|
|
||||||
{
|
|
||||||
Logger.LogWarning("{0} cookie not found.", correlationKey);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var cookieOptions = new CookieOptions
|
|
||||||
{
|
|
||||||
HttpOnly = true,
|
|
||||||
Secure = Request.IsHttps
|
|
||||||
};
|
|
||||||
Response.Cookies.Delete(correlationKey, cookieOptions);
|
|
||||||
|
|
||||||
string correlationExtra;
|
|
||||||
if (!properties.Items.TryGetValue(
|
|
||||||
correlationKey,
|
|
||||||
out correlationExtra))
|
|
||||||
{
|
|
||||||
Logger.LogWarning("{0} state property not found.", correlationKey);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
properties.Items.Remove(correlationKey);
|
|
||||||
|
|
||||||
if (!string.Equals(correlationCookie, correlationExtra, StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
Logger.LogWarning("{0} correlation cookie and state property mismatch.", correlationKey);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -28,11 +28,6 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly string CookieNoncePrefix = ".AspNetCore.OpenIdConnect.Nonce.";
|
public static readonly string CookieNoncePrefix = ".AspNetCore.OpenIdConnect.Nonce.";
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The prefix used for the state in the cookie.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string CookieStatePrefix = ".AspNetCore.OpenIdConnect.State.";
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The property for the RedirectUri that was used when asking for a 'authorizationCode'.
|
/// The property for the RedirectUri that was used when asking for a 'authorizationCode'.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,10 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
||||||
// order for local RedirectUri
|
// order for local RedirectUri
|
||||||
// 1. challenge.Properties.RedirectUri
|
// 1. challenge.Properties.RedirectUri
|
||||||
// 2. CurrentUri if RedirectUri is not set)
|
// 2. CurrentUri if RedirectUri is not set)
|
||||||
var properties = new AuthenticationProperties(context.Properties);
|
var properties = new AuthenticationProperties(context.Properties)
|
||||||
|
{
|
||||||
|
ExpiresUtc = Options.SystemClock.UtcNow.Add(Options.RemoteAuthenticationTimeout)
|
||||||
|
};
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(properties.RedirectUri))
|
if (string.IsNullOrEmpty(properties.RedirectUri))
|
||||||
{
|
{
|
||||||
|
|
@ -810,7 +813,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
||||||
{
|
{
|
||||||
HttpOnly = true,
|
HttpOnly = true,
|
||||||
Secure = Request.IsHttps,
|
Secure = Request.IsHttps,
|
||||||
Expires = DateTime.UtcNow + Options.ProtocolValidator.NonceLifetime
|
Expires = Options.SystemClock.UtcNow.Add(Options.ProtocolValidator.NonceLifetime)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -857,76 +860,6 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateCorrelationId(AuthenticationProperties properties)
|
|
||||||
{
|
|
||||||
if (properties == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(properties));
|
|
||||||
}
|
|
||||||
|
|
||||||
var correlationKey = OpenIdConnectDefaults.CookieStatePrefix;
|
|
||||||
|
|
||||||
var nonceBytes = new byte[32];
|
|
||||||
CryptoRandom.GetBytes(nonceBytes);
|
|
||||||
var correlationId = Base64UrlTextEncoder.Encode(nonceBytes);
|
|
||||||
|
|
||||||
var cookieOptions = new CookieOptions
|
|
||||||
{
|
|
||||||
HttpOnly = true,
|
|
||||||
Secure = Request.IsHttps,
|
|
||||||
Expires = DateTime.UtcNow + Options.ProtocolValidator.NonceLifetime
|
|
||||||
};
|
|
||||||
|
|
||||||
properties.Items[correlationKey] = correlationId;
|
|
||||||
|
|
||||||
Response.Cookies.Append(correlationKey + correlationId, NonceProperty, cookieOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool ValidateCorrelationId(AuthenticationProperties properties)
|
|
||||||
{
|
|
||||||
if (properties == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(properties));
|
|
||||||
}
|
|
||||||
|
|
||||||
var correlationKey = OpenIdConnectDefaults.CookieStatePrefix;
|
|
||||||
|
|
||||||
string correlationId;
|
|
||||||
if (!properties.Items.TryGetValue(
|
|
||||||
correlationKey,
|
|
||||||
out correlationId))
|
|
||||||
{
|
|
||||||
Logger.LogWarning(26, "{0} state property not found.", correlationKey);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
properties.Items.Remove(correlationKey);
|
|
||||||
|
|
||||||
var cookieName = correlationKey + correlationId;
|
|
||||||
|
|
||||||
var correlationCookie = Request.Cookies[cookieName];
|
|
||||||
if (string.IsNullOrEmpty(correlationCookie))
|
|
||||||
{
|
|
||||||
Logger.LogWarning(27, "{0} cookie not found.", cookieName);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var cookieOptions = new CookieOptions
|
|
||||||
{
|
|
||||||
HttpOnly = true,
|
|
||||||
Secure = Request.IsHttps
|
|
||||||
};
|
|
||||||
Response.Cookies.Delete(cookieName, cookieOptions);
|
|
||||||
|
|
||||||
if (!string.Equals(correlationCookie, NonceProperty, StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
Logger.LogWarning(28, "{0} correlation cookie and state property mismatch.", correlationKey);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private AuthenticationProperties GetPropertiesFromState(string state)
|
private AuthenticationProperties GetPropertiesFromState(string state)
|
||||||
{
|
{
|
||||||
// assume a well formed query string: <a=b&>OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey=kasjd;fljasldkjflksdj<&c=d>
|
// assume a well formed query string: <a=b&>OpenIdConnectAuthenticationDefaults.AuthenticationPropertiesKey=kasjd;fljasldkjflksdj<&c=d>
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,11 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
||||||
throw new ArgumentNullException(nameof(context));
|
throw new ArgumentNullException(nameof(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
var properties = new AuthenticationProperties(context.Properties);
|
var properties = new AuthenticationProperties(context.Properties)
|
||||||
|
{
|
||||||
|
ExpiresUtc = Options.SystemClock.UtcNow.Add(Options.RemoteAuthenticationTimeout)
|
||||||
|
};
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(properties.RedirectUri))
|
if (string.IsNullOrEmpty(properties.RedirectUri))
|
||||||
{
|
{
|
||||||
properties.RedirectUri = CurrentUri;
|
properties.RedirectUri = CurrentUri;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Authentication.Twitter;
|
using Microsoft.AspNetCore.Authentication.Twitter;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
@ -50,5 +51,11 @@ namespace Microsoft.AspNetCore.Builder
|
||||||
get { return (ITwitterEvents)base.Events; }
|
get { return (ITwitterEvents)base.Events; }
|
||||||
set { base.Events = value; }
|
set { base.Events = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// For testing purposes only.
|
||||||
|
/// </summary>
|
||||||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
|
public ISystemClock SystemClock { get; set; } = new SystemClock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,24 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Security.Cryptography;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Http.Features.Authentication;
|
using Microsoft.AspNetCore.Http.Features.Authentication;
|
||||||
|
using Microsoft.AspNetCore.Http.Authentication;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Authentication
|
namespace Microsoft.AspNetCore.Authentication
|
||||||
{
|
{
|
||||||
public abstract class RemoteAuthenticationHandler<TOptions> : AuthenticationHandler<TOptions> where TOptions : RemoteAuthenticationOptions
|
public abstract class RemoteAuthenticationHandler<TOptions> : AuthenticationHandler<TOptions> where TOptions : RemoteAuthenticationOptions
|
||||||
{
|
{
|
||||||
|
private const string CorrelationPrefix = ".AspNetCore.Correlation.";
|
||||||
|
private const string CorrelationProperty = ".xsrf";
|
||||||
|
private const string CorrelationMarker = "N";
|
||||||
|
|
||||||
|
private static readonly RandomNumberGenerator CryptoRandom = RandomNumberGenerator.Create();
|
||||||
|
|
||||||
public override async Task<bool> HandleRequestAsync()
|
public override async Task<bool> HandleRequestAsync()
|
||||||
{
|
{
|
||||||
if (Options.CallbackPath == Request.Path)
|
if (Options.CallbackPath == Request.Path)
|
||||||
|
|
@ -99,5 +108,71 @@ namespace Microsoft.AspNetCore.Authentication
|
||||||
{
|
{
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void GenerateCorrelationId(AuthenticationProperties properties)
|
||||||
|
{
|
||||||
|
if (properties == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(properties));
|
||||||
|
}
|
||||||
|
|
||||||
|
var bytes = new byte[32];
|
||||||
|
CryptoRandom.GetBytes(bytes);
|
||||||
|
var correlationId = Base64UrlTextEncoder.Encode(bytes);
|
||||||
|
|
||||||
|
var cookieOptions = new CookieOptions
|
||||||
|
{
|
||||||
|
HttpOnly = true,
|
||||||
|
Secure = Request.IsHttps,
|
||||||
|
Expires = properties.ExpiresUtc
|
||||||
|
};
|
||||||
|
|
||||||
|
properties.Items[CorrelationProperty] = correlationId;
|
||||||
|
|
||||||
|
var cookieName = CorrelationPrefix + Options.AuthenticationScheme + "." + correlationId;
|
||||||
|
|
||||||
|
Response.Cookies.Append(cookieName, CorrelationMarker, cookieOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual bool ValidateCorrelationId(AuthenticationProperties properties)
|
||||||
|
{
|
||||||
|
if (properties == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(properties));
|
||||||
|
}
|
||||||
|
|
||||||
|
string correlationId;
|
||||||
|
if (!properties.Items.TryGetValue(CorrelationProperty, out correlationId))
|
||||||
|
{
|
||||||
|
Logger.LogWarning(26, "{0} state property not found.", CorrelationPrefix);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
properties.Items.Remove(CorrelationProperty);
|
||||||
|
|
||||||
|
var cookieName = CorrelationPrefix + Options.AuthenticationScheme + "." + correlationId;
|
||||||
|
|
||||||
|
var correlationCookie = Request.Cookies[cookieName];
|
||||||
|
if (string.IsNullOrEmpty(correlationCookie))
|
||||||
|
{
|
||||||
|
Logger.LogWarning(27, "'{0}' cookie not found.", cookieName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var cookieOptions = new CookieOptions
|
||||||
|
{
|
||||||
|
HttpOnly = true,
|
||||||
|
Secure = Request.IsHttps
|
||||||
|
};
|
||||||
|
Response.Cookies.Delete(cookieName, cookieOptions);
|
||||||
|
|
||||||
|
if (!string.Equals(correlationCookie, CorrelationMarker, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
Logger.LogWarning(28, "The correlation cookie value '{0}' did not match the expected value '{1}'.", cookieName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -56,6 +56,11 @@ namespace Microsoft.AspNetCore.Builder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool SaveTokensAsClaims { get; set; }
|
public bool SaveTokensAsClaims { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the time limit for completing the authentication flow (15 minutes by default).
|
||||||
|
/// </summary>
|
||||||
|
public TimeSpan RemoteAuthenticationTimeout { get; set; } = TimeSpan.FromMinutes(15);
|
||||||
|
|
||||||
public IRemoteAuthenticationEvents Events = new RemoteAuthenticationEvents();
|
public IRemoteAuthenticationEvents Events = new RemoteAuthenticationEvents();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -212,14 +212,14 @@ namespace Microsoft.AspNetCore.Authentication.Facebook
|
||||||
}, handler: null);
|
}, handler: null);
|
||||||
|
|
||||||
var properties = new AuthenticationProperties();
|
var properties = new AuthenticationProperties();
|
||||||
var correlationKey = ".AspNetCore.Correlation.Facebook";
|
var correlationKey = ".xsrf";
|
||||||
var correlationValue = "TestCorrelationId";
|
var correlationValue = "TestCorrelationId";
|
||||||
properties.Items.Add(correlationKey, correlationValue);
|
properties.Items.Add(correlationKey, correlationValue);
|
||||||
properties.RedirectUri = "/me";
|
properties.RedirectUri = "/me";
|
||||||
var state = stateFormat.Protect(properties);
|
var state = stateFormat.Protect(properties);
|
||||||
var transaction = await server.SendAsync(
|
var transaction = await server.SendAsync(
|
||||||
"https://example.com/signin-facebook?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
|
"https://example.com/signin-facebook?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
|
||||||
correlationKey + "=" + correlationValue);
|
$".AspNetCore.Correlation.Facebook.{correlationValue}=N");
|
||||||
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
|
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
|
||||||
Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
|
Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
|
||||||
Assert.Equal(1, finalUserInfoEndpoint.Count(c => c == '?'));
|
Assert.Equal(1, finalUserInfoEndpoint.Count(c => c == '?'));
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
||||||
ClientSecret = "Test Secret"
|
ClientSecret = "Test Secret"
|
||||||
});
|
});
|
||||||
var transaction = await server.SendAsync("https://example.com/challenge");
|
var transaction = await server.SendAsync("https://example.com/challenge");
|
||||||
Assert.Contains(".AspNetCore.Correlation.Google=", transaction.SetCookie.Single());
|
Assert.Contains(transaction.SetCookie, cookie => cookie.StartsWith(".AspNetCore.Correlation.Google."));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -124,7 +124,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
||||||
AutomaticChallenge = true
|
AutomaticChallenge = true
|
||||||
});
|
});
|
||||||
var transaction = await server.SendAsync("https://example.com/401");
|
var transaction = await server.SendAsync("https://example.com/401");
|
||||||
Assert.Contains(".AspNetCore.Correlation.Google=", transaction.SetCookie.Single());
|
Assert.Contains(transaction.SetCookie, cookie => cookie.StartsWith(".AspNetCore.Correlation.Google."));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -335,18 +335,18 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var properties = new AuthenticationProperties();
|
var properties = new AuthenticationProperties();
|
||||||
var correlationKey = ".AspNetCore.Correlation.Google";
|
var correlationKey = ".xsrf";
|
||||||
var correlationValue = "TestCorrelationId";
|
var correlationValue = "TestCorrelationId";
|
||||||
properties.Items.Add(correlationKey, correlationValue);
|
properties.Items.Add(correlationKey, correlationValue);
|
||||||
properties.RedirectUri = "/me";
|
properties.RedirectUri = "/me";
|
||||||
var state = stateFormat.Protect(properties);
|
var state = stateFormat.Protect(properties);
|
||||||
var transaction = await server.SendAsync(
|
var transaction = await server.SendAsync(
|
||||||
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
|
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
|
||||||
correlationKey + "=" + correlationValue);
|
$".AspNetCore.Correlation.Google.{correlationValue}=N");
|
||||||
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
|
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
|
||||||
Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
|
Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
|
||||||
Assert.Equal(2, transaction.SetCookie.Count);
|
Assert.Equal(2, transaction.SetCookie.Count);
|
||||||
Assert.Contains(correlationKey, transaction.SetCookie[0]);
|
Assert.Contains($".AspNetCore.Correlation.Google.{correlationValue}", transaction.SetCookie[0]);
|
||||||
Assert.Contains(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);
|
Assert.Contains(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);
|
||||||
|
|
||||||
var authCookie = transaction.AuthenticationCookieValue;
|
var authCookie = transaction.AuthenticationCookieValue;
|
||||||
|
|
@ -394,7 +394,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
||||||
} : new OAuthEvents()
|
} : new OAuthEvents()
|
||||||
});
|
});
|
||||||
var properties = new AuthenticationProperties();
|
var properties = new AuthenticationProperties();
|
||||||
var correlationKey = ".AspNetCore.Correlation.Google";
|
var correlationKey = ".xsrf";
|
||||||
var correlationValue = "TestCorrelationId";
|
var correlationValue = "TestCorrelationId";
|
||||||
properties.Items.Add(correlationKey, correlationValue);
|
properties.Items.Add(correlationKey, correlationValue);
|
||||||
properties.RedirectUri = "/me";
|
properties.RedirectUri = "/me";
|
||||||
|
|
@ -402,7 +402,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
||||||
var state = stateFormat.Protect(properties);
|
var state = stateFormat.Protect(properties);
|
||||||
var sendTask = server.SendAsync(
|
var sendTask = server.SendAsync(
|
||||||
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
|
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
|
||||||
correlationKey + "=" + correlationValue);
|
$".AspNetCore.Correlation.Google.{correlationValue}=N");
|
||||||
if (redirect)
|
if (redirect)
|
||||||
{
|
{
|
||||||
var transaction = await sendTask;
|
var transaction = await sendTask;
|
||||||
|
|
@ -446,14 +446,14 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
||||||
} : new OAuthEvents()
|
} : new OAuthEvents()
|
||||||
});
|
});
|
||||||
var properties = new AuthenticationProperties();
|
var properties = new AuthenticationProperties();
|
||||||
var correlationKey = ".AspNetCore.Correlation.Google";
|
var correlationKey = ".xsrf";
|
||||||
var correlationValue = "TestCorrelationId";
|
var correlationValue = "TestCorrelationId";
|
||||||
properties.Items.Add(correlationKey, correlationValue);
|
properties.Items.Add(correlationKey, correlationValue);
|
||||||
properties.RedirectUri = "/me";
|
properties.RedirectUri = "/me";
|
||||||
var state = stateFormat.Protect(properties);
|
var state = stateFormat.Protect(properties);
|
||||||
var sendTask = server.SendAsync(
|
var sendTask = server.SendAsync(
|
||||||
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
|
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
|
||||||
correlationKey + "=" + correlationValue);
|
$".AspNetCore.Correlation.Google.{correlationValue}=N");
|
||||||
if (redirect)
|
if (redirect)
|
||||||
{
|
{
|
||||||
var transaction = await sendTask;
|
var transaction = await sendTask;
|
||||||
|
|
@ -528,18 +528,18 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var properties = new AuthenticationProperties();
|
var properties = new AuthenticationProperties();
|
||||||
var correlationKey = ".AspNetCore.Correlation.Google";
|
var correlationKey = ".xsrf";
|
||||||
var correlationValue = "TestCorrelationId";
|
var correlationValue = "TestCorrelationId";
|
||||||
properties.Items.Add(correlationKey, correlationValue);
|
properties.Items.Add(correlationKey, correlationValue);
|
||||||
properties.RedirectUri = "/me";
|
properties.RedirectUri = "/me";
|
||||||
var state = stateFormat.Protect(properties);
|
var state = stateFormat.Protect(properties);
|
||||||
var transaction = await server.SendAsync(
|
var transaction = await server.SendAsync(
|
||||||
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
|
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
|
||||||
correlationKey + "=" + correlationValue);
|
$".AspNetCore.Correlation.Google.{correlationValue}=N");
|
||||||
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
|
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
|
||||||
Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
|
Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
|
||||||
Assert.Equal(2, transaction.SetCookie.Count);
|
Assert.Equal(2, transaction.SetCookie.Count);
|
||||||
Assert.Contains(correlationKey, transaction.SetCookie[0]);
|
Assert.Contains($".AspNetCore.Correlation.Google.{correlationValue}", transaction.SetCookie[0]);
|
||||||
Assert.Contains(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);
|
Assert.Contains(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);
|
||||||
|
|
||||||
var authCookie = transaction.AuthenticationCookieValue;
|
var authCookie = transaction.AuthenticationCookieValue;
|
||||||
|
|
@ -607,17 +607,17 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var properties = new AuthenticationProperties();
|
var properties = new AuthenticationProperties();
|
||||||
var correlationKey = ".AspNetCore.Correlation.Google";
|
var correlationKey = ".xsrf";
|
||||||
var correlationValue = "TestCorrelationId";
|
var correlationValue = "TestCorrelationId";
|
||||||
properties.Items.Add(correlationKey, correlationValue);
|
properties.Items.Add(correlationKey, correlationValue);
|
||||||
var state = stateFormat.Protect(properties);
|
var state = stateFormat.Protect(properties);
|
||||||
var transaction = await server.SendAsync(
|
var transaction = await server.SendAsync(
|
||||||
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
|
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
|
||||||
correlationKey + "=" + correlationValue);
|
$".AspNetCore.Correlation.Google.{correlationValue}=N");
|
||||||
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
|
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
|
||||||
Assert.Equal("/", transaction.Response.Headers.GetValues("Location").First());
|
Assert.Equal("/", transaction.Response.Headers.GetValues("Location").First());
|
||||||
Assert.Equal(2, transaction.SetCookie.Count);
|
Assert.Equal(2, transaction.SetCookie.Count);
|
||||||
Assert.Contains(correlationKey, transaction.SetCookie[0]);
|
Assert.Contains($".AspNetCore.Correlation.Google.{correlationValue}", transaction.SetCookie[0]);
|
||||||
Assert.Contains(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);
|
Assert.Contains(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -690,7 +690,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
||||||
});
|
});
|
||||||
|
|
||||||
var properties = new AuthenticationProperties();
|
var properties = new AuthenticationProperties();
|
||||||
var correlationKey = ".AspNetCore.Correlation.Google";
|
var correlationKey = ".xsrf";
|
||||||
var correlationValue = "TestCorrelationId";
|
var correlationValue = "TestCorrelationId";
|
||||||
properties.Items.Add(correlationKey, correlationValue);
|
properties.Items.Add(correlationKey, correlationValue);
|
||||||
properties.RedirectUri = "/foo";
|
properties.RedirectUri = "/foo";
|
||||||
|
|
@ -699,7 +699,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
||||||
//Post a message to the Google middleware
|
//Post a message to the Google middleware
|
||||||
var transaction = await server.SendAsync(
|
var transaction = await server.SendAsync(
|
||||||
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
|
"https://example.com/signin-google?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
|
||||||
correlationKey + "=" + correlationValue);
|
$".AspNetCore.Correlation.Google.{correlationValue}=N");
|
||||||
|
|
||||||
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
|
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
|
||||||
Assert.Equal("/foo", transaction.Response.Headers.GetValues("Location").First());
|
Assert.Equal("/foo", transaction.Response.Headers.GetValues("Location").First());
|
||||||
|
|
|
||||||
|
|
@ -152,18 +152,18 @@ namespace Microsoft.AspNetCore.Authentication.Tests.MicrosoftAccount
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var properties = new AuthenticationProperties();
|
var properties = new AuthenticationProperties();
|
||||||
var correlationKey = ".AspNetCore.Correlation.Microsoft";
|
var correlationKey = ".xsrf";
|
||||||
var correlationValue = "TestCorrelationId";
|
var correlationValue = "TestCorrelationId";
|
||||||
properties.Items.Add(correlationKey, correlationValue);
|
properties.Items.Add(correlationKey, correlationValue);
|
||||||
properties.RedirectUri = "/me";
|
properties.RedirectUri = "/me";
|
||||||
var state = stateFormat.Protect(properties);
|
var state = stateFormat.Protect(properties);
|
||||||
var transaction = await server.SendAsync(
|
var transaction = await server.SendAsync(
|
||||||
"https://example.com/signin-microsoft?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
|
"https://example.com/signin-microsoft?code=TestCode&state=" + UrlEncoder.Default.Encode(state),
|
||||||
correlationKey + "=" + correlationValue);
|
$".AspNetCore.Correlation.Microsoft.{correlationValue}=N");
|
||||||
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
|
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
|
||||||
Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
|
Assert.Equal("/me", transaction.Response.Headers.GetValues("Location").First());
|
||||||
Assert.Equal(2, transaction.SetCookie.Count);
|
Assert.Equal(2, transaction.SetCookie.Count);
|
||||||
Assert.Contains(correlationKey, transaction.SetCookie[0]);
|
Assert.Contains($".AspNetCore.Correlation.Microsoft.{correlationValue}", transaction.SetCookie[0]);
|
||||||
Assert.Contains(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);
|
Assert.Contains(".AspNetCore." + TestExtensions.CookieAuthenticationScheme, transaction.SetCookie[1]);
|
||||||
|
|
||||||
var authCookie = transaction.AuthenticationCookieValue;
|
var authCookie = transaction.AuthenticationCookieValue;
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,10 @@ namespace Microsoft.AspNetCore.Authentication.Tests.OpenIdConnect
|
||||||
return "null";
|
return "null";
|
||||||
}
|
}
|
||||||
|
|
||||||
var encoder = UrlEncoder.Default;
|
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
foreach(var item in data.Items)
|
foreach(var item in data.Items)
|
||||||
{
|
{
|
||||||
sb.Append(encoder.Encode(item.Key) + " " + encoder.Encode(item.Value) + " ");
|
sb.Append(Uri.EscapeDataString(item.Key) + " " + Uri.EscapeDataString(item.Value) + " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ namespace Microsoft.AspNetCore.Authentication.Tests.OpenIdConnect
|
||||||
Assert.Contains("expires", firstCookie);
|
Assert.Contains("expires", firstCookie);
|
||||||
|
|
||||||
var secondCookie = transaction.SetCookie.Skip(1).First();
|
var secondCookie = transaction.SetCookie.Skip(1).First();
|
||||||
Assert.Contains(OpenIdConnectDefaults.CookieStatePrefix, secondCookie);
|
Assert.StartsWith(".AspNetCore.Correlation.OpenIdConnect.", secondCookie);
|
||||||
Assert.Contains("expires", secondCookie);
|
Assert.Contains("expires", secondCookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue