Expose AuthenticationProperties in events

This commit is contained in:
Hao Kung 2016-01-05 14:32:31 -08:00
parent f195ed3bab
commit 3257a82367
19 changed files with 138 additions and 67 deletions

View File

@ -186,7 +186,7 @@ namespace Microsoft.AspNet.Authentication.Cookies
cookieValue, cookieValue,
cookieOptions); cookieOptions);
await ApplyHeaders(shouldRedirectToReturnUrl: false); await ApplyHeaders(shouldRedirectToReturnUrl: false, properties: ticket.Properties);
} }
} }
@ -261,7 +261,7 @@ namespace Microsoft.AspNet.Authentication.Cookies
// Only redirect on the login path // Only redirect on the login path
var shouldRedirect = Options.LoginPath.HasValue && OriginalPath == Options.LoginPath; var shouldRedirect = Options.LoginPath.HasValue && OriginalPath == Options.LoginPath;
await ApplyHeaders(shouldRedirect); await ApplyHeaders(shouldRedirect, signedInContext.Properties);
} }
protected override async Task HandleSignOutAsync(SignOutContext signOutContext) protected override async Task HandleSignOutAsync(SignOutContext signOutContext)
@ -277,6 +277,7 @@ namespace Microsoft.AspNet.Authentication.Cookies
var context = new CookieSigningOutContext( var context = new CookieSigningOutContext(
Context, Context,
Options, Options,
new AuthenticationProperties(signOutContext.Properties),
cookieOptions); cookieOptions);
await Options.Events.SigningOut(context); await Options.Events.SigningOut(context);
@ -288,10 +289,10 @@ namespace Microsoft.AspNet.Authentication.Cookies
// Only redirect on the logout path // Only redirect on the logout path
var shouldRedirect = Options.LogoutPath.HasValue && OriginalPath == Options.LogoutPath; var shouldRedirect = Options.LogoutPath.HasValue && OriginalPath == Options.LogoutPath;
await ApplyHeaders(shouldRedirect); await ApplyHeaders(shouldRedirect, context.Properties);
} }
private async Task ApplyHeaders(bool shouldRedirectToReturnUrl) private async Task ApplyHeaders(bool shouldRedirectToReturnUrl, AuthenticationProperties properties)
{ {
Response.Headers[HeaderNames.CacheControl] = HeaderValueNoCache; Response.Headers[HeaderNames.CacheControl] = HeaderValueNoCache;
Response.Headers[HeaderNames.Pragma] = HeaderValueNoCache; Response.Headers[HeaderNames.Pragma] = HeaderValueNoCache;
@ -303,7 +304,7 @@ namespace Microsoft.AspNet.Authentication.Cookies
if (!StringValues.IsNullOrEmpty(redirectUri) if (!StringValues.IsNullOrEmpty(redirectUri)
&& IsHostRelative(redirectUri)) && IsHostRelative(redirectUri))
{ {
var redirectContext = new CookieRedirectContext(Context, Options, redirectUri); var redirectContext = new CookieRedirectContext(Context, Options, redirectUri, properties);
await Options.Events.RedirectToReturnUrl(redirectContext); await Options.Events.RedirectToReturnUrl(redirectContext);
} }
} }
@ -325,13 +326,14 @@ namespace Microsoft.AspNet.Authentication.Cookies
protected override async Task<bool> HandleForbiddenAsync(ChallengeContext context) protected override async Task<bool> HandleForbiddenAsync(ChallengeContext context)
{ {
var returnUrl = new AuthenticationProperties(context.Properties).RedirectUri; var properties = new AuthenticationProperties(context.Properties);
var returnUrl = properties.RedirectUri;
if (string.IsNullOrEmpty(returnUrl)) if (string.IsNullOrEmpty(returnUrl))
{ {
returnUrl = OriginalPathBase + Request.Path + Request.QueryString; returnUrl = OriginalPathBase + Request.Path + Request.QueryString;
} }
var accessDeniedUri = Options.AccessDeniedPath + QueryString.Create(Options.ReturnUrlParameter, returnUrl); var accessDeniedUri = Options.AccessDeniedPath + QueryString.Create(Options.ReturnUrlParameter, returnUrl);
var redirectContext = new CookieRedirectContext(Context, Options, BuildRedirectUri(accessDeniedUri)); var redirectContext = new CookieRedirectContext(Context, Options, BuildRedirectUri(accessDeniedUri), properties);
await Options.Events.RedirectToAccessDenied(redirectContext); await Options.Events.RedirectToAccessDenied(redirectContext);
return true; return true;
} }
@ -343,14 +345,15 @@ namespace Microsoft.AspNet.Authentication.Cookies
throw new ArgumentNullException(nameof(context)); throw new ArgumentNullException(nameof(context));
} }
var redirectUri = new AuthenticationProperties(context.Properties).RedirectUri; var properties = new AuthenticationProperties(context.Properties);
var redirectUri = properties.RedirectUri;
if (string.IsNullOrEmpty(redirectUri)) if (string.IsNullOrEmpty(redirectUri))
{ {
redirectUri = OriginalPathBase + Request.Path + Request.QueryString; redirectUri = OriginalPathBase + Request.Path + Request.QueryString;
} }
var loginUri = Options.LoginPath + QueryString.Create(Options.ReturnUrlParameter, redirectUri); var loginUri = Options.LoginPath + QueryString.Create(Options.ReturnUrlParameter, redirectUri);
var redirectContext = new CookieRedirectContext(Context, Options, BuildRedirectUri(loginUri)); var redirectContext = new CookieRedirectContext(Context, Options, BuildRedirectUri(loginUri), properties);
await Options.Events.RedirectToLogin(redirectContext); await Options.Events.RedirectToLogin(redirectContext);
return true; return true;

