Here’s the problem. We have a legacy application (or a WordPress blog for the example) and we want to protect the access to the application according to our corporate single sign on. We can create a plug-in in WordPress to ensure only our single sign-on’s session cookie is activated.
With WordPress we can create a simple plug-in to perform our desired behaviour:
<?php // wp-content/plugins/gamAuth.php /** * @package gamAuth * @version 1.0.0 */ /* Plugin Name: gamAuth Plugin URI: # Description: Forces users to be authenticated Author: Gonzalo Ayuso Version: 1.0.0 Author URI: gonzalo122.wordpress.com */ function redirectExit() {; nocache_headers(); header("HTTP/1.1 302 Moved Temporarily"); header("Location: http://www.google.com"); header("Status: 302 Moved Temporarily"); exit(); } function chechAuth() { // here we check our session } function ac_auth_redirect() { if (!chechAuth()) redirectExit(); } if('wp-login.php' != $pagenow && 'wp-register.php' != $pagenow) { add_action('template_redirect', 'ac_auth_redirect'); }
This plug-in works, but what happen with the uploaded files? If we upload a PNG file and we show it in our post, our WordPress will create a direct link to the uploaded file in wp-content/uploads folder. That’s means if a non-authenticated user knows the url of the link, he will see the picture, because our simple plug-in does not affect to direct links. OK WordPress is open source. We can change the code and change the behaviour of link generation. Maybe there’s a plugin to do it (don’t hesitate on explain it to me, anyway) but if we don’t want to touch the WordPress code or maybe we cannot do it (because it’s a legacy application), here we are a simple trick to force authorization even over files within public folders, without change any line of the original application.
The trick is very simple. First we activate mod_rewrite in our server and create a .htaccess files in our wp-content/uploads folder:
An example with apache:
RewriteEngine on RewriteBase / RewriteRule !\.(php)$ /wordpress/wp-content/uploads/media.php
That’s means we are going to redirect every file request within or upload folder to a PHP script called media.php
And now our media.php will check the authorization.
<?php $uri = $_SERVER['REQUEST_URI']; $documentRoot = $_SERVER['DOCUMENT_ROOT']; $filename = $documentRoot . $uri; $pathParts = pathinfo($filename); $mime = array( 'jpe' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'jpg' => 'image/jpeg', 'png' => 'image/png', 'xls' => 'application/vnd.ms-excel', 'pdf' => 'application/pdf', ); function chechAuth() { // here we check our session } $ext = strtolower($pathParts['extension']); // there are built-in ways to check file mime type but // they don't work fine, at least for me and I preffer to // check it manually with the extension if (is_file($filename) && array_key_exists($ext, $mime)) { if (chechAuth()) { header("Content-Type: " . $mime[$ext]); readfile($filename); exit(); } } echo "HTTP/1.1 503 Service Unavailable"; header('HTTP/1.1 503 Service Unavailable', true, 503);
If you want to show big files such as video files, maybe you need to have a look to one of my older posts.