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);
}
}
在之前的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);
}
}