View File

@ -3,6 +3,7 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Authentication;
namespace Microsoft.AspNet.Authentication.Cookies namespace Microsoft.AspNet.Authentication.Cookies
{ {
@ -18,10 +19,11 @@ namespace Microsoft.AspNet.Authentication.Cookies
/// <param name="options">The cookie middleware options</param> /// <param name="options">The cookie middleware options</param>
/// <param name="redirectUri">The initial redirect URI</param> /// <param name="redirectUri">The initial redirect URI</param>
[SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "Represents header value")] [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "Represents header value")]
public CookieRedirectContext(HttpContext context, CookieAuthenticationOptions options, string redirectUri) public CookieRedirectContext(HttpContext context, CookieAuthenticationOptions options, string redirectUri, AuthenticationProperties properties)
: base(context, options) : base(context, options)
{ {
RedirectUri = redirectUri; RedirectUri = redirectUri;
Properties = properties;
} }
/// <summary> /// <summary>
@ -29,5 +31,7 @@ namespace Microsoft.AspNet.Authentication.Cookies
/// </summary> /// </summary>
[SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Represents header value")] [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Represents header value")]
public string RedirectUri { get; set; } public string RedirectUri { get; set; }
public AuthenticationProperties Properties { get; }
} }
} }

View File

@ -36,16 +36,16 @@ namespace Microsoft.AspNet.Authentication.Cookies
/// <summary> /// <summary>
/// The name of the AuthenticationScheme creating a cookie /// The name of the AuthenticationScheme creating a cookie
/// </summary> /// </summary>
public string AuthenticationScheme { get; private set; } public string AuthenticationScheme { get; }
/// <summary> /// <summary>
/// Contains the claims that were converted into the outgoing cookie. /// Contains the claims that were converted into the outgoing cookie.
/// </summary> /// </summary>
public ClaimsPrincipal Principal { get; private set; } public ClaimsPrincipal Principal { get; }
/// <summary> /// <summary>
/// Contains the extra data that was contained in the outgoing cookie. /// Contains the extra data that was contained in the outgoing cookie.
/// </summary> /// </summary>
public AuthenticationProperties Properties { get; private set; } public AuthenticationProperties Properties { get; }
} }
} }

View File

@ -39,7 +39,7 @@ namespace Microsoft.AspNet.Authentication.Cookies
/// <summary> /// <summary>
/// The name of the AuthenticationScheme creating a cookie /// The name of the AuthenticationScheme creating a cookie
/// </summary> /// </summary>
public string AuthenticationScheme { get; private set; } public string AuthenticationScheme { get; }
/// <summary> /// <summary>
/// Contains the claims about to be converted into the outgoing cookie. /// Contains the claims about to be converted into the outgoing cookie.

