Ejemplo n.º 1
0
        protected override Task ApplyResponseGrantAsync()
        {
            AuthenticationResponseRevoke signout = Helper.LookupSignOut(Options.AuthenticationType, Options.AuthenticationMode);

            if (signout != null)
            {
                // Base logout url
                var logoutUri = $"https://{Options.Domain}/v2/logout?client_id={Options.ClientId}";

                // Add redirect after logout
                var postLogoutUri = signout.Properties.RedirectUri;
                if (!string.IsNullOrEmpty(postLogoutUri))
                {
                    if (postLogoutUri.StartsWith("/"))
                    {
                        // transform to absolute
                        postLogoutUri = Request.Scheme + "://" + Request.Host + postLogoutUri;
                    }
                    logoutUri += $"&returnTo={Uri.EscapeDataString(postLogoutUri)}";
                }

                // Handle federated logout
                if (signout.Properties.Dictionary.ContainsKey(".federated") &&
                    signout.Properties.Dictionary[".federated"] == "true")
                {
                    logoutUri += "&federated";
                }

                var logoutContext = new Auth0ApplyLogoutContext(
                    Context, Options, signout.Properties, logoutUri);
                Options.Provider.ApplyLogout(logoutContext);
            }

            return(base.ApplyResponseGrantAsync());
        }
