I am having an interesting issue. Anonymous users do not have access content privileges. I would like to set up a nicer access denied page, but when I create a customer node with the desired message and set it in administer -> settings, the anonymous users don't see it. They still see the generic access denied page. I'm guessing because the custom access denied page is content, which they don't have access to? How do I get them to see my custom access denied page?

Comments

ajzeneski’s picture

I'm new the Drupal, and using 4.6.5. I too would like to create a custom access denied page. One which at the very least prompts the user to login/create an account. Where do I find information on customizing this?

anner’s picture

well, you're supposed to be able to create a node and change the access denied (403) error page to that node (in administer -> settings), but it's not working for me.

anner’s picture

anyone? I'm sure it's something basic I'm missing.

Ella-1’s picture

Create a customised access denied page or even just change that line of text, mentioning that users need to log on, rather than just saying they are not authorised.

I tried creating a node and changing the 403 error on the admin>settings page but this did not work, my access denied message just disappeared entirely.

Anyone?

TIA

Wolfflow’s picture

A simple solution you may find at

http://drupal.org/node/87614

of course it's not a nice style solution but it works !!

Drupal User with some test Drupal show cases:
http://www.adaccs.at/test/ Link to a DRUPAL 5 Beta 1 Showcase Site

Contact me for drupal projects in English, German, Italian, Drupal Hosting Support.

klance’s picture

I set up my site using Drupal 4.7.0 back in June 2006, and now it's November and we're at 4.7.4 and 5.0 beta is out. So I'm not big on modifying Drupal core code and tracking and porting all of my changes.

Guys, the presentation layer, PHPTemplate, is written in PHP! ;-) That means you get one last chance to muck with the output before it hits the screen.

So if you want to change the "Access denied" message, just do this in your page.tpl.php file BEFORE you print $title:

<?php

// change the default access denied message
if( $title == "Access denied" ) {
  $title = "Login required";
}

?>

<h1 id="title"><?php print $title ?></h1>

Now, one thing that I've seen a lot of people ask for is a way to customize the Access denied page to include a login prompt that actually redirects you back to the page once logged in. Again, don't think customize Drupal, think customize template. Most of the default templates I've seen contain a line like this, so I'll assume you have something like it in yours:

<?php print $content; ?>

Try replacing it with the following code:

<?php

if( $title == "Access denied" ) { // if you've modified the default message using the code above, replace it here as well
  print "<a href=\"/user?destination=" . substr( $_SERVER['REQUEST_URI'], 1 ) . "\"><b>Please click here to log in</b></a>";
} else {
  if( $content ) {
    print $content;
  }
}

?>

You can add anything you want in that print string--text, images, links, flash, whatever. You can even escape out of PHP with a ?> and create your custom Access denied page layout in html like this:

<?php

if( $title == "Access denied" ) { // if you've modified the default message using the code above, replace it here as well

?>

<image src="image.jpg" alt="Image" />
<a href="/user?destination="<?php print substr( $_SERVER['REQUEST_URI'], 1 ); ?>"><b>Please click here to log in</b></a>

<?php

} else {
  if( $content ) {
    print $content;
  }
}

?>

Using template modifications like this, you can run several sites off the same original Drupal codebase, and even have different Access denied pages on each one, which are defined in their respective templates.

kevinbock’s picture

If you only want the simple version, and don't want to force your users to click the login link, you can auto redirect them to the login page (which will then redirect them back) by adding this line of code as the FIRST line in your page.tpl.php file. It must come before any html code:

<?php if ($title == 'Access denied') { header( 'Location: /user?destination=' . substr ($_SERVER['REQUEST_URI'],1 ) ); } ?>
jacobson’s picture

This is a great solution. Thanks. Only issue I had was that the redirect was going to the root site on my server instead of the subdomain.

HAJ

hintbw’s picture

If you remove the / slash at the start of kevinbock's suggested URL you should get the proper behavior you are expecting, rather than it redirecting to the root of the domain.

kevinbock’s picture

Whoops, we may also want to prevent an ugly loop... If you try to visit, say, /admin with that code while logged in as a user without admin privileges it'll redirect to /user which, because you're logged in, will redirect to /admin which will redirect /user, etc. At least, that's the behavior in my install of 5.1...

Change the IF to force this to apply only only to users who aren't logged in:

<?php global $user; if (!$user->uid && $title == 'Access denied') { header( 'Location: user?destination=' . substr($_SERVER['REQUEST_URI'],1) ); } ?>
jbear’s picture

The above works great if Drual is under /
For http://www.example.com/drupal_under_subdir, try this:

