My own approach to this issue is a derived base-class from CController for my application’s controllers, and adding a property that allows each controller to specify whether it needs SSL or not:
/**
 * Base class for all controllers in the application
 */
class Controller extends CController
{
  /**
   * @var mixed if true, SSL is required - if false, SSL is not allowed - if null, both are acceptable
   */
  public $https = false;
  
  /**
   * Integrate GAuthorizationFilter
   */
  public function filters()
  {
    return array(
      array('GSchemaFilter', 'https'=>$this->https),
    );
  }
}
/**
 * This filter enforces HTTP or HTTPS protocol for the request, by aborting and redirecting
 * the request to the same URL, but with the correct protocol specifier applied.
 *
 * You can globally bypass this filter using define('NO_SSL', true) in your configuration
 * file - this is useful while developing/testing on a machine that does not have an SSL
 * certificate installed.
 */
class GSchemaFilter extends CFilter
{
  /**
   * @var mixed if true, SSL is required - if false, SSL is not allowed - if null, both are allowed
   */
  public $https=null;
  
  /**
   * Apply schema-based filtering
   */
  public function preFilter($filterChain)
  {
    if (defined('NO_SSL') && NO_SSL)
      return true;
    
    if ($this->https===false)
      $this->requireSchema('http');
    if ($this->https===true)
      $this->requireSchema('https');
    
    return true;
  }
  
  /**
   * Aborts the request, redirects and switches schema, if required.
   *
   * @param string the required schema for this request, e.g. 'http' or 'https'
   */
  protected function requireSchema($schema)
  {
    $secure = Yii::app()->getRequest()->getIsSecureConnection();
    
    $c = Yii::app()->getController();
    
    if (($schema==='http' && $secure) || ($schema==='https' && !$secure))
      $c->redirect($c->createAbsoluteUrl('', $_GET, $schema), true);
  }
}
This will automatically redirect and switch protocols as required by your controllers - so for example, your login or checkout controller in a store might have $https=true which would prevent them from loading insecurely on the server-side. I like this approach better than trying to make sure the URLs are correct.
Note that HTTP POST from a secure to a non-secure page (or vice-versa) will not work. This is by design, since this would cause a warning in most browsers anyway. And typically this doesn’t cause any problems, as this setting is per-controller. In other words, the first time you hit CheckoutController::actionIndex() it’ll redirect to switch to SSL - and if you go back to ProductController::actionIndex() it’ll redirect to switch it off again.
I’m using this on several live sites for some years now, and it works well 
For local development/testing without an SSL certificate, define(‘NO_SSL’,true) will disable this filter.