Exemple #1
0
        public static Task RedirectToIdentityProvider(RedirectToIdentityProviderNotification <OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
        {
            // If a challenge was issued by the SingleSignOut javascript
            UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext);

            if (notification.Request.Uri.AbsolutePath == url.Action("SessionChanged", "Account"))
            {
                // Store the state in the cookie so we can distinguish OIDC messages that occurred
                // as a result of the SingleSignOut javascript.
                ICookieManager       cookieManager = new ChunkingCookieManager();
                string               cookie        = cookieManager.GetRequestCookie(notification.OwinContext, CookieName);
                AuthenticationTicket ticket        = ticketDataFormat.Unprotect(cookie);
                if (ticket.Properties.Dictionary != null)
                {
                    ticket.Properties.Dictionary[OpenIdConnectAuthenticationDefaults.AuthenticationType + "SingleSignOut"] = notification.ProtocolMessage.State;
                }
                cookieManager.AppendResponseCookie(notification.OwinContext, CookieName, ticketDataFormat.Protect(ticket), new CookieOptions());

                // Return prompt=none request (to tenant specific endpoint) to SessionChanged controller.
                notification.ProtocolMessage.Prompt        = "none";
                notification.ProtocolMessage.IssuerAddress = notification.OwinContext.Authentication.User.FindFirst("issEndpoint").Value;
                string redirectUrl = notification.ProtocolMessage.BuildRedirectUrl();
                notification.Response.Redirect(url.Action("SessionChanged", "Account") + "?" + redirectUrl);
                notification.HandleResponse();
            }

            return(Task.FromResult <object>(null));
        }
Exemple #2
0
        // If the javascript issues an OIDC authorize request, and it fails (meaning the user needs to login)
        // this notification will be triggered with the error message 'login_required'
        public static Task AuthenticationFailed(AuthenticationFailedNotification <OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> notification)
        {
            string               cookieStateValue = null;
            ICookieManager       cookieManager    = new ChunkingCookieManager();
            string               cookie           = cookieManager.GetRequestCookie(notification.OwinContext, CookieName);
            AuthenticationTicket ticket           = ticketDataFormat.Unprotect(cookie);

            if (ticket.Properties.Dictionary != null)
            {
                ticket.Properties.Dictionary.TryGetValue(OpenIdConnectAuthenticationDefaults.AuthenticationType + "SingleSignOut", out cookieStateValue);
            }

            // If the failed authentication was a result of a request by the SingleSignOut javascript
            if (cookieStateValue != null && cookieStateValue.Contains(notification.ProtocolMessage.State) && notification.Exception.Message == "login_required")
            {
                ;
            }
            {
                // Clear the SingleSignOut cookie, and clear the OIDC session state so
                //that we don't see any further "Session Changed" messages from the iframe.
                ticket.Properties.Dictionary[OpenIdConnectSessionProperties.SessionState] = "";
                ticket.Properties.Dictionary[OpenIdConnectAuthenticationDefaults.AuthenticationType + "SingleSignOut"] = "";
                cookieManager.AppendResponseCookie(notification.OwinContext, CookieName, ticketDataFormat.Protect(ticket), new CookieOptions());

                notification.Response.Redirect("Account/SingleSignOut");
                notification.HandleResponse();
            }

            return(Task.FromResult <object>(null));
        }
Exemple #3
0
    /// <summary>
    /// Loads the temp data from the request.
    /// </summary>
    /// <param name="context">The <see cref="HttpContext"/>.</param>
    /// <returns>The temp data.</returns>
    public IDictionary <string, object> LoadTempData(HttpContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        if (context.Request.Cookies.ContainsKey(_options.Cookie.Name))
        {
            // The cookie we use for temp data is user input, and might be invalid in many ways.
            //
            // Since TempData is a best-effort system, we don't want to throw and get a 500 if the cookie is
            // bad, we will just clear it and ignore the exception. The common case that we've identified for
            // this is misconfigured data protection settings, which can cause the key used to create the
            // cookie to no longer be available.
            try
            {
                var encodedValue = _chunkingCookieManager.GetRequestCookie(context, _options.Cookie.Name);
                if (!string.IsNullOrEmpty(encodedValue))
                {
                    var protectedData   = WebEncoders.Base64UrlDecode(encodedValue);
                    var unprotectedData = _dataProtector.Unprotect(protectedData);
                    var tempData        = _tempDataSerializer.Deserialize(unprotectedData);

                    _logger.TempDataCookieLoadSuccess(_options.Cookie.Name);
                    return(tempData);
                }
            }
            catch (Exception ex)
            {
                _logger.TempDataCookieLoadFailure(_options.Cookie.Name, ex);

                // If we've failed, we want to try and clear the cookie so that this won't keep happening
                // over and over.
                if (!context.Response.HasStarted)
                {
                    _chunkingCookieManager.DeleteCookie(context, _options.Cookie.Name, _options.Cookie.Build(context));
                }
            }
        }

        _logger.TempDataCookieNotFound(_options.Cookie.Name);
        return(new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase));
    }
