diff --git a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs index 4c83699f5d..5ddbde3891 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/CookieAuthenticationHandler.cs @@ -204,7 +204,7 @@ namespace Microsoft.AspNet.Authentication.Cookies cookieValue, cookieOptions); - ApplyHeaders(); + await ApplyHeaders(shouldRedirectToReturnUrl: false); } catch (Exception exception) { @@ -288,8 +288,9 @@ namespace Microsoft.AspNet.Authentication.Cookies await Options.Events.SignedIn(signedInContext); - var shouldLoginRedirect = Options.LoginPath.HasValue && OriginalPath == Options.LoginPath; - ApplyHeaders(shouldLoginRedirect); + // Only redirect on the login path + var shouldRedirect = Options.LoginPath.HasValue && OriginalPath == Options.LoginPath; + await ApplyHeaders(shouldRedirect); } catch (Exception exception) { @@ -326,8 +327,9 @@ namespace Microsoft.AspNet.Authentication.Cookies Options.CookieName, context.CookieOptions); - var shouldLogoutRedirect = Options.LogoutPath.HasValue && OriginalPath == Options.LogoutPath; - ApplyHeaders(shouldLogoutRedirect); + // Only redirect on the logout path + var shouldRedirect = Options.LogoutPath.HasValue && OriginalPath == Options.LogoutPath; + await ApplyHeaders(shouldRedirect); } catch (Exception exception) { @@ -341,12 +343,11 @@ namespace Microsoft.AspNet.Authentication.Cookies } } - private void ApplyHeaders(bool shouldRedirectToReturnUrl = false) + private async Task ApplyHeaders(bool shouldRedirectToReturnUrl) { Response.Headers[HeaderNames.CacheControl] = HeaderValueNoCache; Response.Headers[HeaderNames.Pragma] = HeaderValueNoCache; Response.Headers[HeaderNames.Expires] = HeaderValueMinusOne; - if (shouldRedirectToReturnUrl && Response.StatusCode == 200) { var query = Request.Query; @@ -354,10 +355,11 @@ namespace Microsoft.AspNet.Authentication.Cookies if (!StringValues.IsNullOrEmpty(redirectUri) && IsHostRelative(redirectUri)) { - var redirectContext = new CookieApplyRedirectContext(Context, Options, redirectUri); - Options.Events.ApplyRedirect(redirectContext); + var redirectContext = new CookieRedirectContext(Context, Options, redirectUri); + await Options.Events.RedirectToReturnUrl(redirectContext); } } + } private static bool IsHostRelative(string path) @@ -384,8 +386,8 @@ namespace Microsoft.AspNet.Authentication.Cookies OriginalPathBase + Options.AccessDeniedPath; - var redirectContext = new CookieApplyRedirectContext(Context, Options, accessDeniedUri); - await Options.Events.ApplyRedirect(redirectContext); + var redirectContext = new CookieRedirectContext(Context, Options, accessDeniedUri); + await Options.Events.RedirectToAccessDenied(redirectContext); } catch (Exception exception) { @@ -411,8 +413,8 @@ namespace Microsoft.AspNet.Authentication.Cookies } var loginUri = Options.LoginPath + QueryString.Create(Options.ReturnUrlParameter, redirectUri); - var redirectContext = new CookieApplyRedirectContext(Context, Options, BuildRedirectUri(loginUri)); - await Options.Events.ApplyRedirect(redirectContext); + var redirectContext = new CookieRedirectContext(Context, Options, BuildRedirectUri(loginUri)); + await Options.Events.RedirectToLogin(redirectContext); } catch (Exception exception) { diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Events/CookieAuthenticationEvents.cs b/src/Microsoft.AspNet.Authentication.Cookies/Events/CookieAuthenticationEvents.cs index 578feb1ca4..21881824ea 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Events/CookieAuthenticationEvents.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Events/CookieAuthenticationEvents.cs @@ -36,7 +36,34 @@ namespace Microsoft.AspNet.Authentication.Cookies /// /// A delegate assigned to this property will be invoked when the related method is called /// - public Func OnApplyRedirect { get; set; } = context => + public Func OnRedirectToReturnUrl { get; set; } = context => + { + context.Response.Redirect(context.RedirectUri); + return Task.FromResult(0); + }; + + /// + /// A delegate assigned to this property will be invoked when the related method is called + /// + public Func OnRedirectToAccessDenied { get; set; } = context => + { + context.Response.Redirect(context.RedirectUri); + return Task.FromResult(0); + }; + + /// + /// A delegate assigned to this property will be invoked when the related method is called + /// + public Func OnRedirectToLogin { get; set; } = context => + { + context.Response.Redirect(context.RedirectUri); + return Task.FromResult(0); + }; + + /// + /// A delegate assigned to this property will be invoked when the related method is called + /// + public Func OnRedirectToLogout { get; set; } = context => { context.Response.Redirect(context.RedirectUri); return Task.FromResult(0); @@ -76,7 +103,25 @@ namespace Microsoft.AspNet.Authentication.Cookies /// Implements the interface method by invoking the related delegate method /// /// Contains information about the event - public virtual Task ApplyRedirect(CookieApplyRedirectContext context) => OnApplyRedirect(context); + public virtual Task RedirectToLogout(CookieRedirectContext context) => OnRedirectToLogout(context); + + /// + /// Implements the interface method by invoking the related delegate method + /// + /// Contains information about the event + public virtual Task RedirectToLogin(CookieRedirectContext context) => OnRedirectToLogin(context); + + /// + /// Implements the interface method by invoking the related delegate method + /// + /// Contains information about the event + public virtual Task RedirectToReturnUrl(CookieRedirectContext context) => OnRedirectToReturnUrl(context); + + /// + /// Implements the interface method by invoking the related delegate method + /// + /// Contains information about the event + public virtual Task RedirectToAccessDenied(CookieRedirectContext context) => OnRedirectToAccessDenied(context); /// /// Implements the interface method by invoking the related delegate method diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Events/CookieApplyRedirectContext.cs b/src/Microsoft.AspNet.Authentication.Cookies/Events/CookieRedirectContext.cs similarity index 86% rename from src/Microsoft.AspNet.Authentication.Cookies/Events/CookieApplyRedirectContext.cs rename to src/Microsoft.AspNet.Authentication.Cookies/Events/CookieRedirectContext.cs index aeea8f9633..0687b9d280 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Events/CookieApplyRedirectContext.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Events/CookieRedirectContext.cs @@ -9,7 +9,7 @@ namespace Microsoft.AspNet.Authentication.Cookies /// /// Context passed when a Challenge, SignIn, or SignOut causes a redirect in the cookie middleware /// - public class CookieApplyRedirectContext : BaseContext + public class CookieRedirectContext : BaseContext { /// /// Creates a new context object. @@ -18,7 +18,7 @@ namespace Microsoft.AspNet.Authentication.Cookies /// The cookie middleware options /// The initial redirect URI [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "2#", Justification = "Represents header value")] - public CookieApplyRedirectContext(HttpContext context, CookieAuthenticationOptions options, string redirectUri) + public CookieRedirectContext(HttpContext context, CookieAuthenticationOptions options, string redirectUri) : base(context, options) { RedirectUri = redirectUri; diff --git a/src/Microsoft.AspNet.Authentication.Cookies/Events/ICookieAuthenticationEvents.cs b/src/Microsoft.AspNet.Authentication.Cookies/Events/ICookieAuthenticationEvents.cs index 9a74f657d9..6011ea8774 100644 --- a/src/Microsoft.AspNet.Authentication.Cookies/Events/ICookieAuthenticationEvents.cs +++ b/src/Microsoft.AspNet.Authentication.Cookies/Events/ICookieAuthenticationEvents.cs @@ -32,10 +32,28 @@ namespace Microsoft.AspNet.Authentication.Cookies Task SignedIn(CookieSignedInContext context); /// - /// Called when a Challenge, SignIn, or SignOut causes a redirect in the cookie middleware + /// Called when a SignOut causes a redirect in the cookie middleware /// /// Contains information about the event - Task ApplyRedirect(CookieApplyRedirectContext context); + Task RedirectToLogout(CookieRedirectContext context); + + /// + /// Called when a SignIn causes a redirect in the cookie middleware + /// + /// Contains information about the event + Task RedirectToLogin(CookieRedirectContext context); + + /// + /// Called when redirecting back to the return url in the cookie middleware + /// + /// Contains information about the event + Task RedirectToReturnUrl(CookieRedirectContext context); + + /// + /// Called when an access denied causes a redirect in the cookie middleware + /// + /// Contains information about the event + Task RedirectToAccessDenied(CookieRedirectContext context); /// /// Called during the sign-out flow to augment the cookie cleanup process. diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Events/IOAuthEvents.cs b/src/Microsoft.AspNet.Authentication.OAuth/Events/IOAuthEvents.cs index 9f161f344c..82f4bc4155 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/Events/IOAuthEvents.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Events/IOAuthEvents.cs @@ -29,6 +29,6 @@ namespace Microsoft.AspNet.Authentication.OAuth /// Called when a Challenge causes a redirect to the authorize endpoint. /// /// Contains redirect URI and of the challenge. - Task RedirectToAuthorizationEndpoint(OAuthRedirectToAuthorizationEndpointContext context); + Task RedirectToAuthorizationEndpoint(OAuthRedirectToAuthorizationContext context); } } diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Events/OAuthAuthenticatedContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Events/OAuthCreatingTicketContext.cs similarity index 100% rename from src/Microsoft.AspNet.Authentication.OAuth/Events/OAuthAuthenticatedContext.cs rename to src/Microsoft.AspNet.Authentication.OAuth/Events/OAuthCreatingTicketContext.cs diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Events/OAuthEvents.cs b/src/Microsoft.AspNet.Authentication.OAuth/Events/OAuthEvents.cs index 364d6c2edf..357f2dfa9c 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/Events/OAuthEvents.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Events/OAuthEvents.cs @@ -24,7 +24,7 @@ namespace Microsoft.AspNet.Authentication.OAuth /// /// Gets or sets the delegate that is invoked when the RedirectToAuthorizationEndpoint method is invoked. /// - public Func OnRedirectToAuthorizationEndpoint { get; set; } = context => + public Func OnRedirectToAuthorizationEndpoint { get; set; } = context => { context.Response.Redirect(context.RedirectUri); return Task.FromResult(0); @@ -48,6 +48,6 @@ namespace Microsoft.AspNet.Authentication.OAuth /// Called when a Challenge causes a redirect to authorize endpoint in the OAuth middleware. /// /// Contains redirect URI and of the challenge. - public virtual Task RedirectToAuthorizationEndpoint(OAuthRedirectToAuthorizationEndpointContext context) => OnRedirectToAuthorizationEndpoint(context); + public virtual Task RedirectToAuthorizationEndpoint(OAuthRedirectToAuthorizationContext context) => OnRedirectToAuthorizationEndpoint(context); } } diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Events/OAuthRedirectToAuthorizationEndpointContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Events/OAuthRedirectToAuthorizationContext.cs similarity index 83% rename from src/Microsoft.AspNet.Authentication.OAuth/Events/OAuthRedirectToAuthorizationEndpointContext.cs rename to src/Microsoft.AspNet.Authentication.OAuth/Events/OAuthRedirectToAuthorizationContext.cs index 0bfbd26f7b..636cb933fe 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/Events/OAuthRedirectToAuthorizationEndpointContext.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/Events/OAuthRedirectToAuthorizationContext.cs @@ -9,7 +9,7 @@ namespace Microsoft.AspNet.Authentication.OAuth /// /// Context passed when a Challenge causes a redirect to authorize endpoint in the middleware. /// - public class OAuthRedirectToAuthorizationEndpointContext : BaseContext + public class OAuthRedirectToAuthorizationContext : BaseContext { /// /// Creates a new context object. @@ -17,7 +17,7 @@ namespace Microsoft.AspNet.Authentication.OAuth /// The HTTP request context. /// The authentication properties of the challenge. /// The initial redirect URI. - public OAuthRedirectToAuthorizationEndpointContext(HttpContext context, OAuthOptions options, AuthenticationProperties properties, string redirectUri) + public OAuthRedirectToAuthorizationContext(HttpContext context, OAuthOptions options, AuthenticationProperties properties, string redirectUri) : base(context, options) { RedirectUri = redirectUri; diff --git a/src/Microsoft.AspNet.Authentication.OAuth/Events/OAuthReturnEndpointContext.cs b/src/Microsoft.AspNet.Authentication.OAuth/Events/OAuthReturnEndpointContext.cs deleted file mode 100644 index 2c59fdd183..0000000000 --- a/src/Microsoft.AspNet.Authentication.OAuth/Events/OAuthReturnEndpointContext.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNet.Http; - -namespace Microsoft.AspNet.Authentication.OAuth -{ - /// - /// Provides context information to middleware providers. - /// - public class OAuthReturnEndpointContext : SigningInContext - { - /// - /// Initializes a new . - /// - /// The HTTP environment. - /// The authentication ticket. - public OAuthReturnEndpointContext( - HttpContext context, - AuthenticationTicket ticket) - : base(context, ticket) - { - } - } -} diff --git a/src/Microsoft.AspNet.Authentication.OAuth/OAuthHandler.cs b/src/Microsoft.AspNet.Authentication.OAuth/OAuthHandler.cs index 8449d75d23..c2c3481597 100644 --- a/src/Microsoft.AspNet.Authentication.OAuth/OAuthHandler.cs +++ b/src/Microsoft.AspNet.Authentication.OAuth/OAuthHandler.cs @@ -50,7 +50,7 @@ namespace Microsoft.AspNet.Authentication.OAuth return true; } - var context = new OAuthReturnEndpointContext(Context, ticket) + var context = new SigningInContext(Context, ticket) { SignInScheme = Options.SignInScheme, RedirectUri = ticket.Properties.RedirectUri, @@ -212,7 +212,7 @@ namespace Microsoft.AspNet.Authentication.OAuth var authorizationEndpoint = BuildChallengeUrl(properties, BuildRedirectUri(Options.CallbackPath)); - var redirectContext = new OAuthRedirectToAuthorizationEndpointContext( + var redirectContext = new OAuthRedirectToAuthorizationContext( Context, Options, properties, authorizationEndpoint); await Options.Events.RedirectToAuthorizationEndpoint(redirectContext);