我面临以下问题(虽然我不太确定它是否有问题......):
我使用Spring MVC实现了一个3步用户注册向导。
第3步成功后,将创建新的UserDetails
对象并将其放置在安全上下文中,如:
...
UserDetails newUser = new PanelUser(customer, AuthenticationService.getFixedAuthorities());
Authentication authentication =
new UsernamePasswordAuthenticationToken(newUser, null, newUser.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
因为新用户应被视为已通过身份验证(即已登录)。拦截URL模式定义如下:
<intercept-url pattern="/account/**" access="IS_AUTHENTICATED_REMEMBERED" />
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
现在,这是“问题”
在用户成功注册的同时,可能存在仍在后台运行的长操作,由注册过程触发。直到此操作未完成(基本上它只是在完成时在user
表中设置特定的bool标志),即使登录,用户也不应该看到具有相同URL模式的任何页面,即/account/**
,但应该重定向(我猜)到信息页面,告诉他在后台操作完成时帐户访问权限正在等待。
我尝试的是以下内容:
我定义了MVC拦截器,实现了HandlerInterceptor
并在preHandle
方法
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2) throws Exception {
// omitted for brevity...
// explicitly load from DB
Customer customer = this.customerService.getUserByUsername(pUser.getUsername());
if(customer.getStatus() == CustomerStatus.Suspended.getCode()) {
//arg1.sendRedirect("../pending");
// it should actually return appropriate info view,
// or redirect, this is just for test...
arg1.getOutputStream().write("Account access pending".getBytes());
return false;
}
return true;
}
和配置
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/account/**"/>
<bean id="accountAccessInterceptor"
class="rs.slb.customerpanel.utils.AccountAccess">
<property name="customerService" ref="customerService" />
</bean>
</mvc:interceptor>
</mvc:interceptors>
有了这个,我遇到了一些奇怪的行为,有点类似于Spring安全拦截器和Spring MVC拦截器之间的竞争条件(在我看来)相同的URL模式(有时首先返回响应,有时是登录表格)。
修改
当我真正尝试进行重定向时,奇怪的行为实际上就出现了,而不是直接写回一些响应。现在我似乎无法重现它......
有人可以在这里提出建议吗,我该怎么做呢?