Les*_*ess 14 java spring-mvc filter spring-security interceptor
我在我的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/**,它检查用户状态,并重定向到适当的页面,但不知何故,我感觉这不是真正理想或适当的解决方案,因为我面临奇怪的行为,如多个控制器调用...而且我不太确定何时返回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;
}
Run Code Online (Sandbox Code Playgroud)
.
这是一种有效的方法吗?还有其他建议吗?
Sot*_*lis 21
所有选项都有效,这取决于您想要的抽象级别.
在a中Filter,您只能访问HttpServletRequest和HttpServletResponse对象,因此您非常熟悉ServletAPI.你也没有(直接)访问所有伟大的Spring功能,比如返回要渲染的视图或者ResponseEntity.
在一个HandlerInterceptor,它再次更相同.您可以直接在preHandle()您无权访问的地方进行重定向或请求处理,ModelAndView或者设置您签入的标志postHandle().您可以访问ModelAndView但不能访问其他一些Spring MVC功能.
Spring Security是一个不错的选择,但我发现它有很多我不太喜欢的配置.
我最喜欢的最后一个选择是使用AOP(你也可以使用Spring Security或Shiro).您可以创建一个注释,@Private并注释您的@Controller处理程序方法.您使用AOP建议这些方法.该建议基本上检查一些会话或请求属性的标志(授权与否).如果允许,则继续执行处理程序方法,否则,抛出UnauthorizedException(或类似).然后你还声明了一个@ExceptionHandler异常,你可以完全控制响应的生成方式:a ModelAndView(和相关的),a ResponseEntity,注释处理程序@ResponseBody,直接写响应,等等.我觉得你有更多的控制权, 如果你想要的话.
| 归档时间: |
|
| 查看次数: |
13945 次 |
| 最近记录: |