Ejemplo n.º 2
0
        public async Task KentorAuthServicesAuthenticationMiddleware_CreatesRedirectOnAuthRevoke()
        {
            var revoke = new AuthenticationResponseRevoke(new string[0]);

            var options = new KentorAuthServicesAuthenticationOptions(true);

            options.SPOptions.PublicOrigin = new Uri("https://sp.example.com/ExternalPath/");

            var subject = new KentorAuthServicesAuthenticationMiddleware(
                new StubOwinMiddleware(200, revoke: revoke),
                CreateAppBuilder(),
                options);

            var context = OwinTestHelpers.CreateOwinContext();

            context.Request.Scheme   = "http";
            context.Request.Host     = new HostString("sp-internal.example.com");
            context.Request.PathBase = new PathString("/InternalPath");
            context.Request.Path     = new PathString("/LoggedOut");

            Thread.CurrentPrincipal = new ClaimsPrincipal(
                new ClaimsIdentity(new Claim[]
            {
                new Claim(ClaimTypes.NameIdentifier, "NameId", null, "https://idp.example.com"),
                new Claim(AuthServicesClaimTypes.SessionIndex, "SessionId", null, "https://idp.example.com")
            }, "Federation"));

            await subject.Invoke(context);

            context.Response.StatusCode.Should().Be(303);
            context.Response.Headers["Location"].Should().StartWith("https://idp.example.com/logout?SAMLRequest");
            var returnUrl = ExtractRequestState(options.DataProtector, context).ReturnUrl;

            returnUrl.Should().Be("https://sp.example.com/ExternalPath/LoggedOut");
        }
        protected override async Task ApplyResponseGrantAsync()
        {
            AuthenticationResponseGrant signin = Helper.LookupSignIn(Options.AuthenticationType);
            bool shouldSignin = signin != null;
            AuthenticationResponseRevoke signout = Helper.LookupSignOut(Options.AuthenticationType, Options.AuthenticationMode);
            bool shouldSignout = signout != null;

            if (!(shouldSignin || shouldSignout))
            {
                return;
            }

            AuthenticationTicket model = await AuthenticateAsync();

            try
            {
                if (shouldSignin)
                {
                }
            }
            catch
            {
                throw;
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Find response sign-out details for a specific authentication middleware
        /// </summary>
        /// <param name="authenticationType">The authentication type to look for</param>
        /// <param name="authenticationMode">The authentication mode the middleware is running under</param>
        /// <returns>The information instructing the middleware how it should behave</returns>
        public AuthenticationResponseRevoke LookupSignOut(string authenticationType, AuthenticationMode authenticationMode)
        {
            if (authenticationType == null)
            {
                throw new ArgumentNullException("authenticationType");
            }

            AuthenticationResponseRevoke revoke = _context.Authentication.AuthenticationResponseRevoke;

            if (revoke == null)
            {
                return(null);
            }
            if (revoke.AuthenticationTypes == null || revoke.AuthenticationTypes.Length == 0)
            {
                return(authenticationMode == AuthenticationMode.Active ? revoke : null);
            }
            for (int index = 0; index != revoke.AuthenticationTypes.Length; ++index)
            {
                if (String.Equals(authenticationType, revoke.AuthenticationTypes[index], StringComparison.Ordinal))
                {
                    return(revoke);
                }
            }
            return(null);
        }
Ejemplo n.º 5
0
        private Task <bool> HandleLogoutAsync(AuthenticationResponseRevoke context)
        {
            // Extract the OpenID Connect request from the OWIN/Katana context.
            // If it cannot be found or doesn't correspond to a logout request,
            // throw an InvalidOperationException.
            var request = Context.GetOpenIdConnectRequest();

            if (request == null || !request.IsLogoutRequest())
            {
                throw new InvalidOperationException("An OpenID Connect response cannot be returned from this endpoint.");
            }

            // Note: if an OpenID Connect response was already generated, throw an exception.
            var response = Context.GetOpenIdConnectResponse();

            if (response != null)
            {
                throw new InvalidOperationException("An OpenID Connect response has already been sent.");
            }

            // Prepare a new a OpenID Connect response.
            response = new OpenIdConnectResponse {
                PostLogoutRedirectUri = request.PostLogoutRedirectUri,
                State = request.State
            };

            return(SendLogoutResponseAsync(response));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Handles Signout
        /// </summary>
        /// <returns></returns>
        protected override async Task ApplyResponseGrantAsync()
        {
            AuthenticationResponseRevoke signout = Helper.LookupSignOut(Options.AuthenticationType, Options.AuthenticationMode);

            if (signout == null)
            {
                return;
            }

            if (_configuration == null)
            {
                _configuration = await Options.ConfigurationManager.GetConfigurationAsync(Context.Request.CallCancelled);
            }

            WsFederationMessage wsFederationMessage = new WsFederationMessage()
            {
                IssuerAddress = _configuration.TokenEndpoint ?? string.Empty,
                Wtrealm       = Options.Wtrealm,
                Wa            = WsFederationActions.SignOut,
            };

            // Set Wreply in order:
            // 1. properties.Redirect
            // 2. Options.SignOutWreply
            // 3. Options.Wreply
            AuthenticationProperties properties = signout.Properties;

            if (properties != null && !string.IsNullOrEmpty(properties.RedirectUri))
            {
                wsFederationMessage.Wreply = properties.RedirectUri;
            }
            else if (!string.IsNullOrWhiteSpace(Options.SignOutWreply))
            {
                wsFederationMessage.Wreply = Options.SignOutWreply;
            }
            else if (!string.IsNullOrWhiteSpace(Options.Wreply))
            {
                wsFederationMessage.Wreply = Options.Wreply;
            }

            var notification = new RedirectToIdentityProviderNotification <WsFederationMessage, WsFederationAuthenticationOptions>(Context, Options)
            {
                ProtocolMessage = wsFederationMessage
            };
            await Options.Notifications.RedirectToIdentityProvider(notification);

            if (!notification.HandledResponse)
            {
                string redirectUri = notification.ProtocolMessage.CreateSignOutUrl();
                if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute))
                {
                    _logger.WriteWarning("The sign-out redirect URI is malformed: " + redirectUri);
                }
                Response.Redirect(redirectUri);
            }
        }
        protected override async Task ApplyResponseGrantAsync()
        {
            AuthenticationResponseRevoke signout = Helper.LookupSignOut(Options.AuthenticationType, Options.AuthenticationMode);

            if (signout != null)
            {
                AuthenticationProperties properties = signout.Properties;

                B2CConfigurationManager mgr = Options.ConfigurationManager as B2CConfigurationManager;
                _configuration = await mgr.GetConfigurationAsync(Context.Request.CallCancelled, "b2c_1_sign_in");

                OpenIdConnectMessage openIdConnectMessage = new OpenIdConnectMessage()
                {
                    IssuerAddress = _configuration.EndSessionEndpoint ?? string.Empty,
                    RequestType   = OpenIdConnectRequestType.LogoutRequest,
                };

                string redirect = string.Empty;
                if (properties != null && !string.IsNullOrEmpty(properties.RedirectUri))
                {
                    openIdConnectMessage.PostLogoutRedirectUri = properties.RedirectUri;
                    redirect = properties.RedirectUri;
                }
                else if (!string.IsNullOrWhiteSpace(Options.PostLogoutRedirectUri))
                {
                    openIdConnectMessage.PostLogoutRedirectUri = Options.PostLogoutRedirectUri;
                    redirect = Options.RedirectUri;
                }

                if (string.IsNullOrWhiteSpace(openIdConnectMessage.PostLogoutRedirectUri))
                {
                    throw new Exception("For B2C, the PostLogoutRedirectUri is required.");
                }
                if (string.IsNullOrWhiteSpace(redirect))
                {
                    throw new Exception("For B2C, the RedirectUri is required.");
                }

                var notification = new RedirectToIdentityProviderNotification <OpenIdConnectMessage, OpenIdConnectAuthenticationOptions>(Context, Options)
                {
                    ProtocolMessage = openIdConnectMessage
                };
                await Options.Notifications.RedirectToIdentityProvider(notification);

                if (!notification.HandledResponse)
                {
                    string redirectUri = notification.ProtocolMessage.CreateLogoutRequestUrl();
                    redirectUri = redirectUri + "&" + OpenIdConnectParameterNames.RedirectUri + "=" + HttpUtility.UrlEncode(redirect) + "&" + OpenIdConnectParameterNames.ClientId + "=" + Options.ClientId;
                    if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute))
                    {
                        _logger.WriteWarning("The logout redirect URI is malformed: " + redirectUri);
                    }
                    Response.Redirect(redirectUri);
                }
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Handles Signout
        /// </summary>
        /// <returns></returns>
        protected override async Task ApplyResponseGrantAsync()
        {
            AuthenticationResponseRevoke signout = Helper.LookupSignOut(Options.AuthenticationType, Options.AuthenticationMode);

            if (signout == null)
            {
                return;
            }

            SamlMessage SamlMessage = await SamlMessageFromRequest();

            // WS Fed was "TokenAddress". Not sure this is the right endpoint
            SamlMessage.IssuerAddress = Options.Configuration.ServiceProvider.Endpoints.DefaultLogoutEndpoint.RedirectUrl ?? string.Empty;
            SamlMessage.Reply         = string.Empty;

            // Set Wreply in order:
            // 1. properties.Redirect
            // 2. Options.SignOutWreply
            // 3. Options.Wreply
            AuthenticationProperties properties = signout.Properties;

            if (properties != null && !string.IsNullOrEmpty(properties.RedirectUri))
            {
                SamlMessage.Reply = properties.RedirectUri;
            }
            else if (!string.IsNullOrWhiteSpace(Options.Configuration.ServiceProvider.Endpoints.DefaultLogoutEndpoint.RedirectUrl))
            {
                SamlMessage.Reply = Options.Configuration.ServiceProvider.Endpoints.DefaultLogoutEndpoint.RedirectUrl;
            }

            var notification = new RedirectToIdentityProviderNotification <SamlMessage, SamlAuthenticationOptions>(Context, Options)
            {
                ProtocolMessage = SamlMessage
            };
            await Options.Notifications.RedirectToIdentityProvider(notification);

            if (!notification.HandledResponse)
            {
                string redirectUri = notification.ProtocolMessage.BuildSignOutRedirectUrl();
                if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute))
                {
                    _logger.WriteWarning("The sign-out redirect URI is malformed: " + redirectUri);
                }

                if (Context.Request.IsAjaxRequest())
                {
                    Response.Headers.Add("X-Location", new[] { redirectUri });
                }
                else
                {
                    Response.Redirect(redirectUri);
                }
            }
        }