<?php global $user; if (!$user->uid && $title == 'Access denied') { header( 'Location: ?q=user&' . drupal_get_destination()' ); } ?>
prasoon gupta’s picture

I am still not able to change Access denied Page, m using Drupal 5 and its installed in a Directory and its path is like this http://www.creativeteensclub.org/ctc . I changed the

print $content

to

global $user; if (!$user->uid && $title == 'Access denied') { header( 'Location: /user?destination=' . substr($_SERVER['REQUEST_URI'],1) ); exit; }

I changed this is code in page.tpl.php file thats kept in my theme Directory.
Still there has been no change.

tklawsuc’s picture

If you are caching your pages you might want to add "exit;" after the header call. That way the page will not get cached with the "access denied" message. I am using http://drupal.org/project/boost and without the exit when I returned to the page as an anonymous user I got the access denied page because it got cached before the redirect to the login. FYI I also changed the code back to using an absolute path for login page in case someone copies it.

global $user; if (!$user->uid && $title == 'Access denied') { header( 'Location: /user?destination=' . substr($_SERVER['REQUEST_URI'],1) ); exit; }

BTW Thanks kevinbock for the original code and the loop catch!

scottrigby’s picture

Hi,
This worked great for the 'Access Denied' page. But now, whenever I add or edit any other page (node/add or node/edit), I get a strange line of text, and my layout is off below.

The text is this:

-- Content (disabled)---- Create content (disabled)------ Page------ Story------ Webform-- Administer---- Content management------ Categories------ Comments------ Content------ Content types------ Post settings------ RSS publishing------ Webforms---- Site building------ Blocks------ Menus------ Modules------ Themes---- Site configuration------ Administration theme------ Clean URLs------ Date and time------ Error reporting------ External links------ File system------ File uploads------ Image toolkit------ Input formats------ Performance------ Site information------ Site maintenance------ Webform---- User management------ Access control-------- Access control by taxonomy------ Access rules------ Roles------ Users------ User settings---- Logs------ Recent log entries------ Top 'access denied' errors------ Top 'page not found' errors------ Status report---- Help-- Log out Primary links

The layout issue looks as if a div is missing. Because half of the contact form pushes below the left navigation (and preview and submit button shows above that point).

Here's what I did:
1. I added this just before the title (including title here for context):

          <?php
          // This modifies access denied page. From: http://drupal.org/node/69007#comment-637218 (including comments above that one):
          // change the default access denied message
          if( $title == "Access denied" ) {
            $title = "Login required";
          }
   		  ?>
          <?php if (!empty($title)): ?><h1 class="title"><?php print $title; ?></h1><?php endif; ?>

Then I commented out <?php print $content ?> as suggested above. In it's place I added this (it's a combo of suggestions above:

          <!--<?php print $content; ?>-->
          <?php
		  // Continuation of above "modifies access denied page"
          if( $title == "Login required" ) { 
          // if you've modified the default message using the code above, 
          // replace it here as well
            print "<a href=\"/user?destination=" . substr($_SERVER['REQUEST_URI'],1) . "\"><b>Please click here to log in</b></a>";
            exit;
          } else {
            if( $content ) {
              print $content;
            }
          }
          ?>

This is the site's url: http://scottt.aharonic.net/

Any idea what I may be doing wrong?
Scott


Edit: I removed the commented-out $content area, and now seems ok. I'm leaving this post in case I'm still missing something, or in case this is helpful to someone else.

pamphile’s picture

This was fixe in Drupal 5.5 at least
See: admin/settings/error-reporting

Marcel
PrewrittenContent.com
Drupal Themes
Writing Schedule

prasoon gupta’s picture

I am still not able to change Access denied Page, m using Drupal 5 and its installed in a Directory and its path is like this http://www.creativeteensclub.org/ctc . I changed the

print $content

to

global $user; if (!$user->uid && $title == 'Access denied') { header( 'Location: /user?destination=' . substr($_SERVER['REQUEST_URI'],1) ); exit; }

I changed this is code in page.tpl.php file thats kept in my theme Directory.
Still there has been no change.

Jens Dill’s picture

I'm sorry to reopen an old thread, but the title refers exactly to what I want to talk about. And I've spent most of a day searching the archives for more current information without seeing anything better. This problem was reported in Drupal 4.6.x over five years ago, and is still a problem for me in Drupal 7.x.

I'm building my first "closed" Drupal site, where the content is supposed to be visible only to authenticated users. So it's very important that the view published content permission not be granted to anonymous users. So, when you navigate to the site, before you log in, you see the login block attached to the generic Access Deniedpage. You try to fill in a friendlier page by creating one and setting it up as the Default 403 (access denied) page, but it still doesn't show when you first navigate to the site because it's content, and anonymous viewers can't view published content. Yes, this is a rephrasing of the original problem statement, because, in five years and three major releases of Drupal, it hasn't been fixed.

Yes, there are lots of hacks and workarounds, including the ones in this thread. I've looked them over, and I could probably get one of them to work for me, but they still feel like hacks, and I'm seeking a cleaner solution. I could also play around with creating a special content type called "public page," and setting up permissions so that "public pages" are visible to anonymous users and everything else isn't. That's a lot of individual permission-flicking, and it makes the general view published content permission essentially useless.

My logic says the solution should fall along the following lines: If an anonymous user (or any other role) is to be denied permission to view published content, then the only content they are permitted to see is the page that tells them their access is being denied. That, to my mind, is the node declared as the Default 403 (access denied) page. So, by my logic, the Default 403 (access denied) page should be an exception to the denial of the view published content permission. Make sense?

It's hard to understand why this doesn't happen by default. It's not like there's no precedent: Both the login page and the Create new account page are accessible to anonymous users in the same circumstances. It might appear to create a security hole in the protection offered by the view published content permission, but that doesn't stand up to close scrutiny. If you don't have permission to see other content, you can't navigate from this one node to any other, and, although it is possible for this node itself to have poorly-coded content that contains a security loophole, that same risk is present on every bit of content presented to an anonymous user, including things that come from the theme and are displayed regardless of permissions.

So I'm left wondering why nobody seems to have followed this logical path to its logical conclusion. Am I missing something? Did somebody already create a module to do this? If so, where is it? If not, is there some good reason why not, one that I'm not aware of? If it's just that nobody's gotten around to it, I'll volunteer to create such a module, if someone will act as a mentor and steer me to the right part of the code.

deville’s picture

Diane Bryan’s picture

The issues queue for the customerror module shows that you have to hack into the code still to get it working for version 7. There is a patch, but I don't know from patches... so I'm still hunting, like the person above.