Spring MVC + 会话对话(多个选项卡)+ Spring 使用 CSRF + Thymeleaf 的安全性

Spring MVC + Session Conversation (multiple tabs) + Spring Security with CSRF + Thymeleaf

在之前的Spring + Spring安全版本中,当我没有使用内置的CSFR时,很容易添加会话对话支持(用于支持多个"edit"标签) ,使用 https://github.com/duckranger/Spring-MVC-conversation 中描述的技术,具体实施 RequestDataValueProcessor

然而,现在我们使用 spring 引导,所有它的自动配置优点,CsrfRequestDataValueProcessor 现在实现 RequestDataValueProcessor

如果我添加自己的 RequestDataValueProcessor 实现,它永远不会被使用。

任何人都可以指出正确的方向,以便我可以同时使用 CsrfRequestDataValueProcessor 和我的 RequestDataValueProcessor

我假设我需要创建一个复合 RequestDataValueProcessor,或者您可以有多个 RequestDataValueProcessor 实现吗?

提前致谢

我刚刚通过对 duckranger 解决方案的一个小修改解决了这个问题。我将对 ScrfRequestDataValueProcessor 的调用嵌入到 getExtraHiddenFields 方法中。

@Override
public Map<String, String> getExtraHiddenFields(HttpServletRequest request) {
    CsrfRequestDataValueProcessor csrfRDVP = new CsrfRequestDataValueProcessor();
    Map<String, String> hiddenFields = csrfRDVP.getExtraHiddenFields(request);

    if (request.getAttribute(ConversationalSessionAttributeStore.CID_FIELD) != null) {
        hiddenFields.put(ConversationalSessionAttributeStore.CID_FIELD,
        request.getAttribute(ConversationalSessionAttributeStore.CID_FIELD).toString());
    }

    return hiddenFields;
}

今天刚刚实施,几乎没有开始用户测试,因此使用风险自负。

我忍不住认为有更好的方法,但这似乎可以解决问题。

想我会分享我为使它正常工作所做的工作。 我需要一个解决方案,但我无法让 Thymeleaf 使用我自己的 RequestDataValueProcessor,即使在我的配置中正确创建了 bean。

注意:我知道这是一个很 hack,但同时也很有趣。

解决方案:AspectJ.....

@Aspect
public class SessionConversationAspect {

    private final ConversationIdRequestProcessor conversationIdRequestProcessor;

    public SessionConversationAspect() {
        this.conversationIdRequestProcessor = new ConversationIdRequestProcessor();
    }

    @Pointcut("execution(* org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor.getExtraHiddenFields(..) ) && args(request) )")
    protected void getExtraHiddenFields(HttpServletRequest request) {
    }

    @AfterReturning(
            pointcut = "getExtraHiddenFields(request)",
            returning = "hiddenFields"
    )
    protected void addExtraHiddenFields(HttpServletRequest request, Map<String, String> hiddenFields) {
        Map<String, String> extraFields = conversationIdRequestProcessor.getExtraHiddenFields(request);
        hiddenFields.putAll(extraFields);
    }

}