Ejemplo n.º 9
0
 public StubOwinMiddleware(
     int statusCode,
     AuthenticationResponseChallenge challenge = null,
     AuthenticationResponseRevoke revoke       = null,
     AuthenticationResponseGrant grant         = null)
     : base(null)
 {
     this.statusCode = statusCode;
     this.challenge  = challenge;
     this.revoke     = revoke;
     this.grant      = grant;
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Handles Signout
        /// </summary>
        /// <returns></returns>
        protected override async Task ApplyResponseGrantAsync()
        {
            AuthenticationResponseRevoke signout =
                Helper.LookupSignOut(Options.AuthenticationType, Options.AuthenticationMode);

            if (signout != null)
            {
                if (_configuration == null)
                {
                    _configuration =
                        await Options.ConfigurationManager.GetConfigurationAsync(Context.Request.CallCancelled);
                }

                OpenIdConnectMessage openIdConnectMessage = new OpenIdConnectMessage()
                {
                    IssuerAddress = _configuration.EndSessionEndpoint ?? string.Empty,
                    RequestType   = OpenIdConnectRequestType.Logout,
                };

                // Set End_Session_Endpoint in order:
                // 1. properties.Redirect
                // 2. Options.Wreply
                AuthenticationProperties properties = signout.Properties;
                if (properties != null && !string.IsNullOrEmpty(properties.RedirectUri))
                {
                    openIdConnectMessage.PostLogoutRedirectUri = properties.RedirectUri;
                }
                else if (!string.IsNullOrWhiteSpace(Options.PostLogoutRedirectUri))
                {
                    openIdConnectMessage.PostLogoutRedirectUri = Options.PostLogoutRedirectUri;
                }

                var notification =
                    new RedirectToIdentityProviderNotification <OpenIdConnectMessage, OpenIdConnectAuthenticationOptions
                                                                >(Context, Options)
                {
                    ProtocolMessage = openIdConnectMessage
                };
                await Options.Notifications.RedirectToIdentityProvider(notification);

                if (!notification.HandledResponse)
                {
                    string redirectUri = notification.ProtocolMessage.CreateLogoutRequestUrl();
                    if (!Uri.IsWellFormedUriString(redirectUri, UriKind.Absolute))
                    {
                        _logger.WriteWarning("The logout redirect URI is malformed: " + redirectUri);
                    }

                    Response.Redirect(redirectUri);
                }
            }
        }
        /// <summary>
        /// Handles Signout
        /// </summary>
        /// <returns></returns>
        protected override async Task ApplyResponseGrantAsync()
        {
            AuthenticationResponseRevoke signout = Helper.LookupSignOut(Options.AuthenticationType, Options.AuthenticationMode);

            if (signout != null)
            {
                object obj = null;
                Context.Environment.TryGetValue("wsfed.SignOutRedirect", out obj);
                string wreply = obj as string;

                WsFederationMessage wsFederationMessage = new WsFederationMessage()
                {
                    IssuerAddress = Options.IssuerAddress ?? string.Empty,
                    Wtrealm       = Options.Wtrealm,
                };

                if (!string.IsNullOrWhiteSpace(wreply))
                {
                    wsFederationMessage.Wreply = wreply;
                }
                else if (!string.IsNullOrWhiteSpace(Options.Wreply))
                {
                    wsFederationMessage.Wreply = Options.Wreply;
                }

                if (Options.Notifications != null && Options.Notifications.RedirectToIdentityProvider != null)
                {
                    RedirectToIdentityProviderNotification <WsFederationMessage> notification =
                        new RedirectToIdentityProviderNotification <WsFederationMessage> {
                        ProtocolMessage = wsFederationMessage
                    };
                    await Options.Notifications.RedirectToIdentityProvider(notification);

                    if (notification.Cancel)
                    {
                        return;
                    }
                }

                string redirect = wsFederationMessage.CreateSignOutQueryString();
                if (!Uri.IsWellFormedUriString(redirect, UriKind.Absolute))
                {
                    _logger.WriteError(string.Format(CultureInfo.InvariantCulture, "The WsFederation sign-out redirect uri is not well formed: '{0}'", redirect));
                    return;
                }

                Response.Redirect(redirect);
            }
        }
Ejemplo n.º 12
0
        private async Task KentorAuthServicesAuthenticationMiddleware_CreatesRedirectOnAuthRevoke_PreservesRedirect(
            string location, string expectedUrl, string path = "/Account/LogOut")
        {
            var revoke = new AuthenticationResponseRevoke(new string[0]);

            var options = new KentorAuthServicesAuthenticationOptions(true);

            ((SPOptions)options.SPOptions).PublicOrigin = new Uri("https://sp.example.com/ExternalPath/");

            var subject = new KentorAuthServicesAuthenticationMiddleware(
                new StubOwinMiddleware(303, revoke: revoke),
                CreateAppBuilder(),
                options);

            var context = OwinTestHelpers.CreateOwinContext();

            context.Request.Scheme               = "http";
            context.Request.Host                 = new HostString("sp-internal.example.com");
            context.Request.PathBase             = new PathString("/AppPath");
            context.Request.Path                 = new PathString(path);
            context.Response.Headers["Location"] = location;

            Thread.CurrentPrincipal = new ClaimsPrincipal(
                new ClaimsIdentity(new Claim[]
            {
                new Claim(ClaimTypes.NameIdentifier, "NameId", null, "https://idp.example.com"),
                new Claim(AuthServicesClaimTypes.SessionIndex, "SessionId", null, "https://idp.example.com")
            }, "Federation"));

            await subject.Invoke(context);

            var cookieValue = context.Response.Headers["Set-Cookie"].Split(';', '=')[1]
                              .Replace('_', '/').Replace('-', '+').Replace('.', '=');

            var returnUrl = Encoding.UTF8.GetString(options.DataProtector.Unprotect(
                                                        Convert.FromBase64String(cookieValue)));

            returnUrl.Should().Be(expectedUrl);
        }
Ejemplo n.º 13
0
        public async Task KentorAuthServicesAuthenticationMiddleware_CreatesRedirectOnAuthRevoke_UsesAuthPropsReturnUrl()
        {
            var authPropsReturnUrl = "http://sp.exmample.com/AuthPropsLogout";

            var revoke = new AuthenticationResponseRevoke(
                new string[0],
                new AuthenticationProperties {
                RedirectUri = authPropsReturnUrl
            });

            var options = new KentorAuthServicesAuthenticationOptions(true);

            options.SPOptions.PublicOrigin = new Uri("https://sp.example.com/ExternalPath/");

            var subject = new KentorAuthServicesAuthenticationMiddleware(
                new StubOwinMiddleware(303, revoke: revoke),
                CreateAppBuilder(),
                options);

            var context = OwinTestHelpers.CreateOwinContext();

            context.Response.Headers["Location"] = "http://sp.example.com/locationHeader";

            Thread.CurrentPrincipal = new ClaimsPrincipal(
                new ClaimsIdentity(new Claim[]
            {
                new Claim(ClaimTypes.NameIdentifier, "NameId", null, "https://idp.example.com"),
                new Claim(AuthServicesClaimTypes.SessionIndex, "SessionId", null, "https://idp.example.com")
            }, "Federation"));

            await subject.Invoke(context);

            var cookieValue = context.Response.Headers["Set-Cookie"].Split(';', '=')[1];

            var returnUrl = new StoredRequestState(options.DataProtector.Unprotect(
                                                       HttpRequestData.GetBinaryData(cookieValue))).ReturnUrl;

            returnUrl.Should().Be(authPropsReturnUrl);
        }
Ejemplo n.º 14
0
        public async Task GivenNextMiddlewareRevokesAuth_ItRemovesForceSslCookie()
        {
            // Arrange
            var context = Fakes.CreateOwinContext();
            var next    = Fakes.CreateOwinMiddleware();
            var app     = new AppBuilder();
            var revoke  = new AuthenticationResponseRevoke(new string[0]);

            next.Setup(n => n.Invoke(context))
            .Returns <IOwinContext>(c =>
            {
                c.Authentication.AuthenticationResponseRevoke = revoke;
                return(Task.FromResult <object>(null));
            });
            context.Request
            .SetUrl("http://nuget.local/foo/bar/baz?qux=qooz");
            var middleware = new ForceSslWhenAuthenticatedMiddleware(next.Object, app, "ForceSSL", 443);

            // Act
            await middleware.Invoke(context);

            // Assert
            OwinAssert.DeletesCookie(context.Response, "ForceSSL");
        }
Ejemplo n.º 15
0
        private async Task <bool> HandleLogoutAsync(AuthenticationResponseRevoke context)
        {
            // Extract the OpenID Connect request from the OWIN/Katana context.
            // If it cannot be found or doesn't correspond to a logout request,
            // throw an InvalidOperationException.
            var request = Context.GetOpenIdConnectRequest();

            if (request == null || !request.IsLogoutRequest())
            {
                throw new InvalidOperationException("A logout response cannot be returned from this endpoint.");
            }

            // Note: if a response was already generated, throw an exception.
            var response = Context.GetOpenIdConnectResponse();

            if (response != null)
            {
                throw new InvalidOperationException("A response has already been sent.");
            }

            Logger.LogTrace("A log-out operation was triggered: {Properties}.", context.Properties.Dictionary);

            return(await SendLogoutResponseAsync(new OpenIdConnectResponse()));
        }
 private Task <bool> HandleLogoutAsync(AuthenticationResponseRevoke context)
 => HandleLogoutAsync(context.Properties);
Ejemplo n.º 17
0
 public void Revoke(string[] authenticationTypes)
 {
     AuthenticationResponseRevoke = new AuthenticationResponseRevoke(authenticationTypes);
 }
        protected override async Task ApplyResponseGrantAsync()
        {
            AuthenticationResponseGrant signin = Helper.LookupSignIn(Options.AuthenticationType);
            bool shouldSignin = signin != null;
            AuthenticationResponseRevoke signout = Helper.LookupSignOut(Options.AuthenticationType, Options.AuthenticationMode);
            bool shouldSignout = signout != null;

            if (shouldSignin || shouldSignout || _shouldRenew)
            {
                var cookieOptions = new CookieOptions
                {
                    Domain   = Options.CookieDomain,
                    HttpOnly = Options.CookieHttpOnly,
                    Path     = Options.CookiePath ?? "/",
                };
                if (Options.CookieSecure == CookieSecureOption.SameAsRequest)
                {
                    cookieOptions.Secure = Request.IsSecure;
                }
                else
                {
                    cookieOptions.Secure = Options.CookieSecure == CookieSecureOption.Always;
                }

                if (shouldSignin)
                {
                    var context = new CookieResponseSignInContext(
                        Context,
                        Options,
                        Options.AuthenticationType,
                        signin.Identity,
                        signin.Properties);

                    DateTimeOffset issuedUtc  = Options.SystemClock.UtcNow;
                    DateTimeOffset expiresUtc = issuedUtc.Add(Options.ExpireTimeSpan);

                    context.Properties.IssuedUtc  = issuedUtc;
                    context.Properties.ExpiresUtc = expiresUtc;

                    Options.Provider.ResponseSignIn(context);

                    if (context.Properties.IsPersistent)
                    {
                        cookieOptions.Expires = expiresUtc.ToUniversalTime().DateTime;
                    }

                    var    model       = new AuthenticationTicket(context.Identity, context.Properties);
                    string cookieValue = Options.TicketDataFormat.Protect(model);

                    Response.Cookies.Append(
                        Options.CookieName,
                        cookieValue,
                        cookieOptions);
                }
                else if (shouldSignout)
                {
                    Response.Cookies.Delete(
                        Options.CookieName,
                        cookieOptions);
                }
                else if (_shouldRenew)
                {
                    AuthenticationTicket model = await AuthenticateAsync();

                    model.Properties.IssuedUtc  = _renewIssuedUtc;
                    model.Properties.ExpiresUtc = _renewExpiresUtc;

                    string cookieValue = Options.TicketDataFormat.Protect(model);

                    if (model.Properties.IsPersistent)
                    {
                        cookieOptions.Expires = _renewExpiresUtc.ToUniversalTime().DateTime;
                    }

                    Response.Cookies.Append(
                        Options.CookieName,
                        cookieValue,
                        cookieOptions);
                }

                Response.Headers.Set(
                    HeaderNameCacheControl,
                    HeaderValueNoCache);

                Response.Headers.Set(
                    HeaderNamePragma,
                    HeaderValueNoCache);

                Response.Headers.Set(
                    HeaderNameExpires,
                    HeaderValueMinusOne);

                bool shouldLoginRedirect  = shouldSignin && Options.LoginPath.HasValue && Request.Path == Options.LoginPath;
                bool shouldLogoutRedirect = shouldSignout && Options.LogoutPath.HasValue && Request.Path == Options.LogoutPath;

                if ((shouldLoginRedirect || shouldLogoutRedirect) && Response.StatusCode == 200)
                {
                    IReadableStringCollection query = Request.Query;
                    string redirectUri = query.Get(Options.ReturnUrlParameter);
                    if (!string.IsNullOrWhiteSpace(redirectUri) &&
                        IsHostRelative(redirectUri))
                    {
                        var redirectContext = new CookieApplyRedirectContext(Context, Options, redirectUri);
                        Options.Provider.ApplyRedirect(redirectContext);
                    }
                }
            }
        }
Ejemplo n.º 19
0
        protected override async Task ApplyResponseGrantAsync()
        {
            AuthenticationResponseGrant signin = Helper.LookupSignIn(Options.AuthenticationType);
            bool shouldSignin = signin != null;
            AuthenticationResponseRevoke signout = Helper.LookupSignOut(Options.AuthenticationType, Options.AuthenticationMode);
            bool shouldSignout = signout != null;

            if (!(shouldSignin || shouldSignout || _shouldRenew))
            {
                return;
            }

            AuthenticationTicket model = await AuthenticateAsync();

            try
            {
                var cookieOptions = new CookieOptions
                {
                    Domain   = Options.CookieDomain,
                    HttpOnly = Options.CookieHttpOnly,
                    Path     = Options.CookiePath ?? "/",
                };
                if (Options.CookieSecure == CookieSecureOption.SameAsRequest)
                {
                    cookieOptions.Secure = Request.IsSecure;
                }
                else
                {
                    cookieOptions.Secure = Options.CookieSecure == CookieSecureOption.Always;
                }

                #region == 登陆,登出,刷新 ==

                // 登陆
                if (shouldSignin)
                {
                    var signInContext = new CookieResponseSignInContext(
                        Context,
                        Options,
                        Options.AuthenticationType,
                        signin.Identity,
                        signin.Properties,
                        cookieOptions);

                    DateTimeOffset issuedUtc;
                    if (signInContext.Properties.IssuedUtc.HasValue)
                    {
                        issuedUtc = signInContext.Properties.IssuedUtc.Value;
                    }
                    else
                    {
                        issuedUtc = Options.SystemClock.UtcNow;
                        signInContext.Properties.IssuedUtc = issuedUtc;
                    }

                    if (!signInContext.Properties.ExpiresUtc.HasValue)
                    {
                        signInContext.Properties.ExpiresUtc = issuedUtc.Add(Options.ExpireTimeSpan);
                    }

                    Options.Provider.ResponseSignIn(signInContext);

                    if (signInContext.Properties.IsPersistent)
                    {
                        DateTimeOffset expiresUtc = signInContext.Properties.ExpiresUtc ?? issuedUtc.Add(Options.ExpireTimeSpan);
                        signInContext.CookieOptions.Expires = expiresUtc.ToUniversalTime().DateTime;
                    }

                    model = new AuthenticationTicket(signInContext.Identity, signInContext.Properties);
                    if (Options.SessionStore != null)
                    {
                        if (_sessionKey != null)
                        {
                            await Options.SessionStore.RemoveAsync(_sessionKey);
                        }
                        _sessionKey = await Options.SessionStore.StoreAsync(model);

                        ClaimsIdentity identity = new ClaimsIdentity(
                            new[] { new Claim(SessionIdClaim, _sessionKey) },
                            Options.AuthenticationType);
                        model = new AuthenticationTicket(identity, null);
                    }

                    string cookieValue = Options.TicketDataFormat.Protect(model);

                    Options.CookieManager.AppendResponseCookie(
                        Context,
                        Options.CookieName,
                        cookieValue,
                        signInContext.CookieOptions);

                    var signedInContext = new CookieResponseSignedInContext(
                        Context,
                        Options,
                        Options.AuthenticationType,
                        signInContext.Identity,
                        signInContext.Properties);

                    Options.Provider.ResponseSignedIn(signedInContext);
                }
                // 登出
                else if (shouldSignout)
                {
                    if (Options.SessionStore != null && _sessionKey != null)
                    {
                        await Options.SessionStore.RemoveAsync(_sessionKey);
                    }

                    var context = new CookieResponseSignOutContext(
                        Context,
                        Options,
                        cookieOptions);

                    Options.Provider.ResponseSignOut(context);

                    Options.CookieManager.DeleteCookie(
                        Context,
                        Options.CookieName,
                        context.CookieOptions);
                }
                // 刷新
                else if (_shouldRenew)
                {
                    model.Properties.IssuedUtc  = _renewIssuedUtc;
                    model.Properties.ExpiresUtc = _renewExpiresUtc;

                    if (Options.SessionStore != null && _sessionKey != null)
                    {
                        await Options.SessionStore.RenewAsync(_sessionKey, model);

                        ClaimsIdentity identity = new ClaimsIdentity(
                            new[] { new Claim(SessionIdClaim, _sessionKey) },
                            Options.AuthenticationType);
                        model = new AuthenticationTicket(identity, null);
                    }

                    string cookieValue = Options.TicketDataFormat.Protect(model);

                    if (model.Properties.IsPersistent)
                    {
                        cookieOptions.Expires = _renewExpiresUtc.ToUniversalTime().DateTime;
                    }

                    Options.CookieManager.AppendResponseCookie(
                        Context,
                        Options.CookieName,
                        cookieValue,
                        cookieOptions);
                }

                #endregion

                Response.Headers.Set(
                    HeaderNameCacheControl,
                    HeaderValueNoCache);

                Response.Headers.Set(
                    HeaderNamePragma,
                    HeaderValueNoCache);

                Response.Headers.Set(
                    HeaderNameExpires,
                    HeaderValueMinusOne);

                // 跳转
                bool shouldLoginRedirect  = shouldSignin && Options.LoginPath.HasValue && Request.Path == Options.LoginPath;
                bool shouldLogoutRedirect = shouldSignout && Options.LogoutPath.HasValue && Request.Path == Options.LogoutPath;

                if ((shouldLoginRedirect || shouldLogoutRedirect) && Response.StatusCode == 200)
                {
                    IReadableStringCollection query = Request.Query;
                    string redirectUri = query.Get(Options.ReturnUrlParameter); // 根据url参数读取 跳转url
                    if (!string.IsNullOrWhiteSpace(redirectUri) &&
                        IsHostRelative(redirectUri))
                    {
                        var redirectContext = new CookieApplyRedirectContext(Context, Options, redirectUri);
                        Options.Provider.ApplyRedirect(redirectContext);
                    }
                }
            }
            catch (Exception exception)
            {
                CookieExceptionContext exceptionContext = new CookieExceptionContext(Context, Options,
                                                                                     CookieExceptionContext.ExceptionLocation.ApplyResponseGrant, exception, model);
                Options.Provider.Exception(exceptionContext);
                if (exceptionContext.Rethrow)
                {
                    throw;
                }
            }
        }
Ejemplo n.º 20
0
        protected override async Task ApplyResponseGrant()
        {
            _logger.WriteVerbose("ApplyResponseGrant");
            AuthenticationResponseGrant signin = Helper.LookupSignin(Options.AuthenticationType);
            bool shouldSignin = signin != null;
            AuthenticationResponseRevoke signout = Helper.LookupSignout(Options.AuthenticationType, Options.AuthenticationMode);
            bool shouldSignout = signout != null;

            if (shouldSignin || shouldSignout || _shouldRenew)
            {
                var cookieOptions = new CookieOptions
                {
                    Domain   = Options.CookieDomain,
                    HttpOnly = Options.CookieHttpOnly,
                    Path     = Options.CookiePath ?? "/",
                };
                if (Options.CookieSecure == CookieSecureOption.SameAsRequest)
                {
                    cookieOptions.Secure = Request.IsSecure;
                }
                else
                {
                    cookieOptions.Secure = Options.CookieSecure == CookieSecureOption.Always;
                }

                if (shouldSignin)
                {
                    var context = new FormsResponseSignInContext(
                        Response.Environment,
                        Options.AuthenticationType,
                        signin.Identity,
                        signin.Extra);

                    DateTimeOffset issuedUtc  = Options.SystemClock.UtcNow;
                    DateTimeOffset expiresUtc = issuedUtc.Add(Options.ExpireTimeSpan);

                    context.Extra.IssuedUtc  = issuedUtc;
                    context.Extra.ExpiresUtc = expiresUtc;

                    Options.Provider.ResponseSignIn(context);

                    if (context.Extra.IsPersistent)
                    {
                        cookieOptions.Expires = expiresUtc.ToUniversalTime().DateTime;
                    }

                    var    model       = new AuthenticationTicket(context.Identity, context.Extra.Properties);
                    string cookieValue = Options.TicketDataHandler.Protect(model);

                    Response.AddCookie(
                        Options.CookieName,
                        cookieValue,
                        cookieOptions);
                }
                else if (shouldSignout)
                {
                    Response.DeleteCookie(
                        Options.CookieName,
                        cookieOptions);
                }
                else if (_shouldRenew)
                {
                    AuthenticationTicket model = await Authenticate();

                    model.Extra.IssuedUtc  = _renewIssuedUtc;
                    model.Extra.ExpiresUtc = _renewExpiresUtc;

                    string cookieValue = Options.TicketDataHandler.Protect(model);

                    if (model.Extra.IsPersistent)
                    {
                        cookieOptions.Expires = _renewExpiresUtc.ToUniversalTime().DateTime;
                    }

                    Response.AddCookie(
                        Options.CookieName,
                        cookieValue,
                        cookieOptions);
                }

                Response.SetHeader(
                    HeaderNameCacheControl,
                    HeaderValueNoCache);

                Response.SetHeader(
                    HeaderNamePragma,
                    HeaderValueNoCache);

                Response.SetHeader(
                    HeaderNameExpires,
                    HeaderValueMinusOne);

                bool shouldLoginRedirect  = shouldSignin && !string.IsNullOrEmpty(Options.LoginPath) && string.Equals(Request.Path, Options.LoginPath, StringComparison.OrdinalIgnoreCase);
                bool shouldLogoutRedirect = shouldSignout && !string.IsNullOrEmpty(Options.LogoutPath) && string.Equals(Request.Path, Options.LogoutPath, StringComparison.OrdinalIgnoreCase);

                if ((shouldLoginRedirect || shouldLogoutRedirect) && Response.StatusCode == 200)
                {
                    IDictionary <string, string[]> query = Request.GetQuery();
                    string[] redirectUri;
                    if (query.TryGetValue(Options.ReturnUrlParameter ?? FormsAuthenticationDefaults.ReturnUrlParameter, out redirectUri) &&
                        redirectUri != null &&
                        redirectUri.Length == 1 &&
                        IsHostRelative(redirectUri[0]))
                    {
                        Response.Redirect(redirectUri[0]);
                    }
                }
            }
        }