title: attribute asks user to login instead of access denied?
body: <p><strong>Updated:</strong> Thanks to the help here I've created the following solution:</p>
  
  <pre><code>public class CustomAuthorize : AuthorizeAttribute
  {
      protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
      {
          // Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs
          // If user is not logged in prompt
          if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
          {
              base.HandleUnauthorizedRequest(filterContext);
          }
          // Otherwise deny access
          else
          {
              filterContext.Result = new RedirectToRouteResult(
                  new RouteValueDictionary {
                  {"controller", "Account"},
                  {"action", "NotAuthorized"}
              });
          }
      }
  }
  </code></pre>
  
  <hr/>
  
  <p>I started from NerdDinner and am using FormsAuthentication with ActiveDirectory as my membership provider. I've added support for roles via my db with Global.asax &amp; AccountController (below).</p>
  
  <p>So now in my controller I have my Authorize attribute set to roles of admin only (below). My logged in user is an author. When I click delete it asks me to login even though I have already done so. Where can I put the logic to return an access denied view?</p>
  
  <p>Global.asax.cs</p>
  
  <pre><code>    protected void Application_AuthenticateRequest(Object sender, EventArgs e)
      {
          HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
          if (authCookie == null || authCookie.Value == "")
          {
              return;
          }
  
          FormsAuthenticationTicket authTicket = null;
  
          try
          {
              authTicket = FormsAuthentication.Decrypt(authCookie.Value);
          }
          catch
          {
              return;
          }
  
          if (Context.User != null)
          {
              string[] roles = authTicket.UserData.Split(new char[] { ';' });
              Context.User = new GenericPrincipal(Context.User.Identity, roles);
          }
      }
  </code></pre>
  
  <p>AccountController.cs</p>
  
  <pre><code>    [HttpPost]
      [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings",
          Justification = "Needs to take same parameter type as Controller.Redirect()")]
      public ActionResult LogOn(string userName, string password, bool rememberMe, string returnUrl)
      {
  
          if (!ValidateLogOn(userName, password))
          {
              ViewData["rememberMe"] = rememberMe;
              return View();
          }
  
          // Make sure we have the username with the right capitalization
          // since we do case sensitive checks for OpenID Claimed Identifiers later.
          userName = this.MembershipService.GetCanonicalUsername(userName);
  
          // Lookup user's (CWID) appropriate access level
          string accessLevel = userRepository.FindUserByUserName(userName).AccessLevel.LevelName;
  
          FormsAuthenticationTicket authTicket = new
                          FormsAuthenticationTicket(1, //version
                          userName, // user name
                          DateTime.Now,             //creation
                          DateTime.Now.AddMinutes(30), //Expiration
                          rememberMe, //Persistent
                          accessLevel); // hacked to use roles instead
  
          string encTicket = FormsAuthentication.Encrypt(authTicket);
          this.Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));
  
          if (!String.IsNullOrEmpty(returnUrl))
          {
              return Redirect(returnUrl);
          }
          else
          {
              return RedirectToAction("Index", "Home");
          }
      }
  </code></pre>
  
  <p>SpotlightController.cs</p>
  
  <pre><code>    [Authorize(Roles="Admin")]
      public ActionResult Delete(int id)
  </code></pre>