簡體   English   中英

MVC攔截器與Spring安全過濾器vs其他東西......?

[英]MVC interceptor vs Spring security filter vs something else…?

我在我的Web應用程序中使用Spring-MVC和Spring Security。 它包括用戶注冊頁面和私人用戶面板。 我現在設置了以下網址模式:

  • whatever/myapp/login用戶登錄
  • whatever/myapp/register?step=1開始注冊
  • whatever/myapp/account/**私人區域視圖(頁面)
  • 注冊后流程完成后顯示的whatever/myapp/pending視圖
  • whatever/myapp/blocked帳戶被阻止的視圖
  • 如果注冊失敗, whatever/myapp/register/retry ,都允許重試

基本上,下面的這些URL應該要求用戶身份驗證,即需要登錄:

  • whatever/myapp/account/** (私人區域頁面)
  • whatever/myapp/pending (此頁面有一個定時器設置為重定向到/ account / home)
  • whatever/myapp/register/retry

使用Spring安全性非常簡單。 但是,無論通過Spring安全性進行用戶身份驗證,私有區域頁面都應該是可訪問的,具體取決於用戶的當前帳戶狀態(存儲在我的數據庫中)。

更具體地說:如果用戶試圖訪問私有區域( /account/** )中的任何內容,則應根據狀態向他顯示相應的視圖(重定向到適當的頁面)。 我定義了這些狀態:

  • suspended - 與待審視圖有關
  • enabled - 允許完全訪問權限
  • disabled - 與此無關
  • retry_allowed - 與重試視圖有關
  • blocked - 與帳戶被阻止的視圖有關

目前,我有一個MVC攔截器設置到/account/** ,它檢查用戶狀態,並重定向到適當的頁面,但不知何故,我覺得這不是真正理想或適當的解決方案,因為我面臨奇怪行為,就像多個控制器調用一樣...而且我不太確定何時在preHandle()方法中返回true / false 這是攔截器的代碼片段:

@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;
}

這是一種有效的方法嗎? 還有其他建議嗎?

所有選項都有效,這取決於您想要的抽象級別。

Filter ,您只能訪問HttpServletRequestHttpServletResponse對象,因此您非常適合使用Servlet API。 您也沒有(直接)訪問所有偉大的Spring功能,例如返回要呈現的視圖或ResponseEntity

HandlerInterceptor ,它再次變得更加相同。 您可以直接在preHandle()中進行重定向或請求處理,在preHandle()中您無權訪問ModelAndView或設置您在postHandle()檢查的標志。 您可以訪問ModelAndView但不能訪問其他一些Spring MVC功能。

Spring Security是一個不錯的選擇,但我發現它有很多我不太喜歡的配置。

我最喜歡的最后一個選擇是使用AOP(你也可以使用Spring Security或Shiro)。 您可以創建類似@Private的注釋,並注釋@Controller處理程序方法。 您使用AOP建議這些方法。 該建議基本上檢查一些會話或請求屬性的標志(授權與否)。 如果允許,則繼續執行處理程序方法,否則,拋出UnauthorizedException (或類似)。 然后,您還可以為該異常聲明一個@ExceptionHandler ,您可以完全控制響應的生成方式: ModelAndView (及相關), ResponseEntity ,使用@ResponseBody注釋處理程序,直接編寫響應等等。我覺得就像你有更多的控制權,如果你想要的話。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM