Background
When the ItemResolver
processor executes, it determines the context item for the request based on the current URL. Additionally, it also performs a security check to see if the current user can access that item. If they can't, the context item is cleared and a PermissionDenied
property on HttpRequestArgs
is set to true
.
When the ExecuteRequest
processor executes, the PermissionDenied
property is inspected and this is where Sitecore decides to redirect the user to the login page if one has been specified for the site. It does not determine if the user is already logged in or not when doing so, hence your problem.
Solution
You can achieve what you want by adding a pipeline step in-between the ItemResolver
and ExecuteRequest
processors in the httpRequestBegin
pipeline:
public class PermissionDeniedResolver : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
Assert.ArgumentNotNull((object) args, "args");
if (args.PermissionDenied && UserIsLoggedIn(Sitecore.Context.User)
{
// Redirect to your permission denied page here
}
}
private bool UserIsLoggedIn(Account user)
{
// Perform your logged in test here, e.g:
return user.IsAuthenticated;
}
}
This can then be patched to execute after the Item resolver:
<processor type="MyProject.Pipelines.HttpRequest.PermissionDeniedResolver, MyProject"
patch:after="*[@type='Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel']"/>