[英]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
,您只能訪問HttpServletRequest
和HttpServletResponse
對象,因此您非常適合使用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.