diff --git a/config-templates/config.php b/config-templates/config.php
index 461a9f0c1799f93db02938e3306d87b7f691c0ea..e95e60ab7236b2803304875dd5bc6866d37837b3 100644
--- a/config-templates/config.php
+++ b/config-templates/config.php
@@ -169,6 +169,10 @@ $config = array (
 	 */
 	'session.datastore.timeout' => (4*60*60), // 4 hours
 	
+	/*
+	 * Option to override the default settings for the session cookie name
+	 */
+	'session.cookie.name' => NULL,
 
 	/*
 	 * Expiration time for the session cookie, in seconds.
@@ -209,6 +213,19 @@ $config = array (
 	 */
 	'session.cookie.secure' => FALSE,
 
+	/*
+	 * Enable secure POST from HTTPS to HTTP.
+	 *
+	 * If you have some SP's on HTTP and IdP is normally on HTTPS, this option
+	 * enables secure POSTing to HTTP endpoint without warning from browser.
+	 *
+	 * For this to work, module.php/core/postredirect.php must be accessible
+	 * also via HTTP on IdP, e.g. if your IdP is on
+	 * https://idp.example.org/ssp/, then
+	 * http://idp.example.org/ssp/module.php/core/postredirect.php must be accessible.
+	 */
+	'enable.http_post' => FALSE,
+
 	/*
 	 * Options to override the default settings for php sessions.
 	 */
diff --git a/lib/SimpleSAML/SessionHandlerCookie.php b/lib/SimpleSAML/SessionHandlerCookie.php
index 0aca668a598d72dd5abd6f2fbe930368fde33dd0..f69d060b18879d1d5fd7c8cf0aa7ea06b0b1f4b6 100644
--- a/lib/SimpleSAML/SessionHandlerCookie.php
+++ b/lib/SimpleSAML/SessionHandlerCookie.php
@@ -17,9 +17,12 @@ abstract class SimpleSAML_SessionHandlerCookie
 extends SimpleSAML_SessionHandler {
 
 	/* This variable contains the current session id. */
-	protected $session_id = NULL;
+	private $session_id = NULL;
 
 
+	/* This variable contains the session cookie name. */
+	protected $cookie_name;
+
 
 	/* This constructor initializes the session id based on what
 	 * we receive in a cookie. We create a new session id and set
@@ -31,27 +34,8 @@ extends SimpleSAML_SessionHandler {
 		 */
 		parent::__construct();
 
-		/* Attempt to retrieve the session id from the cookie. */
-		if(array_key_exists('SimpleSAMLSessionID', $_COOKIE)) {
-			$this->session_id = $_COOKIE['SimpleSAMLSessionID'];
-		}
-
-		/* We need to create a new session. */
-
-		if (headers_sent()) {
-			throw new SimpleSAML_Error_Exception('Cannot create new session - headers already sent.');
-		}
-
-		/* Check if we have a valid session id. */
-		if(self::isValidSessionID($this->session_id)) {
-			/* We are done now if it was valid. */
-			return;
-		}
-
-		/* We don't have a valid session. Create a new session id. */
-		$this->session_id = self::createSessionID();
-
-		$this->setCookie('SimpleSAMLSessionID', $this->session_id);
+		$config = SimpleSAML_Configuration::getInstance();
+		$this->cookie_name = $config->getString('session.cookie.name', 'SimpleSAMLSessionID');
 	}
 
 
@@ -61,6 +45,21 @@ extends SimpleSAML_SessionHandler {
 	 * @return string  The session id saved in the cookie.
 	 */
 	public function getCookieSessionId() {
+		if ($this->session_id === NULL) {
+			if(self::hasSessionCookie()) {
+				/* Attempt to retrieve the session id from the cookie. */
+				$this->session_id = $_COOKIE[$this->cookie_name];
+			}
+
+			/* Check if we have a valid session id. */
+			if(!self::isValidSessionID($this->session_id)) {
+				/* We don't have a valid session. Create a new session id. */
+				$this->session_id = self::createSessionID();
+			}
+
+			$this->setCookie($this->cookie_name, $this->session_id);
+		}
+
 		return $this->session_id;
 	}
 
@@ -112,7 +111,7 @@ extends SimpleSAML_SessionHandler {
 	 */
 	public function hasSessionCookie() {
 
-		return array_key_exists('SimpleSAMLSessionID', $_COOKIE);
+		return array_key_exists($this->cookie_name, $_COOKIE);
 	}
 
 }
diff --git a/lib/SimpleSAML/SessionHandlerPHP.php b/lib/SimpleSAML/SessionHandlerPHP.php
index c6c029ef06a057741a3f3d52a9dc8aec20f870e7..02188aecadf7efd93fb3784e43fb9db800a21ec6 100644
--- a/lib/SimpleSAML/SessionHandlerPHP.php
+++ b/lib/SimpleSAML/SessionHandlerPHP.php
@@ -49,8 +49,24 @@ class SimpleSAML_SessionHandlerPHP extends SimpleSAML_SessionHandler {
 			if(!empty($savepath)) {
 				session_save_path($savepath);
 			}
+		}
+	}
+
+
+	/**
+	 * Retrieve the session id of saved in the session cookie.
+	 *
+	 * @return string  The session id saved in the cookie.
+	 */
+	public function getCookieSessionId() {
+		if(session_id() === '') {
+			$session_cookie_params = session_get_cookie_params();
+
+			if ($session_cookie_params['secure'] && !SimpleSAML_Utilities::isHTTPS()) {
+				throw new SimpleSAML_Error_Exception('Session start with secure cookie not allowed on http.');
+			}
 
-			if(!array_key_exists(session_name(), $_COOKIE)) {
+			if(!self::hasSessionCookie()) {
 
 				if (headers_sent()) {
 					throw new SimpleSAML_Error_Exception('Cannot create new session - headers already sent.');
@@ -62,15 +78,7 @@ class SimpleSAML_SessionHandlerPHP extends SimpleSAML_SessionHandler {
 			
 			session_start();
 		}
-	}
-
 
-	/**
-	 * Retrieve the session id of saved in the session cookie.
-	 *
-	 * @return string  The session id saved in the cookie.
-	 */
-	public function getCookieSessionId() {
 		return session_id();
 	}
 
@@ -95,8 +103,21 @@ class SimpleSAML_SessionHandlerPHP extends SimpleSAML_SessionHandler {
 	public function loadSession($sessionId = NULL) {
 		assert('is_string($sessionId) || is_null($sessionId)');
 
-		if ($sessionId !== NULL && $sessionId !== session_id()) {
-			throw new SimpleSAML_Error_Exception('Cannot load PHP session with a specific ID.');
+		if ($sessionId !== NULL) {
+			if (session_id() === '') {
+				/* session not initiated with getCookieSessionId(), start session without setting cookie */
+				$ret = ini_set('session.use_cookies', '0');
+				if ($ret === FALSE) {
+					throw new SimpleSAML_Error_Exception('Disabling PHP option session.use_cookies failed.');
+				}
+
+				session_id($sessionId);
+				session_start();
+			} elseif ($sessionId !== session_id()) {
+				throw new SimpleSAML_Error_Exception('Cannot load PHP session with a specific ID.');
+			}
+		} elseif (session_id() === '') {
+			$sessionId = self::getCookieSessionId();
 		}
 
 		if (!isset($_SESSION['SimpleSAMLphp_SESSION'])) {
diff --git a/lib/SimpleSAML/SessionHandlerStore.php b/lib/SimpleSAML/SessionHandlerStore.php
index 81be78ddcf5e86a1d4e48dcae5590c3cfd16a76c..cd01a5adf81bd025f56f9cb48c5b06dd2a03acaf 100644
--- a/lib/SimpleSAML/SessionHandlerStore.php
+++ b/lib/SimpleSAML/SessionHandlerStore.php
@@ -33,7 +33,7 @@ class SimpleSAML_SessionHandlerStore extends SimpleSAML_SessionHandlerCookie {
 		assert('is_string($sessionId) || is_null($sessionId)');
 
 		if ($sessionId === NULL) {
-			$sessionId = $this->session_id;
+			$sessionId = $this->getCookieSessionId();
 		}
 
 		$session = $this->store->get('session', $sessionId);
@@ -47,7 +47,7 @@ class SimpleSAML_SessionHandlerStore extends SimpleSAML_SessionHandlerCookie {
 		}
 
 		/* For backwards compatibility, check the MemcacheStore object. */
-		$store = SimpleSAML_MemcacheStore::find($this->session_id);
+		$store = SimpleSAML_MemcacheStore::find($sessionId);
 		if ($store === NULL) {
 			return NULL;
 		}
diff --git a/lib/SimpleSAML/Utilities.php b/lib/SimpleSAML/Utilities.php
index 5a38cd60bf992d36f7ccedeb427917e26d54488e..b633c2e0dd3ff64095d896f9d3f48f9a68070b85 100644
--- a/lib/SimpleSAML/Utilities.php
+++ b/lib/SimpleSAML/Utilities.php
@@ -1606,6 +1606,13 @@ class SimpleSAML_Utilities {
 		assert('is_array($post)');
 
 		$config = SimpleSAML_Configuration::getInstance();
+		$httpRedirect = $config->getBoolean('enable.http_post', FALSE);
+
+		if ($httpRedirect && preg_match("#^http:#", $destination) && self::isHTTPS()) {
+			$url = self::createHttpPostRedirectLink($destination, $post);
+			self::redirect($url);
+			assert('FALSE');
+		}
 
 		$p = new SimpleSAML_XHTML_Template($config, 'post.php');
 		$p->data['destination'] = $destination;
@@ -1625,16 +1632,54 @@ class SimpleSAML_Utilities {
 		assert('is_string($destination)');
 		assert('is_array($post)');
 
-		$id = SimpleSAML_Utilities::generateID();
+		$config = SimpleSAML_Configuration::getInstance();
+		$httpRedirect = $config->getBoolean('enable.http_post', FALSE);
+
+		if ($httpRedirect && preg_match("#^http:#", $destination) && self::isHTTPS()) {
+			$url = self::createHttpPostRedirectLink($destination, $post);
+		} else {
+			$postId = SimpleSAML_Utilities::generateID();
+			$postData = array(
+				'post' => $post,
+				'url' => $destination,
+			);
+
+			$session = SimpleSAML_Session::getInstance();
+			$session->setData('core_postdatalink', $postId, $postData);
+
+			$url = SimpleSAML_Module::getModuleURL('core/postredirect.php', array('RedirId' => $postId));
+		}
+
+		return $url;
+	}
+
+
+	/**
+	 * Create a link which will POST data to HTTP in a secure way.
+	 *
+	 * @param string $destination  The destination URL.
+	 * @param array $post  The name-value pairs which will be posted to the destination.
+	 * @return string  An URL which can be accessed to post the data.
+	 */
+	public static function createHttpPostRedirectLink($destination, $post) {
+		assert('is_string($destination)');
+		assert('is_array($post)');
+
+		$postId = SimpleSAML_Utilities::generateID();
 		$postData = array(
 			'post' => $post,
 			'url' => $destination,
 		);
 
 		$session = SimpleSAML_Session::getInstance();
-		$session->setData('core_postdatalink', $id, $postData);
+		$session->setData('core_postdatalink', $postId, $postData);
+
+		$redirInfo = base64_encode(self::aesEncrypt($session->getSessionId() . ':' . $postId));
+
+		$url = SimpleSAML_Module::getModuleURL('core/postredirect.php', array('RedirInfo' => $redirInfo));
+		$url = preg_replace("#^https:#", "http:", $url);
 
-		return SimpleSAML_Module::getModuleURL('core/postredirect.php', array('RedirId' => $id));
+		return $url;
 	}
 
 
@@ -2060,4 +2105,75 @@ class SimpleSAML_Utilities {
 		return $data;
 	}
 
+
+	/**
+	 * Function to AES encrypt data.
+	 *
+	 * @param string $clear  Data to encrypt.
+	 * @return array  The encrypted data and IV.
+	 */
+	public static function aesEncrypt($clear) {
+		assert('is_string($clear)');
+
+		if (!function_exists("mcrypt_encrypt")) {
+			throw new Exception("aesEncrypt needs mcrypt php module.");
+		}
+
+		$enc = MCRYPT_RIJNDAEL_256;
+		$mode = MCRYPT_MODE_CBC;
+
+		$blockSize = mcrypt_get_block_size($enc, $mode);
+		$ivSize = mcrypt_get_iv_size($enc, $mode);
+		$keySize = mcrypt_get_key_size($enc, $mode);
+
+		$key = hash('sha256', self::getSecretSalt(), TRUE);
+		$key = substr($key, 0, $keySize);
+
+		$len = strlen($clear);
+		$numpad = $blockSize - ($len % $blockSize);
+		$clear = str_pad($clear, $len + $numpad, chr($numpad));
+
+		$iv = self::generateRandomBytes($ivSize);
+
+		$data = mcrypt_encrypt($enc, $key, $clear, $mode, $iv);
+
+		return $iv . $data;
+	}
+
+
+	/**
+	 * Function to AES decrypt data.
+	 *
+	 * @param $data  Encrypted data.
+	 * @param $iv  IV of encrypted data.
+	 * @return string  The decrypted data.
+	 */
+	public static function aesDecrypt($encData) {
+		assert('is_string($encData)');
+
+		if (!function_exists("mcrypt_encrypt")) {
+			throw new Exception("aesDecrypt needs mcrypt php module.");
+		}
+
+		$enc = MCRYPT_RIJNDAEL_256;
+		$mode = MCRYPT_MODE_CBC;
+
+		$ivSize = mcrypt_get_iv_size($enc, $mode);
+		$keySize = mcrypt_get_key_size($enc, $mode);
+
+		$key = hash('sha256', self::getSecretSalt(), TRUE);
+		$key = substr($key, 0, $keySize);
+
+		$iv = substr($encData, 0, $ivSize);
+		$data = substr($encData, $ivSize);
+
+		$clear = mcrypt_decrypt($enc, $key, $data, $mode, $iv);
+
+		$len = strlen($clear);
+		$numpad = ord($clear[$len - 1]);
+		$clear = substr($clear, 0, $len - $numpad);
+
+		return $clear;
+	}
+
 }
diff --git a/modules/core/www/postredirect.php b/modules/core/www/postredirect.php
index 408fe554e65682e339af3120db0f34a5c81eaa7b..fd9bef458ebedf22dcd1b78badbf3884e8e837a3 100644
--- a/modules/core/www/postredirect.php
+++ b/modules/core/www/postredirect.php
@@ -7,26 +7,49 @@
  * @version $Id$
  */
 
-if (!array_key_exists('RedirId', $_REQUEST)) {
-	throw new SimpleSAML_Error_BadRequest('Missing RedirId parameter.');
+if (array_key_exists('RedirId', $_REQUEST)) {
+	$postId = $_REQUEST['RedirId'];
+	$session = SimpleSAML_Session::getInstance();
+} elseif (array_key_exists('RedirInfo', $_REQUEST)) {
+	$encData = base64_decode($_REQUEST['RedirInfo']);
+
+	if (empty($encData)) {
+		throw new SimpleSAML_Error_BadRequest('Invalid RedirInfo data.');
+	}
+
+	list($sessionId, $postId) = explode(':', SimpleSAML_Utilities::aesDecrypt($encData));
+
+	if (empty($sessionId) || empty($postId)) {
+		throw new SimpleSAML_Error_BadRequest('Invalid session info data.');
+	}
+
+	$session = SimpleSAML_Session::getSession($sessionId);
+} else {
+	throw new SimpleSAML_Error_BadRequest('Missing redirection info parameter.');
 }
 
-$id = $_REQUEST['RedirId'];
+if ($session === NULL) {
+	throw new Exception('Unable to load session.');
+}
 
-$session = SimpleSAML_Session::getInstance();
-$postData = $session->getData('core_postdatalink', $id);
+$postData = $session->getData('core_postdatalink', $postId);
 
 if ($postData === NULL) {
 	/* The post data is missing, probably because it timed out. */
 	throw new Exception('The POST data we should restore was lost.');
 }
+
+$session->deleteData('core_postdatalink', $postId);
+
 assert('is_array($postData)');
 assert('array_key_exists("url", $postData)');
 assert('array_key_exists("post", $postData)');
 
-$url = $postData['url'];
-$post = $postData['post'];
-
-SimpleSAML_Utilities::postRedirect($url, $post);
+$config = SimpleSAML_Configuration::getInstance();
+$p = new SimpleSAML_XHTML_Template($config, 'post.php');
+$p->data['destination'] = $postData['url'];
+$p->data['post'] = $postData['post'];
+$p->show();
+exit(0);
 
 ?>
\ No newline at end of file