Использование метода setAllowedFields() в Spring
Я использую Spring 3.2.0. Я зарегистрировал несколько пользовательских редакторов свойств для некоторых основных потребностей следующим образом.
import editors.DateTimeEditor;
import editors.StrictNumberFormatEditor;
import java.math.RoundingMode;
import java.net.URL;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import org.joda.time.DateTime;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.beans.propertyeditors.URLEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.request.WebRequest;
@ControllerAdvice
public final class GlobalDataBinder
{
@InitBinder
public void initBinder(WebDataBinder binder, WebRequest request)
{
binder.setIgnoreInvalidFields(true);
binder.setIgnoreUnknownFields(true);
//binder.setAllowedFields(someArray);
NumberFormat numberFormat=DecimalFormat.getInstance();
numberFormat.setGroupingUsed(false);
numberFormat.setMaximumFractionDigits(2);
numberFormat.setRoundingMode(RoundingMode.HALF_UP);
binder.registerCustomEditor(DateTime.class, new DateTimeEditor("MM/dd/yyyy HH:mm:ss", true));
binder.registerCustomEditor(Double.class, new StrictNumberFormatEditor(Double.class, numberFormat, true));
binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
binder.registerCustomEditor(URL.class, new URLEditor());
}
}
У меня есть много зарегистрированных редакторов. Двое из них DateTimeEditor
а также StrictNumberFormatEditor
были настроены путем переопределения соответствующих методов для удовлетворения пользовательских потребностей формата чисел и Joda-Time.
Поскольку я использую Spring 3.2.0, я могу воспользоваться @ControllerAdvice
,
Spring рекомендует перечислить набор разрешенных полей с setAllowedFields()
метод, чтобы злоумышленники не могли вводить значения в связанные объекты.
Из документов о DataBinder
Связыватель, который позволяет устанавливать значения свойств для целевого объекта, включая поддержку проверки и анализа результатов привязки. Процесс привязки можно настроить, указав разрешенные поля, обязательные поля, пользовательские редакторы и т. Д.
Обратите внимание, что при сбое в настройке массива допустимых полей возможны последствия для безопасности. Например, в случае данных POST формы HTTP злонамеренные клиенты могут попытаться подорвать приложение, указав значения для полей или свойств, которые не существуют в форме. В некоторых случаях это может привести к тому, что недопустимые данные будут установлены для объектов команд или их вложенных объектов. По этой причине настоятельно рекомендуется указать
allowedFields
свойство в DataBinder.
У меня большое приложение и, очевидно, есть тысячи полей. Указание и перечисление их всех с setAllowedFields()
это утомительная работа. Кроме того, как-то мне нужно их запомнить.
Изменение веб-страницы для удаления некоторых полей или добавления дополнительных полей при повторной необходимости требует изменения значения параметра setAllowedFields()
метод, чтобы отразить эти изменения.
Есть ли альтернатива этому?
3 ответа
Вместо того, чтобы использовать setAllowedFields()
в белый список, вы можете использовать setDisallowedFields()
в черный список. Например, из примера приложения для петклиники:
@InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
dataBinder.setDisallowedFields("id");
}
С точки зрения безопасности белый список предпочтительнее черного списка, но, возможно, он поможет облегчить бремя.
setAllowedFields() очень удобен при использовании объектов сущностей непосредственно в веб-слое. В качестве альтернативы можно использовать выделенные объекты передачи данных (DTO), из которых объекты объектов создаются на уровне обслуживания. Фабрики могут быть использованы не только повторно, но и вне веб-контекста, например, для асинхронных сообщений. Кроме того, наследование DTO не обязательно должно следовать за наследованием сущностей, поэтому вы можете свободно проектировать иерархию DTO в соответствии с потребностями сценариев использования.
Решение использовать связующее с DTO (например, данные компании) в случае, если большая часть входных значений формы должна быть преобразована в null, если она пуста, но есть необходимость добавить несколько исключений (setDisallowedFields у меня не сработал).
@InitBinder()
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
}
@InitBinder
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) {
binder.registerCustomEditor(String.class, "companydata.companyName", new StringTrimmerEditor(false));
binder.registerCustomEditor(String.class, "companydata.companyNumber", new StringTrimmerEditor(false));
}
4.9. Указание привязок явно
Используйте элемент связывателя, чтобы настроить точный набор привязок модели, используемых представлением. Это особенно полезно в среде Spring MVC для ограничения набора "разрешенных полей" для представления.
<view-state id="enterBookingDetails" model="booking">
<binder>
<binding property="creditCard" />
<binding property="creditCardName" />
<binding property="creditCardExpiryMonth" />
<binding property="creditCardExpiryYear" />
</binder>
<transition on="proceed" to="reviewBooking" />
<transition on="cancel" to="cancel" bind="false" />
</view-state>
Если элемент связывания не указан, все открытые свойства модели могут быть привязаны представлением. Если указан элемент связывания, разрешены только явно настроенные привязки.
Каждая привязка может также применять конвертер для форматирования значения свойства модели для отображения в пользовательском порядке. Если конвертер не указан, будет использован конвертер по умолчанию для типа свойства модели.
<view-state id="enterBookingDetails" model="booking">
<binder>
<binding property="checkinDate" converter="shortDate" />
<binding property="checkoutDate" converter="shortDate" />
<binding property="creditCard" />
<binding property="creditCardName" />
<binding property="creditCardExpiryMonth" />
<binding property="creditCardExpiryYear" />
</binder>
<transition on="proceed" to="reviewBooking" />
<transition on="cancel" to="cancel" bind="false" />
</view-state>
В приведенном выше примере конвертер shortDate привязан к свойствам checkinDate и checkoutDate. Пользовательские конвертеры могут быть зарегистрированы в приложении ConversionService.
Каждая привязка может также применять обязательную проверку, которая будет генерировать ошибку проверки, если предоставленное пользователем значение равно нулю при обратной передаче формы:
<view-state id="enterBookingDetails" model="booking">
<binder>
<binding property="checkinDate" converter="shortDate" required="true" />
<binding property="checkoutDate" converter="shortDate" required="true" />
<binding property="creditCard" required="true" />
<binding property="creditCardName" required="true" />
<binding property="creditCardExpiryMonth" required="true" />
<binding property="creditCardExpiryYear" required="true" />
</binder>
<transition on="proceed" to="reviewBooking">
<transition on="cancel" to="bookingCancelled" bind="false" />
</view-state>
В приведенном выше примере все привязки обязательны. Если одно или несколько пустых входных значений связаны, будут сгенерированы ошибки проверки, и представление будет повторно визуализировано с этими ошибками.