View File

@ -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 Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Authentication;
namespace Microsoft.AspNet.Authentication.Cookies namespace Microsoft.AspNet.Authentication.Cookies
{ {
@ -16,20 +17,23 @@ namespace Microsoft.AspNet.Authentication.Cookies
/// <param name="context"></param> /// <param name="context"></param>
/// <param name="options"></param> /// <param name="options"></param>
/// <param name="cookieOptions"></param> /// <param name="cookieOptions"></param>
public CookieSigningOutContext(HttpContext context, CookieAuthenticationOptions options, CookieOptions cookieOptions) public CookieSigningOutContext(
HttpContext context,
CookieAuthenticationOptions options,
AuthenticationProperties properties,
CookieOptions cookieOptions)
: base(context, options) : base(context, options)
{ {
CookieOptions = cookieOptions; CookieOptions = cookieOptions;
Properties = properties;
} }
/// <summary> /// <summary>
/// The options for creating the outgoing cookie. /// The options for creating the outgoing cookie.
/// May be replace or altered during the SigningOut call. /// May be replace or altered during the SigningOut call.
/// </summary> /// </summary>
public CookieOptions CookieOptions public CookieOptions CookieOptions { get; set; }
{
get; public AuthenticationProperties Properties { get; set; }
set;
}
} }
} }

View File

@ -37,12 +37,8 @@ namespace Microsoft.AspNet.Authentication.Facebook
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
var context = new OAuthCreatingTicketContext(Context, Options, Backchannel, tokens, payload) var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Options, Backchannel, tokens, payload);
{
Properties = properties,
Principal = new ClaimsPrincipal(identity)
};
var identifier = FacebookHelper.GetId(payload); var identifier = FacebookHelper.GetId(payload);
if (!string.IsNullOrEmpty(identifier)) if (!string.IsNullOrEmpty(identifier))

View File

@ -31,12 +31,8 @@ namespace Microsoft.AspNet.Authentication.Google
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
var context = new OAuthCreatingTicketContext(Context, Options, Backchannel, tokens, payload) var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Options, Backchannel, tokens, payload);
{
Properties = properties,
Principal = new ClaimsPrincipal(identity)
};
var identifier = GoogleHelper.GetId(payload); var identifier = GoogleHelper.GetId(payload);
if (!string.IsNullOrEmpty(identifier)) if (!string.IsNullOrEmpty(identifier))

View File

@ -2,14 +2,18 @@
// 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 Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Authentication;
namespace Microsoft.AspNet.Authentication.JwtBearer namespace Microsoft.AspNet.Authentication.JwtBearer
{ {
public class JwtBearerChallengeContext : BaseJwtBearerContext public class JwtBearerChallengeContext : BaseJwtBearerContext
{ {
public JwtBearerChallengeContext(HttpContext context, JwtBearerOptions options) public JwtBearerChallengeContext(HttpContext context, JwtBearerOptions options, AuthenticationProperties properties)
: base(context, options) : base(context, options)
{ {
Properties = properties;
} }
public AuthenticationProperties Properties { get; }
} }
} }

View File

