我正在为我的 Web 应用程序使用带有 Spring Security 的 Spring-MVC。它包括用户注册页面和私人用户面板。我目前使用以下 URL 模式设置它:
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/**
,用于检查用户状态,并重定向到适当的页面,但不知何故,我觉得这不是真正理想或适当的解决方案,因为我面临着奇怪的行为,比如多个控制器调用...而且我也不太确定何时在方法内返回true
/ 。这是拦截器的代码片段: false
preHandle()
@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;
}
.
这是一种有效的方法吗?任何替代建议?