title: MVC interceptor vs Spring security filter vs something else...?
body: <p>I'm using Spring-MVC with Spring Security for my web application. It includes user registration pages and private user panel. I have it set up currently with the following URL patterns:  </p>
  
  <ul>
  <li><code>whatever/myapp/login</code> user log in</li>
  <li><code>whatever/myapp/register?step=1</code> start registration</li>
  <li><code>whatever/myapp/account/**</code> private area views (pages)</li>
  <li><code>whatever/myapp/pending</code> view shown while post-registration processes complete</li>
  <li><code>whatever/myapp/blocked</code> account blocked view</li>
  <li><code>whatever/myapp/register/retry</code> if registration failed, allow retry  </li>
  </ul>
  
  <p>Essentially, these URLs below should require user authentication, i.e. require log-in:  </p>
  
  <ul>
  <li><code>whatever/myapp/account/**</code> (private area pages)</li>
  <li><code>whatever/myapp/pending</code> (this page has a timer set to redirect to /account/home)</li>
  <li><code>whatever/myapp/register/retry</code></li>
  </ul>
  
  <p>This is quite straightforward to achieve using Spring security. However, regardless of user authentication through Spring security, private area pages should be accessible or not, depending on user's current account status (stored in my DB).  </p>
  
  <p>More specifically: if a user tries to access anything in the private area (<code>/account/**</code>), he should be shown the appropriate view (redirected to appropriate page), according to the status. I have these statuses defined: </p>
  
  <ul>
  <li><code>suspended</code> - relates to pending view</li>
  <li><code>enabled</code> - allow full access</li>
  <li><code>disabled</code> - not relevant here</li>
  <li><code>retry_allowed</code>- relates to retry view</li>
  <li><code>blocked</code> - relates to account-blocked view</li>
  </ul>
  
  <p>Currently, I have a MVC interceptor setup to <code>/account/**</code>, that checks user status, and redirects to appropriate pages, but somehow I get the sense that this is not really the ideal or appropriate solution here, since I'm facing strange behavior, like multiple controller invocation...  and also I'm not quite certain when to return <code>true</code> / <code>false</code> within <code>preHandle()</code> method. Here's the code snippet from the interceptor:  </p>
  
  <pre><code>@Override
  public boolean preHandle(
      HttpServletRequest request, 
      HttpServletResponse response,
      Object arg2) 
      throws Exception {
  
  IPanelUser pUser =  (IPanelUser) SecurityContextHolder.getContext()
          .getAuthentication().getPrincipal();
  
  // check principal first and then load from DB
  // "suspended" is initial status upon registration
  if(pUser.getCustomer().getStatus() == CustomerStatus.Suspended.getCode()) {
  
      // if suspended, load from DB and update status
      Customer customer = this.customerService.getUserByUsername(pUser.getUsername());
      if(customer != null)
          pUser.getCustomer().setStatus(customer.getStatus());
  
      // still suspended? redirect to pending
      if(pUser.getCustomer().getStatus() == CustomerStatus.Suspended.getCode()) {
          response.sendRedirect("../pending");
          return false;
      }
  }
  
  if(pUser.getCustomer().getStatus() == CustomerStatus.Blocked.getCode()) {
  
      // redirect to blocked page
      response.sendRedirect("../blocked");
      SecurityContextHolder.clearContext();
      return false;
  }
  
  if(pUser.getCustomer().getStatus() == CustomerStatus.AllowRetry.getCode()) {
  
      // redirect to CC submission page
      response.sendRedirect("../register/retry");
      return false;
  }
  
  if(pUser.getCustomer().getStatus() == CustomerStatus.Enabled.getCode() ||
     pUser.getCustomer().getStatus() == CustomerStatus.Disabled.getCode()) {
  
      // do nothing
  }
  
  return true;
  }
  </code></pre>
  
  <p>.  </p>
  
  <p>Is this a valid approach ? Any alternative suggestions ?</p>