我面临以下问题(虽然我不太确定这是否是一个问题......):
我已经使用 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 Security 拦截器和 Spring MVC 拦截器之间的竞争条件(在我看来)相同的 URL 模式(有时首先返回响应,有时是登录表单) .
编辑
当我实际尝试进行重定向时,奇怪的行为实际上出现了,而不是直接写回一些响应。现在我似乎无法重现它......
有人可以在这里提出建议,我应该如何正确处理?