The problem: My Drupal installation was configured so Anonymous users cannot access content; they have to log in first. However, on the login page, the anon-user was presented with the message "Access denied. You are not authorized to access this page."

Looking into module resources for solutions, I found proposals related to taxonomy, a front-page module, etc., and upon further investigation and use, the implementations of these solutions struck me as convoluted and a bit more complicated than it actually needed to be.

Solution:Digging further into the login process, I discovered the include file for that process and the function responsible for producing the HTTP 403 error which results in the message being produced.

The file is common.inc and is located in \htdocs\<drupal_install_dir>\includes under the Apache directory. In my version of Drupal (6.19) the function is located beginning at line 394. This is the section of the function which issues the message:

  if (empty($return) || $return == MENU_NOT_FOUND || $return == MENU_ACCESS_DENIED) {
   
      	drupal_set_title(t('Access denied'));   
    	$return = t('You are not authorized to access this page.');

    };

This check for a valid menu or denial of access to a menu doesn't go far enough to determine if the message should be issued at the login page. To get the desired behavior, I modified it so that it does not show the message if the user is being presented with the front page ( if ($_REQUEST['destination'] != 'node/1' ) { ). Furthermore, if the user was at the login page, the title needed to be set so that it was positioned closer to the top of the page. A block couldn't do this.

The full solution employed in this function is shown below.

/**
 * Generates a 403 error if the request is not allowed.
 */
function drupal_access_denied() {
  drupal_set_header('HTTP/1.1 403 Forbidden');

  watchdog('access denied', check_plain($_GET['q']), NULL, WATCHDOG_WARNING);

  // Keep old path for reference, and to allow forms to redirect to it.
  if (!isset($_REQUEST['destination'])) {
    $_REQUEST['destination'] = $_GET['q'];
  }

  $path = drupal_get_normal_path(variable_get('site_403', ''));
  if ($path && $path != $_GET['q']) {
    // Set the active item in case there are tabs to display or other
    // dependencies on the path.
    menu_set_active_item($path);
    $return = menu_execute_active_handler($path);
  }

  if (empty($return) || $return == MENU_NOT_FOUND || $return == MENU_ACCESS_DENIED) {
   
    if ($_REQUEST['destination'] != 'node/1' )  {
        drupal_set_title(t('Access denied'));  
        $return = t('You are not authorized to access this page.');
    } else {
        drupal_set_title(t('Welcome !'));
        //drupal_set_message(  t(' '), 'status');
        $return = t('  ');
    };
  
  }
  print theme('page', $return);
}

This simple change provides the desired behavior. The user wishing to log in is not presented with the offending message before given the chance to enter his/her user id and password, and is instead greeted with a "Welcome !" message. A block visible only to anon-users was added to the page which contains the instructions to enter user id and password. After log in validation completes another block visible only to authenticated users is presented on the front page which shows initial content for that page.

Be aware that I have not tested for the reassignment of a new front page; I don't know if the new front page will be assigned to node/1 or to another node. In the latter event, the code will have to be modified to reflect the new node id. In addition, the code could benefit by also checking the $user object to determine if it is an anon-user. For now, I'm satisfied with the effect and am free to move on to more pressing issues.

-buster529

Comments

manarth’s picture

Page access control is governed by the access callback in hook_menu.

For user/login, this is:

 $items['user/login'] = array(
    'title' => 'Log in',
    'access callback' => 'user_is_anonymous',
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );

In other words, user/login is always accessible to anonymous users (in Drupal core). If that's not working in your installation, I'd look to see which 3rd-party module has stopped this working.