StrictHttpFirewall в spring безопасности 4.2 vs spring MVC @MatrixVariable

Обновившись до весенней безопасности 4.2.4, я обнаружил, что StrictHttpFirewall теперь используется по умолчанию. К сожалению, он не очень хорошо работает с пружиной MVC @MatrixVariable, так как ";" больше не допускаются Как обойти это?

Пример:

@GetMapping(path = "/{param}")
public void example(@PathVariable String param,
                    @MatrixVariable Map<String, String> matrix) {
    //...
}

Это можно назвать так:

mockMvc.perform(get("/someparam;key=value"))

И матричная карта будет заполнена. Теперь весенняя охрана блокирует его.

org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentially malicious String ";"

at org.springframework.security.web.firewall.StrictHttpFirewall.rejectedBlacklistedUrls(StrictHttpFirewall.java:140)

Я мог бы использовать собственный HttpFirewall, который позволял бы использовать точки с запятой. Есть ли способ использовать @MatrixVariable без использования запрещенных символов?

КСТАТИ: Javadoc неверно https://docs.spring.io/autorepo/docs/spring-security/4.2.x/apidocs/index.html?org/springframework/security/web/firewall/StrictHttpFirewall.html

Поскольку:

5.0.1

Я думаю, это было перенесено?

Ответ 1

Вы можете разбавить брандмауэр безопасности Spring по умолчанию, используя свой пользовательский экземпляр StrictHttpFirewall (на свой страх и риск)

@Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
    StrictHttpFirewall firewall = new StrictHttpFirewall();
    firewall.setAllowUrlEncodedSlash(true);
    firewall.setAllowSemicolon(true);
    return firewall;
}

А затем используйте этот пользовательский компонент брандмауэра в WebSecurity (загрузка Spring не требует этого изменения)

@Override
public void configure(WebSecurity web) throws Exception {
  super.configure(web);
  // @formatter:off
  web.httpFirewall(allowUrlEncodedSlashHttpFirewall());
...
}

Это должно работать с Spring Security 4.2. 4+, но, конечно, это сопряжено с некоторыми рисками!

Ответ 2

Как отметил Крис в комментарии, если вы предпочитаете использовать XML-подход, вы можете добавить следующую часть в ваш securityContext.xml (или как там называется xml-config, связанная с пружинной безопасностью):

<bean id="allowSemicolonHttpFirewall" 
      class="org.springframework.security.web.firewall.StrictHttpFirewall"> 
        <property name="allowSemicolon" value="true"/> 
</bean> 
<security:http-firewall ref="allowSemicolonHttpFirewall"/>

Часть <bean> определяет новый компонент StrictHttpFirewall с идентификатором allowSemicolonHttpFirewall который затем устанавливается как http-firewall по умолчанию в <security> путем ссылки на id.

Ответ 3

Я использовал комбинацию следующих двух

  1. fooobar.com/info/849178/...
  2. fooobar.com/info/10213540/...

  • Сначала был решен The request was rejected because the URL contained a potentially malicious String ";"
  • Второй решен Spring MVC Missing matrix variable

Поскольку я использую Spring Security с Spring Web, мне пришлось сделать и то, и другое, и проблема теперь решена.

Я обнаружил, что использование @MatrixVariable Pattern полезно. Сначала в Url {num} нужно упомянуть, чтобы использовать его как @MatrixVariable

@RequestMapping(method = RequestMethod.GET,value = "/test{num}")
@ResponseBody
public ResponseEntity<String> getDetail(@MatrixVariable String num){
    return new ResponseEntity<>("test"+num, HttpStatus.OK);
}'''