title: How do I create a custom JSON 401 page for my Spring MVC/Security restful web service?
body: <p>I'm trying to create a secured restful web service using Servlet 3.0, Spring MVC and Spring Security. I'd like to return a custom JSON message on a 401 instead of the default HTML message returned by the Servlet container.</p>
  
  <p>I've tried several approaches but can't seem to get this working.</p>
  
  <p>My controller looks like follows::</p>
  
  <pre><code>@Controller
  @RequestMapping("/")
  public class ApplicationController {
  
      private ApplicationFactory applicationFactory;
  
      @Inject
      public ApplicationController(ApplicationFactory applicationFactory) {
          super();
          this.applicationFactory = applicationFactory;
      }
  
      @RequestMapping(method = GET)
      @ResponseBody
      @Secured("ROLE_USER")
      public Application getApplicationInfo() {
          return applicationFactory.buildApplication(this);
      }
  
  }
  </code></pre>
  
  <p>And my Spring Security context looks as follows:</p>
  
  <pre><code>&lt;security:global-method-security secured-annotations="enabled" mode="aspectj" /&gt;
  
  &lt;security:http auto-config="true" use-expressions="true"&gt;
  &lt;security:http-basic /&gt;
  &lt;/security:http&gt;
  </code></pre>
  
  <p>I've tried adding the following:</p>
  
  <pre><code>@ExceptionHandler(AccessDeniedException.class)
  @ResponseBody
  public Application accessDenied() {
      return applicationFactory.buildApplication(this);
  }
  </code></pre>
  
  <p>But it gets ignored. I've tried adding "access-denied-page="/denied"" to my security:http tag with the following in my controller:</p>
  
  <pre><code>@RequestMapping(value = "/denied", method = GET)
  @ResponseBody
  public Application accessDenied() {
      return applicationFactory.buildApplication(this);
  }
  </code></pre>
  
  <p>But it gets ignored. I've tried a custom access denied handler as follows:</p>
  
  <pre><code>&lt;security:http auto-config="true" use-expressions="true"&gt;
  &lt;security:http-basic /&gt;
  &lt;security:access-denied-handler ref="jsonAccessDeniedHandler" /&gt;
  &lt;/security:http&gt;
  </code></pre>
  
  <p>The only thing that does seem to work is the following:</p>
  
  <pre><code>@ExceptionHandler(Exception.class)
  @ResponseBody
  public Application accessDenied() {
      return applicationFactory.buildApplication(this);
  }
  </code></pre>
  
  <p>But this catches everything and I only want to customise a failed authentication.</p>
  
  <p>Lastly, adding this to my web.xml also works:</p>
  
  <pre><code>&lt;error-page&gt;
  &lt;error-code&gt;401&lt;/error-code&gt;
  &lt;location&gt;/401&lt;/location&gt;
  &lt;/error-page&gt;
  </code></pre>
  
  <p>But I'd prefer to configure as much pro-grammatically or through annotations.</p>