Exemple #4
0
        // If the javascript issues an OIDC authorize reuest, and it succeeds, the user is already logged
        // into AAD.  Since the AAD session cookie has changed, we need to check if the same use is still
        // logged in.
        public static Task AuthorizationCodeRecieved(AuthorizationCodeReceivedNotification notification)
        {
            // If the successful authorize request was issued by the SingleSignOut javascript
            if (notification.AuthenticationTicket.Properties.RedirectUri.Contains("SessionChanged"))
            {
                // Clear the SingleSignOut Cookie
                ICookieManager       cookieManager = new ChunkingCookieManager();
                string               cookie        = cookieManager.GetRequestCookie(notification.OwinContext, CookieName);
                AuthenticationTicket ticket        = ticketDataFormat.Unprotect(cookie);
                if (ticket.Properties.Dictionary != null)
                {
                    ticket.Properties.Dictionary[OpenIdConnectAuthenticationDefaults.AuthenticationType + "SingleSignOut"] = "";
                }
                cookieManager.AppendResponseCookie(notification.OwinContext, CookieName, ticketDataFormat.Protect(ticket), new CookieOptions());

                Claim existingUserObjectId = notification.OwinContext.Authentication.User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier");
                Claim incomingUserObjectId = notification.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier");

                if (existingUserObjectId.Value != null && incomingUserObjectId != null)
                {
                    // If a different user is logged into AAD
                    if (existingUserObjectId.Value != incomingUserObjectId.Value)
                    {
                        // No need to clear the session state here. It has already been
                        // updated with the new user's session state in SecurityTokenValidated.
                        notification.Response.Redirect("Account/SingleSignOut");
                        notification.HandleResponse();
                    }
                    // If the same user is logged into AAD
                    else if (existingUserObjectId.Value == incomingUserObjectId.Value)
                    {
                        // No need to clear the session state, SecurityTokenValidated will do so.
                        // Simply redirect the iframe to a page other than SingleSignOut to reset
                        // the timer in the javascript.
                        notification.Response.Redirect("/");
                        notification.HandleResponse();
                    }
                }
            }

            return(Task.FromResult <object>(null));
        }
Exemple #5
0
        public IDictionary <string, object> LoadTempData(HttpContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (context.Request.Cookies.ContainsKey(CookieName))
            {
                var encodedValue = _chunkingCookieManager.GetRequestCookie(context, CookieName);
                if (!string.IsNullOrEmpty(encodedValue))
                {
                    var protectedData   = Base64UrlTextEncoder.Decode(encodedValue);
                    var unprotectedData = _dataProtector.Unprotect(protectedData);
                    return(_tempDataSerializer.Deserialize(unprotectedData));
                }
            }

            return(new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase));
        }
Exemple #6
0
        public IActionResult DecryptCookie()
        {
            var cookieManager = new ChunkingCookieManager();
            var cookie        = cookieManager.GetRequestCookie(HttpContext, ".AspNetCore.Identity.Application");

            var dataProtector = _protector.CreateProtector("Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", "Identity.Application", "v2");

            //Get the decrypted cookie as plain text
            UTF8Encoding specialUtf8Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
            var          protectedBytes      = Base64UrlTextEncoder.Decode(cookie);

            var plainBytes = dataProtector.Unprotect(protectedBytes);
            var plainText  = specialUtf8Encoding.GetString(plainBytes);


            //Get teh decrypted cookies as a Authentication Ticket
            var ticketDataFormat = new TicketDataFormat(dataProtector);
            var ticket           = ticketDataFormat.Unprotect(cookie);

            return(View(new CookieDetails(plainText, ticket)));
        }
        /// <summary>
        /// Gets the reassembled cookie using chunkingCookieManager.
        /// </summary>
        /// <param name="cookieName">The cookie to get. If null, default cookieName in app.config will be used</param>
        /// <returns>The value of the cookie or an empty string</returns>
        public string GetCookie(string cookieName)
        {
            try
            {
                string cookie = string.Empty;
                string key    = String.IsNullOrEmpty(cookieName) ? _cookieName : cookieName;

                IHttpContextAccessor currentContextAccessor = _serviceProvider.GetInstance <IHttpContextAccessor>();
                if ((currentContextAccessor != null) && (currentContextAccessor.HttpContext != null))
                {
                    cookie = _chunkingCookieManager.GetRequestCookie(currentContextAccessor.HttpContext, key);
                }

                return(cookie);
            }
            catch (Exception ex)
            {
                string setBreakPointHere = ex.Message;
                return(String.Empty);
            }
        }
        public IActionResult DecryptCookie()
        {
            //var cookieValue = HttpContext.Request.Cookies[".AspNetCore.CookiesC1"];

            var cookieManager = new ChunkingCookieManager();
            var cookieValue   = cookieManager.GetRequestCookie(HttpContext, ".AspNetCore.Cookies");


            //Get a data protector to use with either approach
            var dataProtector = _provider.CreateProtector("Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", "Cookies", "v2");


            //Get the decrypted cookie as plain text
            UTF8Encoding specialUtf8Encoding = new UTF8Encoding();

            byte[] protectedBytes = Base64UrlTextEncoder.Decode(cookieValue);
            byte[] plainBytes     = dataProtector.Unprotect(protectedBytes);
            string plainText      = Encoding.UTF8.GetString(plainBytes).ToString();


            return(View());
        }