@ -203,7 +203,7 @@ namespace Microsoft.AspNet.Authentication.JwtBearer
protected override async Task<bool> HandleUnauthorizedAsync(ChallengeContext context) protected override async Task<bool> HandleUnauthorizedAsync(ChallengeContext context)
{ {
var eventContext = new JwtBearerChallengeContext(Context, Options); var eventContext = new JwtBearerChallengeContext(Context, Options, new AuthenticationProperties(context.Properties));
await Options.Events.Challenge(eventContext); await Options.Events.Challenge(eventContext);
if (eventContext.HandledResponse) if (eventContext.HandledResponse)
{ {

View File

@ -27,13 +27,8 @@ namespace Microsoft.AspNet.Authentication.MicrosoftAccount
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
var context = new OAuthCreatingTicketContext(Context, Options, Backchannel, tokens, payload)
{
Properties = properties,
Principal = new ClaimsPrincipal(identity)
};
var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Options, Backchannel, tokens, payload);
var identifier = MicrosoftAccountHelper.GetId(payload); var identifier = MicrosoftAccountHelper.GetId(payload);
if (!string.IsNullOrEmpty(identifier)) if (!string.IsNullOrEmpty(identifier))
{ {

View File

@ -19,28 +19,36 @@ namespace Microsoft.AspNet.Authentication.OAuth
/// <summary> /// <summary>
/// Initializes a new <see cref="OAuthCreatingTicketContext"/>. /// Initializes a new <see cref="OAuthCreatingTicketContext"/>.
/// </summary> /// </summary>
/// <param name="principal">The <see cref="ClaimsPrincipal"/> representing the user.</param>
/// <param name="properties">Property bag for common authentication properties.</param>
/// <param name="context">The HTTP environment.</param> /// <param name="context">The HTTP environment.</param>
/// <param name="options">The options used by the authentication middleware.</param> /// <param name="options">The options used by the authentication middleware.</param>
/// <param name="backchannel">The HTTP client used by the authentication middleware</param> /// <param name="backchannel">The HTTP client used by the authentication middleware</param>
/// <param name="tokens">The tokens returned from the token endpoint.</param> /// <param name="tokens">The tokens returned from the token endpoint.</param>
public OAuthCreatingTicketContext( public OAuthCreatingTicketContext(
ClaimsPrincipal principal,
AuthenticationProperties properties,
HttpContext context, HttpContext context,
OAuthOptions options, OAuthOptions options,
HttpClient backchannel, HttpClient backchannel,
OAuthTokenResponse tokens) OAuthTokenResponse tokens)
: this(context, options, backchannel, tokens, user: new JObject()) : this(principal, properties, context, options, backchannel, tokens, user: new JObject())
{ {
} }
/// <summary> /// <summary>
/// Initializes a new <see cref="OAuthCreatingTicketContext"/>. /// Initializes a new <see cref="OAuthCreatingTicketContext"/>.
/// </summary> /// </summary>
/// <param name="principal">The <see cref="ClaimsPrincipal"/> representing the user.</param>
/// <param name="properties">Property bag for common authentication properties.</param>
/// <param name="context">The HTTP environment.</param> /// <param name="context">The HTTP environment.</param>
/// <param name="options">The options used by the authentication middleware.</param> /// <param name="options">The options used by the authentication middleware.</param>
/// <param name="backchannel">The HTTP client used by the authentication middleware</param> /// <param name="backchannel">The HTTP client used by the authentication middleware</param>
/// <param name="tokens">The tokens returned from the token endpoint.</param> /// <param name="tokens">The tokens returned from the token endpoint.</param>
/// <param name="user">The JSON-serialized user.</param> /// <param name="user">The JSON-serialized user.</param>
public OAuthCreatingTicketContext( public OAuthCreatingTicketContext(
ClaimsPrincipal principal,
AuthenticationProperties properties,
HttpContext context, HttpContext context,
OAuthOptions options, OAuthOptions options,
HttpClient backchannel, HttpClient backchannel,
@ -77,6 +85,8 @@ namespace Microsoft.AspNet.Authentication.OAuth
Backchannel = backchannel; Backchannel = backchannel;
User = user; User = user;
Options = options; Options = options;
Principal = principal;
Properties = properties;
} }
public OAuthOptions Options { get; } public OAuthOptions Options { get; }

View File

@ -155,11 +155,7 @@ namespace Microsoft.AspNet.Authentication.OAuth
protected virtual async Task<AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens) protected virtual async Task<AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
{ {
var context = new OAuthCreatingTicketContext(Context, Options, Backchannel, tokens) var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Options, Backchannel, tokens);
{
Principal = new ClaimsPrincipal(identity),
Properties = properties
};
await Options.Events.CreatingTicket(context); await Options.Events.CreatingTicket(context);

View File

@ -2,17 +2,21 @@
// 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 Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Authentication;
using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Microsoft.IdentityModel.Protocols.OpenIdConnect;
namespace Microsoft.AspNet.Authentication.OpenIdConnect namespace Microsoft.AspNet.Authentication.OpenIdConnect
{ {
public class AuthenticationValidatedContext : BaseOpenIdConnectContext public class AuthenticationValidatedContext : BaseOpenIdConnectContext
{ {
public AuthenticationValidatedContext(HttpContext context, OpenIdConnectOptions options) public AuthenticationValidatedContext(HttpContext context, OpenIdConnectOptions options, AuthenticationProperties properties)
: base(context, options) : base(context, options)
{ {
Properties = properties;
} }
public AuthenticationProperties Properties { get; }
public OpenIdConnectMessage TokenEndpointResponse { get; set; } public OpenIdConnectMessage TokenEndpointResponse { get; set; }
} }
} }

View File

@ -4,7 +4,7 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
using Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Microsoft.AspNet.Http.Authentication;
namespace Microsoft.AspNet.Authentication.OpenIdConnect namespace Microsoft.AspNet.Authentication.OpenIdConnect
{ {
@ -16,11 +16,14 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
/// <summary> /// <summary>
/// Creates a <see cref="AuthorizationCodeReceivedContext"/> /// Creates a <see cref="AuthorizationCodeReceivedContext"/>
/// </summary> /// </summary>
public AuthorizationCodeReceivedContext(HttpContext context, OpenIdConnectOptions options) public AuthorizationCodeReceivedContext(HttpContext context, OpenIdConnectOptions options, AuthenticationProperties properties)
: base(context, options) : base(context, options)
{ {
Properties = properties;
} }
public AuthenticationProperties Properties { get; set; }
/// <summary> /// <summary>
/// Gets or sets the 'code'. /// Gets or sets the 'code'.
/// </summary> /// </summary>

View File

@ -9,11 +9,12 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
{ {
public class AuthorizationResponseReceivedContext : BaseOpenIdConnectContext public class AuthorizationResponseReceivedContext : BaseOpenIdConnectContext
{ {
public AuthorizationResponseReceivedContext(HttpContext context, OpenIdConnectOptions options) public AuthorizationResponseReceivedContext(HttpContext context, OpenIdConnectOptions options, AuthenticationProperties properties)
: base(context, options) : base(context, options)
{ {
Properties = properties;
} }
public AuthenticationProperties Properties { get; set; } public AuthenticationProperties Properties { get; }
} }
} }

View File

@ -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 Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Authentication;
using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Microsoft.IdentityModel.Protocols.OpenIdConnect;
namespace Microsoft.AspNet.Authentication.OpenIdConnect namespace Microsoft.AspNet.Authentication.OpenIdConnect
@ -12,9 +13,12 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
/// </summary> /// </summary>
public class RedirectContext : BaseOpenIdConnectContext public class RedirectContext : BaseOpenIdConnectContext
{ {
public RedirectContext(HttpContext context, OpenIdConnectOptions options) public RedirectContext(HttpContext context, OpenIdConnectOptions options, AuthenticationProperties properties)
: base(context, options) : base(context, options)
{ {
Properties = properties;
} }
public AuthenticationProperties Properties { get; }
} }
} }

View File

@ -1,4 +1,5 @@
using Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Authentication;
using Microsoft.IdentityModel.Protocols.OpenIdConnect; using Microsoft.IdentityModel.Protocols.OpenIdConnect;
namespace Microsoft.AspNet.Authentication.OpenIdConnect namespace Microsoft.AspNet.Authentication.OpenIdConnect
@ -11,11 +12,14 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
/// <summary> /// <summary>
/// Creates a <see cref="TokenResponseReceivedContext"/> /// Creates a <see cref="TokenResponseReceivedContext"/>
/// </summary> /// </summary>
public TokenResponseReceivedContext(HttpContext context, OpenIdConnectOptions options) public TokenResponseReceivedContext(HttpContext context, OpenIdConnectOptions options, AuthenticationProperties properties)
: base(context, options) : base(context, options)
{ {
Properties = properties;
} }
public AuthenticationProperties Properties { get; }
/// <summary> /// <summary>
/// Gets or sets the <see cref="OpenIdConnectMessage"/> that contains the tokens received after redeeming the code at the token endpoint. /// Gets or sets the <see cref="OpenIdConnectMessage"/> that contains the tokens received after redeeming the code at the token endpoint.
/// </summary> /// </summary>

View File

@ -99,7 +99,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
message.IdTokenHint = principal?.FindFirst(OpenIdConnectParameterNames.IdToken)?.Value; message.IdTokenHint = principal?.FindFirst(OpenIdConnectParameterNames.IdToken)?.Value;
} }
var redirectContext = new RedirectContext(Context, Options) var redirectContext = new RedirectContext(Context, Options, properties)
{ {
ProtocolMessage = message ProtocolMessage = message
}; };
@ -215,7 +215,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
GenerateCorrelationId(properties); GenerateCorrelationId(properties);
var redirectContext = new RedirectContext(Context, Options) var redirectContext = new RedirectContext(Context, Options, properties)
{ {
ProtocolMessage = message ProtocolMessage = message
}; };
@ -379,10 +379,9 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
} }
Logger.LogTrace(15, "Authorization response received."); Logger.LogTrace(15, "Authorization response received.");
var authorizationResponseReceivedContext = new AuthorizationResponseReceivedContext(Context, Options) var authorizationResponseReceivedContext = new AuthorizationResponseReceivedContext(Context, Options, properties)
{ {
ProtocolMessage = message, ProtocolMessage = message
Properties = properties
}; };
await Options.Events.AuthorizationResponseReceived(authorizationResponseReceivedContext); await Options.Events.AuthorizationResponseReceived(authorizationResponseReceivedContext);
if (authorizationResponseReceivedContext.HandledResponse) if (authorizationResponseReceivedContext.HandledResponse)
@ -469,7 +468,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
var tokenEndpointResponse = await RedeemAuthorizationCodeAsync(code, authorizationCodeReceivedContext.RedirectUri); var tokenEndpointResponse = await RedeemAuthorizationCodeAsync(code, authorizationCodeReceivedContext.RedirectUri);
var authorizationCodeRedeemedContext = await RunTokenResponseReceivedEventAsync(message, tokenEndpointResponse); var authorizationCodeRedeemedContext = await RunTokenResponseReceivedEventAsync(message, tokenEndpointResponse, properties);
if (authorizationCodeRedeemedContext.HandledResponse) if (authorizationCodeRedeemedContext.HandledResponse)
{ {
return AuthenticateResult.Success(authorizationCodeRedeemedContext.AuthenticationTicket); return AuthenticateResult.Success(authorizationCodeRedeemedContext.AuthenticationTicket);
@ -502,7 +501,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
Nonce = nonce Nonce = nonce
}); });
var authenticationValidatedContext = await RunAuthenticationValidatedEventAsync(message, ticket, tokenEndpointResponse); var authenticationValidatedContext = await RunAuthenticationValidatedEventAsync(message, ticket, properties, tokenEndpointResponse);
if (authenticationValidatedContext.HandledResponse) if (authenticationValidatedContext.HandledResponse)
{ {
return AuthenticateResult.Success(authenticationValidatedContext.AuthenticationTicket); return AuthenticateResult.Success(authenticationValidatedContext.AuthenticationTicket);
@ -551,7 +550,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
Nonce = nonce Nonce = nonce
}); });
var authenticationValidatedContext = await RunAuthenticationValidatedEventAsync(message, ticket, tokenEndpointResponse: null); var authenticationValidatedContext = await RunAuthenticationValidatedEventAsync(message, ticket, properties, tokenEndpointResponse: null);
if (authenticationValidatedContext.HandledResponse) if (authenticationValidatedContext.HandledResponse)
{ {
return AuthenticateResult.Success(authenticationValidatedContext.AuthenticationTicket); return AuthenticateResult.Success(authenticationValidatedContext.AuthenticationTicket);
@ -950,7 +949,7 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
Logger.LogTrace(32, "AuthorizationCode received: '{0}'", message.Code); Logger.LogTrace(32, "AuthorizationCode received: '{0}'", message.Code);
var authorizationCodeReceivedContext = new AuthorizationCodeReceivedContext(Context, Options) var authorizationCodeReceivedContext = new AuthorizationCodeReceivedContext(Context, Options, properties)
{ {
Code = message.Code, Code = message.Code,
ProtocolMessage = message, ProtocolMessage = message,
@ -972,10 +971,10 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
return authorizationCodeReceivedContext; return authorizationCodeReceivedContext;
} }
private async Task<TokenResponseReceivedContext> RunTokenResponseReceivedEventAsync(OpenIdConnectMessage message, OpenIdConnectMessage tokenEndpointResponse) private async Task<TokenResponseReceivedContext> RunTokenResponseReceivedEventAsync(OpenIdConnectMessage message, OpenIdConnectMessage tokenEndpointResponse, AuthenticationProperties properties)
{ {
Logger.LogTrace(35, "Token response received."); Logger.LogTrace(35, "Token response received.");
var tokenResponseReceivedContext = new TokenResponseReceivedContext(Context, Options) var tokenResponseReceivedContext = new TokenResponseReceivedContext(Context, Options, properties)
{ {
ProtocolMessage = message, ProtocolMessage = message,
TokenEndpointResponse = tokenEndpointResponse TokenEndpointResponse = tokenEndpointResponse
@ -993,9 +992,9 @@ namespace Microsoft.AspNet.Authentication.OpenIdConnect
return tokenResponseReceivedContext; return tokenResponseReceivedContext;
} }
private async Task<AuthenticationValidatedContext> RunAuthenticationValidatedEventAsync(OpenIdConnectMessage message, AuthenticationTicket ticket, OpenIdConnectMessage tokenEndpointResponse) private async Task<AuthenticationValidatedContext> RunAuthenticationValidatedEventAsync(OpenIdConnectMessage message, AuthenticationTicket ticket, AuthenticationProperties properties, OpenIdConnectMessage tokenEndpointResponse)
{ {
var authenticationValidatedContext = new AuthenticationValidatedContext(Context, Options) var authenticationValidatedContext = new AuthenticationValidatedContext(Context, Options, properties)
{ {
AuthenticationTicket = ticket, AuthenticationTicket = ticket,
ProtocolMessage = message, ProtocolMessage = message,

View File

@ -533,6 +533,54 @@ namespace Microsoft.AspNet.Authentication.Cookies
Assert.Null(FindClaimValue(transaction5, ClaimTypes.Name)); Assert.Null(FindClaimValue(transaction5, ClaimTypes.Name));
} }
[Fact]
public async Task CookieValidatorOnlyCalledOnce()
{
var clock = new TestClock();
var server = CreateServer(options =>
{
options.SystemClock = clock;
options.ExpireTimeSpan = TimeSpan.FromMinutes(10);
options.SlidingExpiration = false;
options.Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = ctx =>
{
ctx.ShouldRenew = true;
return Task.FromResult(0);
}
};
},
context =>
context.Authentication.SignInAsync("Cookies",
new ClaimsPrincipal(new ClaimsIdentity(new GenericIdentity("Alice", "Cookies")))));
var transaction1 = await SendAsync(server, "http://example.com/testpath");
var transaction2 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
Assert.NotNull(transaction2.SetCookie);
Assert.Equal("Alice", FindClaimValue(transaction2, ClaimTypes.Name));
clock.Add(TimeSpan.FromMinutes(5));
var transaction3 = await SendAsync(server, "http://example.com/me/Cookies", transaction2.CookieNameValue);
Assert.NotNull(transaction3.SetCookie);
Assert.Equal("Alice", FindClaimValue(transaction3, ClaimTypes.Name));
clock.Add(TimeSpan.FromMinutes(6));
var transaction4 = await SendAsync(server, "http://example.com/me/Cookies", transaction1.CookieNameValue);
Assert.Null(transaction4.SetCookie);
Assert.Null(FindClaimValue(transaction4, ClaimTypes.Name));
clock.Add(TimeSpan.FromMinutes(5));
var transaction5 = await SendAsync(server, "http://example.com/me/Cookies", transaction2.CookieNameValue);
Assert.Null(transaction5.SetCookie);
Assert.Null(FindClaimValue(transaction5, ClaimTypes.Name));
}
[Fact] [Fact]
public async Task CookieExpirationCanBeOverridenInEvent() public async Task CookieExpirationCanBeOverridenInEvent()
{ {