Replace configure method on Twitter, RemoteAuthentication, and OpenIdConnect options with CookieBuilder
This commit is contained in:
parent
66b939725e
commit
968237d751
|
|
@ -275,8 +275,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
/// <returns>A task executing the callback procedure</returns>
|
||||
protected virtual Task<bool> HandleSignOutCallbackAsync()
|
||||
{
|
||||
StringValues protectedState;
|
||||
if (Request.Query.TryGetValue(OpenIdConnectParameterNames.State, out protectedState))
|
||||
if (Request.Query.TryGetValue(OpenIdConnectParameterNames.State, out StringValues protectedState))
|
||||
{
|
||||
var properties = Options.StateDataFormat.Unprotect(protectedState);
|
||||
if (!string.IsNullOrEmpty(properties?.RedirectUri))
|
||||
|
|
@ -505,8 +504,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
return HandleRequestResult.Fail(Resources.MessageStateIsInvalid);
|
||||
}
|
||||
|
||||
string userstate = null;
|
||||
properties.Items.TryGetValue(OpenIdConnectDefaults.UserstatePropertiesKey, out userstate);
|
||||
properties.Items.TryGetValue(OpenIdConnectDefaults.UserstatePropertiesKey, out string userstate);
|
||||
authorizationResponse.State = userstate;
|
||||
|
||||
if (!ValidateCorrelationId(properties))
|
||||
|
|
@ -859,8 +857,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
|
||||
if (!string.IsNullOrEmpty(message.ExpiresIn))
|
||||
{
|
||||
int value;
|
||||
if (int.TryParse(message.ExpiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out value))
|
||||
if (int.TryParse(message.ExpiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out int value))
|
||||
{
|
||||
var expiresAt = Clock.UtcNow + TimeSpan.FromSeconds(value);
|
||||
// https://www.w3.org/TR/xmlschema-2/#dateTime
|
||||
|
|
@ -885,21 +882,12 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
throw new ArgumentNullException(nameof(nonce));
|
||||
}
|
||||
|
||||
var options = new CookieOptions
|
||||
{
|
||||
HttpOnly = true,
|
||||
SameSite = Http.SameSiteMode.None,
|
||||
Path = OriginalPathBase + Options.CallbackPath,
|
||||
Secure = Request.IsHttps,
|
||||
Expires = Clock.UtcNow.Add(Options.ProtocolValidator.NonceLifetime)
|
||||
};
|
||||
|
||||
Options.ConfigureNonceCookie?.Invoke(Context, options);
|
||||
var cookieOptions = Options.NonceCookie.Build(Context, Clock.UtcNow);
|
||||
|
||||
Response.Cookies.Append(
|
||||
OpenIdConnectDefaults.CookieNoncePrefix + Options.StringDataFormat.Protect(nonce),
|
||||
Options.NonceCookie.Name + Options.StringDataFormat.Protect(nonce),
|
||||
NonceProperty,
|
||||
options);
|
||||
cookieOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -918,23 +906,14 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
|
||||
foreach (var nonceKey in Request.Cookies.Keys)
|
||||
{
|
||||
if (nonceKey.StartsWith(OpenIdConnectDefaults.CookieNoncePrefix))
|
||||
if (nonceKey.StartsWith(Options.NonceCookie.Name))
|
||||
{
|
||||
try
|
||||
{
|
||||
var nonceDecodedValue = Options.StringDataFormat.Unprotect(nonceKey.Substring(OpenIdConnectDefaults.CookieNoncePrefix.Length, nonceKey.Length - OpenIdConnectDefaults.CookieNoncePrefix.Length));
|
||||
var nonceDecodedValue = Options.StringDataFormat.Unprotect(nonceKey.Substring(Options.NonceCookie.Name.Length, nonceKey.Length - Options.NonceCookie.Name.Length));
|
||||
if (nonceDecodedValue == nonce)
|
||||
{
|
||||
var cookieOptions = new CookieOptions
|
||||
{
|
||||
HttpOnly = true,
|
||||
Path = OriginalPathBase + Options.CallbackPath,
|
||||
SameSite = Http.SameSiteMode.None,
|
||||
Secure = Request.IsHttps
|
||||
};
|
||||
|
||||
Options.ConfigureNonceCookie?.Invoke(Context, cookieOptions);
|
||||
|
||||
var cookieOptions = Options.NonceCookie.Build(Context, Clock.UtcNow);
|
||||
Response.Cookies.Delete(nonceKey, cookieOptions);
|
||||
return nonce;
|
||||
}
|
||||
|
|
@ -1170,8 +1149,7 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
validationParameters.IssuerSigningKeys = validationParameters.IssuerSigningKeys?.Concat(_configuration.SigningKeys) ?? _configuration.SigningKeys;
|
||||
}
|
||||
|
||||
SecurityToken validatedToken = null;
|
||||
var principal = Options.SecurityTokenValidator.ValidateToken(idToken, validationParameters, out validatedToken);
|
||||
var principal = Options.SecurityTokenValidator.ValidateToken(idToken, validationParameters, out SecurityToken validatedToken);
|
||||
jwt = validatedToken as JwtSecurityToken;
|
||||
if (jwt == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using Microsoft.AspNetCore.Authentication.Internal;
|
||||
using Microsoft.AspNetCore.Authentication.OAuth.Claims;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.IdentityModel.Protocols;
|
||||
|
|
@ -17,6 +18,8 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
/// </summary>
|
||||
public class OpenIdConnectOptions : RemoteAuthenticationOptions
|
||||
{
|
||||
private CookieBuilder _nonceCookieBuilder;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="OpenIdConnectOptions"/>
|
||||
/// </summary>
|
||||
|
|
@ -65,6 +68,14 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
ClaimActions.MapUniqueJsonKey("family_name", "family_name");
|
||||
ClaimActions.MapUniqueJsonKey("profile", "profile");
|
||||
ClaimActions.MapUniqueJsonKey("email", "email");
|
||||
|
||||
_nonceCookieBuilder = new OpenIdConnectNonceCookieBuilder(this)
|
||||
{
|
||||
Name = OpenIdConnectDefaults.CookieNoncePrefix,
|
||||
HttpOnly = true,
|
||||
SameSite = SameSiteMode.None,
|
||||
SecurePolicy = CookieSecurePolicy.SameAsRequest,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -145,8 +156,8 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
/// </summary>
|
||||
public new OpenIdConnectEvents Events
|
||||
{
|
||||
get { return (OpenIdConnectEvents)base.Events; }
|
||||
set { base.Events = value; }
|
||||
get => (OpenIdConnectEvents)base.Events;
|
||||
set => base.Events = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -259,9 +270,40 @@ namespace Microsoft.AspNetCore.Authentication.OpenIdConnect
|
|||
public bool DisableTelemetry { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an action that can override the nonce cookie options before the
|
||||
/// Determines the settings used to create the nonce cookie before the
|
||||
/// cookie gets added to the response.
|
||||
/// </summary>
|
||||
public Action<HttpContext, CookieOptions> ConfigureNonceCookie { get; set; }
|
||||
/// <remarks>
|
||||
/// The value of <see cref="CookieBuilder.Name"/> is treated as the prefix to the cookie name, and defaults to <seealso cref="OpenIdConnectDefaults.CookieNoncePrefix"/>.
|
||||
/// </remarks>
|
||||
public CookieBuilder NonceCookie
|
||||
{
|
||||
get => _nonceCookieBuilder;
|
||||
set => _nonceCookieBuilder = value ?? throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
|
||||
private class OpenIdConnectNonceCookieBuilder : RequestPathBaseCookieBuilder
|
||||
{
|
||||
private readonly OpenIdConnectOptions _options;
|
||||
|
||||
public OpenIdConnectNonceCookieBuilder(OpenIdConnectOptions oidcOptions)
|
||||
{
|
||||
_options = oidcOptions;
|
||||
}
|
||||
|
||||
protected override string AdditionalPath => _options.CallbackPath;
|
||||
|
||||
public override CookieOptions Build(HttpContext context, DateTimeOffset expiresFrom)
|
||||
{
|
||||
var cookieOptions = base.Build(context, expiresFrom);
|
||||
|
||||
if (!Expiration.HasValue || !cookieOptions.Expires.HasValue)
|
||||
{
|
||||
cookieOptions.Expires = expiresFrom.Add(_options.ProtocolValidator.NonceLifetime);
|
||||
}
|
||||
|
||||
return cookieOptions;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ using System.Security.Cryptography;
|
|||
using System.Text;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
|
@ -23,7 +22,6 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
internal class TwitterHandler : RemoteAuthenticationHandler<TwitterOptions>
|
||||
{
|
||||
private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
private const string StateCookie = "__TwitterState";
|
||||
private const string RequestTokenEndpoint = "https://api.twitter.com/oauth/request_token";
|
||||
private const string AuthenticationEndpoint = "https://api.twitter.com/oauth/authenticate?oauth_token=";
|
||||
private const string AccessTokenEndpoint = "https://api.twitter.com/oauth/access_token";
|
||||
|
|
@ -50,7 +48,7 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
{
|
||||
AuthenticationProperties properties = null;
|
||||
var query = Request.Query;
|
||||
var protectedRequestToken = Request.Cookies[StateCookie];
|
||||
var protectedRequestToken = Request.Cookies[Options.StateCookie.Name];
|
||||
|
||||
var requestToken = Options.StateDataFormat.Unprotect(protectedRequestToken);
|
||||
|
||||
|
|
@ -80,16 +78,9 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
return HandleRequestResult.Fail("Missing or blank oauth_verifier");
|
||||
}
|
||||
|
||||
var cookieOptions = new CookieOptions
|
||||
{
|
||||
HttpOnly = true,
|
||||
SameSite = SameSiteMode.Lax,
|
||||
Secure = Request.IsHttps
|
||||
};
|
||||
var cookieOptions = Options.StateCookie.Build(Context, Clock.UtcNow);
|
||||
|
||||
Options.ConfigureStateCookie?.Invoke(Context, cookieOptions);
|
||||
|
||||
Response.Cookies.Delete(StateCookie, cookieOptions);
|
||||
Response.Cookies.Delete(Options.StateCookie.Name, cookieOptions);
|
||||
|
||||
var accessToken = await ObtainAccessTokenAsync(requestToken, oauthVerifier);
|
||||
|
||||
|
|
@ -144,17 +135,9 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
var requestToken = await ObtainRequestTokenAsync(BuildRedirectUri(Options.CallbackPath), properties);
|
||||
var twitterAuthenticationEndpoint = AuthenticationEndpoint + requestToken.Token;
|
||||
|
||||
var cookieOptions = new CookieOptions
|
||||
{
|
||||
HttpOnly = true,
|
||||
SameSite = SameSiteMode.Lax,
|
||||
Secure = Request.IsHttps,
|
||||
Expires = Clock.UtcNow.Add(Options.RemoteAuthenticationTimeout),
|
||||
};
|
||||
var cookieOptions = Options.StateCookie.Build(Context, Clock.UtcNow);
|
||||
|
||||
Options.ConfigureStateCookie?.Invoke(Context, cookieOptions);
|
||||
|
||||
Response.Cookies.Append(StateCookie, Options.StateDataFormat.Protect(requestToken), cookieOptions);
|
||||
Response.Cookies.Append(Options.StateCookie.Name, Options.StateDataFormat.Protect(requestToken), cookieOptions);
|
||||
|
||||
var redirectContext = new RedirectContext<TwitterOptions>(Context, Scheme, Options, properties, twitterAuthenticationEndpoint);
|
||||
await Events.RedirectToAuthorizationEndpoint(redirectContext);
|
||||
|
|
|
|||
|
|
@ -3,10 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.OAuth.Claims;
|
||||
using Microsoft.AspNetCore.Authentication.Twitter;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.Twitter
|
||||
|
|
@ -16,6 +13,10 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
/// </summary>
|
||||
public class TwitterOptions : RemoteAuthenticationOptions
|
||||
{
|
||||
private const string DefaultStateCookieName = "__TwitterState";
|
||||
|
||||
private CookieBuilder _stateCookieBuilder;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TwitterOptions"/> class.
|
||||
/// </summary>
|
||||
|
|
@ -26,6 +27,14 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
Events = new TwitterEvents();
|
||||
|
||||
ClaimActions.MapJsonKey(ClaimTypes.Email, "email", ClaimValueTypes.Email);
|
||||
|
||||
_stateCookieBuilder = new TwitterCookieBuilder(this)
|
||||
{
|
||||
Name = DefaultStateCookieName,
|
||||
SecurePolicy = CookieSecurePolicy.SameAsRequest,
|
||||
HttpOnly = true,
|
||||
SameSite = SameSiteMode.Lax,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -58,19 +67,43 @@ namespace Microsoft.AspNetCore.Authentication.Twitter
|
|||
/// </summary>
|
||||
public ISecureDataFormat<RequestToken> StateDataFormat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an action that can override the state cookie options before the
|
||||
/// cookie gets added to the response.
|
||||
/// </summary>
|
||||
public Action<HttpContext, CookieOptions> ConfigureStateCookie { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="TwitterEvents"/> used to handle authentication events.
|
||||
/// </summary>
|
||||
public new TwitterEvents Events
|
||||
{
|
||||
get { return (TwitterEvents)base.Events; }
|
||||
set { base.Events = value; }
|
||||
get => (TwitterEvents)base.Events;
|
||||
set => base.Events = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the settings used to create the state cookie before the
|
||||
/// cookie gets added to the response.
|
||||
/// </summary>
|
||||
public CookieBuilder StateCookie
|
||||
{
|
||||
get => _stateCookieBuilder;
|
||||
set => _stateCookieBuilder = value ?? throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
|
||||
private class TwitterCookieBuilder : CookieBuilder
|
||||
{
|
||||
private readonly TwitterOptions _twitterOptions;
|
||||
|
||||
public TwitterCookieBuilder(TwitterOptions twitterOptions)
|
||||
{
|
||||
_twitterOptions = twitterOptions;
|
||||
}
|
||||
|
||||
public override CookieOptions Build(HttpContext context, DateTimeOffset expiresFrom)
|
||||
{
|
||||
var options = base.Build(context, expiresFrom);
|
||||
if (!Expiration.HasValue)
|
||||
{
|
||||
options.Expires = expiresFrom.Add(_twitterOptions.RemoteAuthenticationTimeout);
|
||||
}
|
||||
return options;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
// 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.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Authentication.Internal
|
||||
{
|
||||
/// <summary>
|
||||
/// A cookie builder that sets <see cref="CookieOptions.Path"/> to the request path base.
|
||||
/// </summary>
|
||||
public class RequestPathBaseCookieBuilder : CookieBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets an optional value that is appended to the request path base.
|
||||
/// </summary>
|
||||
protected virtual string AdditionalPath { get; }
|
||||
|
||||
public override CookieOptions Build(HttpContext context, DateTimeOffset expiresFrom)
|
||||
{
|
||||
// check if the user has overridden the default value of path. If so, use that instead of our default value.
|
||||
var path = Path;
|
||||
if (path == null)
|
||||
{
|
||||
var originalPathBase = context.Features.Get<IAuthenticationFeature>()?.OriginalPathBase ?? context.Request.PathBase;
|
||||
path = originalPathBase + AdditionalPath;
|
||||
}
|
||||
|
||||
var options = base.Build(context, expiresFrom);
|
||||
|
||||
options.Path = !string.IsNullOrEmpty(path)
|
||||
? path
|
||||
: "/";
|
||||
|
||||
return options;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,6 @@ using System;
|
|||
using System.Security.Cryptography;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
|
|
@ -14,7 +13,6 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
public abstract class RemoteAuthenticationHandler<TOptions> : AuthenticationHandler<TOptions>, IAuthenticationRequestHandler
|
||||
where TOptions : RemoteAuthenticationOptions, new()
|
||||
{
|
||||
private const string CorrelationPrefix = ".AspNetCore.Correlation.";
|
||||
private const string CorrelationProperty = ".xsrf";
|
||||
private const string CorrelationMarker = "N";
|
||||
private const string AuthSchemeKey = ".AuthScheme";
|
||||
|
|
@ -187,20 +185,11 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
CryptoRandom.GetBytes(bytes);
|
||||
var correlationId = Base64UrlTextEncoder.Encode(bytes);
|
||||
|
||||
var cookieOptions = new CookieOptions
|
||||
{
|
||||
HttpOnly = true,
|
||||
SameSite = SameSiteMode.None,
|
||||
Secure = Request.IsHttps,
|
||||
Path = OriginalPathBase + Options.CallbackPath,
|
||||
Expires = Clock.UtcNow.Add(Options.RemoteAuthenticationTimeout),
|
||||
};
|
||||
|
||||
Options.ConfigureCorrelationIdCookie?.Invoke(Context, cookieOptions);
|
||||
var cookieOptions = Options.CorrelationCookie.Build(Context, Clock.UtcNow);
|
||||
|
||||
properties.Items[CorrelationProperty] = correlationId;
|
||||
|
||||
var cookieName = CorrelationPrefix + Scheme.Name + "." + correlationId;
|
||||
var cookieName = Options.CorrelationCookie.Name + Scheme.Name + "." + correlationId;
|
||||
|
||||
Response.Cookies.Append(cookieName, CorrelationMarker, cookieOptions);
|
||||
}
|
||||
|
|
@ -212,16 +201,15 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
throw new ArgumentNullException(nameof(properties));
|
||||
}
|
||||
|
||||
string correlationId;
|
||||
if (!properties.Items.TryGetValue(CorrelationProperty, out correlationId))
|
||||
if (!properties.Items.TryGetValue(CorrelationProperty, out string correlationId))
|
||||
{
|
||||
Logger.CorrelationPropertyNotFound(CorrelationPrefix);
|
||||
Logger.CorrelationPropertyNotFound(Options.CorrelationCookie.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
properties.Items.Remove(CorrelationProperty);
|
||||
|
||||
var cookieName = CorrelationPrefix + Scheme.Name + "." + correlationId;
|
||||
var cookieName = Options.CorrelationCookie.Name + Scheme.Name + "." + correlationId;
|
||||
|
||||
var correlationCookie = Request.Cookies[cookieName];
|
||||
if (string.IsNullOrEmpty(correlationCookie))
|
||||
|
|
@ -230,15 +218,7 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
return false;
|
||||
}
|
||||
|
||||
var cookieOptions = new CookieOptions
|
||||
{
|
||||
HttpOnly = true,
|
||||
Path = OriginalPathBase + Options.CallbackPath,
|
||||
SameSite = SameSiteMode.None,
|
||||
Secure = Request.IsHttps
|
||||
};
|
||||
|
||||
Options.ConfigureCorrelationIdCookie?.Invoke(Context, cookieOptions);
|
||||
var cookieOptions = Options.CorrelationCookie.Build(Context, Clock.UtcNow);
|
||||
|
||||
Response.Cookies.Delete(cookieName, cookieOptions);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Authentication.Internal;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
|
|
@ -13,6 +14,24 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
/// </summary>
|
||||
public class RemoteAuthenticationOptions : AuthenticationSchemeOptions
|
||||
{
|
||||
private const string CorrelationPrefix = ".AspNetCore.Correlation.";
|
||||
|
||||
private CookieBuilder _correlationCookieBuilder;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="RemoteAuthenticationOptions"/>.
|
||||
/// </summary>
|
||||
public RemoteAuthenticationOptions()
|
||||
{
|
||||
_correlationCookieBuilder = new CorrelationCookieBuilder(this)
|
||||
{
|
||||
Name = CorrelationPrefix,
|
||||
HttpOnly = true,
|
||||
SameSite = SameSiteMode.None,
|
||||
SecurePolicy = CookieSecurePolicy.SameAsRequest,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check that the options are valid. Should throw an exception if things are not ok.
|
||||
/// </summary>
|
||||
|
|
@ -71,8 +90,8 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
|
||||
public new RemoteAuthenticationEvents Events
|
||||
{
|
||||
get { return (RemoteAuthenticationEvents)base.Events; }
|
||||
set { base.Events = value; }
|
||||
get => (RemoteAuthenticationEvents)base.Events;
|
||||
set => base.Events = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -84,9 +103,37 @@ namespace Microsoft.AspNetCore.Authentication
|
|||
public bool SaveTokens { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an action that can override the correlation id cookie options before the
|
||||
/// Determines the settings used to create the correlation cookie before the
|
||||
/// cookie gets added to the response.
|
||||
/// </summary>
|
||||
public Action<HttpContext, CookieOptions> ConfigureCorrelationIdCookie { get; set; }
|
||||
public CookieBuilder CorrelationCookie
|
||||
{
|
||||
get => _correlationCookieBuilder;
|
||||
set => _correlationCookieBuilder = value ?? throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
|
||||
private class CorrelationCookieBuilder : RequestPathBaseCookieBuilder
|
||||
{
|
||||
private readonly RemoteAuthenticationOptions _options;
|
||||
|
||||
public CorrelationCookieBuilder(RemoteAuthenticationOptions remoteAuthenticationOptions)
|
||||
{
|
||||
_options = remoteAuthenticationOptions;
|
||||
}
|
||||
|
||||
protected override string AdditionalPath => _options.CallbackPath;
|
||||
|
||||
public override CookieOptions Build(HttpContext context, DateTimeOffset expiresFrom)
|
||||
{
|
||||
var cookieOptions = base.Build(context, expiresFrom);
|
||||
|
||||
if (!Expiration.HasValue || !cookieOptions.Expires.HasValue)
|
||||
{
|
||||
cookieOptions.Expires = expiresFrom.Add(_options.RemoteAuthenticationTimeout);
|
||||
}
|
||||
|
||||
return cookieOptions;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ namespace Microsoft.AspNetCore.Authentication.OAuth
|
|||
opt.AuthorizationEndpoint = "https://example.com/provider/login";
|
||||
opt.TokenEndpoint = "https://example.com/provider/token";
|
||||
opt.CallbackPath = "/oauth-callback";
|
||||
opt.ConfigureCorrelationIdCookie = (ctx, options) => options.Path = "/";
|
||||
opt.CorrelationCookie.Path = "/";
|
||||
}),
|
||||
ctx =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
{
|
||||
AuthorizationEndpoint = "https://example.com/provider/login"
|
||||
};
|
||||
opt.ConfigureNonceCookie = (ctx, options) => options.Path = "/";
|
||||
opt.NonceCookie.Path = "/";
|
||||
});
|
||||
|
||||
var server = setting.CreateTestServer();
|
||||
|
|
@ -143,7 +143,7 @@ namespace Microsoft.AspNetCore.Authentication.Test.OpenIdConnect
|
|||
{
|
||||
AuthorizationEndpoint = "https://example.com/provider/login"
|
||||
};
|
||||
opt.ConfigureCorrelationIdCookie = (ctx, options) => options.Path = "/";
|
||||
opt.CorrelationCookie.Path = "/";
|
||||
});
|
||||
|
||||
var server = setting.CreateTestServer();
|
||||
|
|
|
|||
Loading…
Reference in New Issue