2

我面临以下问题(虽然我不太确定这是否是一个问题......):

我已经使用 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 模式(有时首先返回响应,有时是登录表单) .

编辑
当我实际尝试进行重定向时,奇怪的行为实际上出现了,而不是直接写回一些响应。现在我似乎无法重现它......

有人可以在这里提出建议,我应该如何正确处理?

4

0 回答 0