当程序将非将HTTP请求参数直接绑定给对象时,应该要控制绑定到对象的属性,防止暴露敏感属性。
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.setDisallowedFields(new String[]{"admin"});
}
@RequestMapping("/login" )
public String login(User user) {
...
}
@Override
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
binder.setDisallowedFields(new String[]{"admin"});
}
在使用@RequestBody注释参数的 Spring MVC应用程序中,绑定过程由HttpMessageConverter进行处理,这些实例使用Jackson和JAXB等库将 HTTP请求参数转换为Java对象。这些库提供了注释来控制应允许或禁止的字段。例如对于Jackson,可以使用@JsonIgnore注释禁止将某个字段绑定到请求。
@RequestMapping(value="/add/user", method=RequestMethod.POST, consumes="text/html")
public void addEmployee(@RequestBody User user){
...
}
public class User {
private String username;
private String address;
@JsonIgnore
private boolean admin;
private int age;
...
}
同理,Jackson还可以使用@JsonIgnoreProperties、@JsonIgnoreTyp和 @JsonInclude等注解告诉框架忽略这些属性,使用JAXB使用@XmlAccessorType、@XmlAttribute、@XmlElement和 @XmlTransient等注解告诉框架忽略这些属性,然后使用@XmlAttribute和@XmlElement等注解选择应绑定的字段。
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class User {
private String username;
private String address;
@JsonIgnore
private boolean admin;
private int age;
@XmlAttribute
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@XmlAttribute
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
private boolean isAdmin() {
return admin;
}
private void setAdmin(boolean admin) {
this.admin = admin;
}
...
}
例5:在以下代码片段中,在Struts可以将某个属性的setter方法设置为私有从而禁止绑定敏感属性。
private boolean admin;
private void setAdmin(boolean admin) {
this.admin = admin;
}
还有另一种方法是使用将 HTTP请求参数绑定到仅含有 Web表单或 API中定义的属性DTO对象中,再将其映射到User中,防止敏感字段暴露。