Exemple #9
0
        private byte[] GetOrCreateSessionId(IDotvvmRequestContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            var sessionIdCookieName = GetSessionIdCookieName(context);

            if (string.IsNullOrWhiteSpace(sessionIdCookieName))
            {
                throw new FormatException("Configured SessionIdCookieName is missing or empty.");
            }

            // Get cookie manager
            var mgr = new ChunkingCookieManager(); // TODO: Make this configurable

            // Get application key helper
            var keyHelper = new ApplicationKeyHelper(context.Configuration.Security);

            // Get cookie value
            var sidCookieValue = mgr.GetRequestCookie(context.OwinContext, sessionIdCookieName);

            if (string.IsNullOrWhiteSpace(sidCookieValue))
            {
                // No SID - generate and protect new one
                var rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
                var sid = new byte[SID_LENGTH];
                rng.GetBytes(sid);
                var protectedSid = keyHelper.ProtectData(sid, KDF_LABEL_SID);

                // Save to cookie
                sidCookieValue = Convert.ToBase64String(protectedSid);
                mgr.AppendResponseCookie(
                    context.OwinContext,
                    sessionIdCookieName, // Configured cookie name
                    sidCookieValue,      // Base64-encoded SID value
                    new Microsoft.Owin.CookieOptions
                {
                    HttpOnly = true,                                    // Don't allow client script access
                    Secure   = context.OwinContext.Request.IsSecure     // If request goes trough HTTPS, mark as secure only
                });

                // Return newly generated SID
                return(sid);
            }
            else
            {
                // Try to read from cookie
                try
                {
                    var protectedSid = Convert.FromBase64String(sidCookieValue);
                    var sid          = keyHelper.UnprotectData(protectedSid, KDF_LABEL_SID);
                    return(sid);
                }
                catch (Exception ex)
                {
                    // Incorrect Base64 formatting of crypto protection error
                    throw new SecurityException("Value of the SessionID cookie is corrupted or has been tampered with.", ex);
                }
            }
        }
Exemple #10
0
        private byte[] GetOrCreateSessionId(IDotvvmRequestContext context, bool canGenerate = true)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            var sessionIdCookieName = GetSessionIdCookieName(context);

            if (string.IsNullOrWhiteSpace(sessionIdCookieName))
            {
                throw new FormatException("Configured SessionIdCookieName is missing or empty.");
            }

            // Get cookie manager
            var mgr = new ChunkingCookieManager(); // TODO: Make this configurable

            // Construct protector with purposes
            var userIdentity    = ProtectionHelpers.GetUserIdentity(context);
            var requestIdentity = ProtectionHelpers.GetRequestIdentity(context);
            var protector       = this.protectionProvider.Create(PURPOSE_SID);

            // Get cookie value
            var sidCookieValue = mgr.GetRequestCookie(context.GetOwinContext(), sessionIdCookieName);

            if (!string.IsNullOrWhiteSpace(sidCookieValue))
            {
                // Try to read from cookie
                try
                {
                    var protectedSid = Convert.FromBase64String(sidCookieValue);
                    var sid          = protector.Unprotect(protectedSid);
                    return(sid);
                }
                catch (Exception ex)
                {
                    // Incorrect Base64 formatting of crypto protection error
                    // Generate new one or thow error if can't
                    if (!canGenerate)
                    {
                        throw new SecurityException("Value of the SessionID cookie is corrupted or has been tampered with.", ex);
                    }
                    // else suppress error and generate new SID
                }
            }

            // No SID - generate and protect new one

            if (canGenerate)
            {
                var rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
                var sid = new byte[SID_LENGTH];
                rng.GetBytes(sid);
                var protectedSid = protector.Protect(sid);

                // Save to cookie
                sidCookieValue = Convert.ToBase64String(protectedSid);
                mgr.AppendResponseCookie(
                    context.GetOwinContext(),
                    sessionIdCookieName,                                // Configured cookie name
                    sidCookieValue,                                     // Base64-encoded SID value
                    new Microsoft.Owin.CookieOptions
                {
                    HttpOnly = true,                                   // Don't allow client script access
                    Secure   = context.HttpContext.Request.IsHttps     // If request goes trough HTTPS, mark as secure only
                });

                // Return newly generated SID
                return(sid);
            }
            else
            {
                throw new SecurityException("SessionID cookie is missing, so can't verify CSRF token.");
            }
        }
Exemple #11
0
 public string GetRequestCookie(IOwinContext context, string key)
 {
     return(_chunkingCookieManager.GetRequestCookie(context, key));
 }
 public string GetRequestCookie(HttpContext context, string key)
 {
     return(_cookieManager.GetRequestCookie(context, key));
 }