如何安全地使用URL GET请求参数初始化ViewScoped bean?

时间:2014-07-14 19:51:11

标签: jsf jsf-2

我有一些托管bean(ViewScoped),它们当前已使用会话中的数据进行初始化。我想用URL GET参数初始化它们,这样我就可以提供我希望在视图中显示的实体ID的URL。像displayClient.xhtml?entityId=123这样的东西。

现在我在视图主要实体的getter中考虑这样的事情:

public clientModel getclientM() {
  if (this.clientM == null) {
    // TODO: Check for empty, non-integer or garbage parameters...
    // Anything exists to "sanitize" URL parameters?
    int entityId = Integer.parseInt(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("entityId"));

    // I guess I should check here if the logged user is authorized to 
    // load client entity with this entityId...  anything else to check?

    this.clientM = this.clientS.find(entityId);
  }

  return this.clientM;
}

非常感谢任何提示或建议的最佳做法。

3 个答案:

答案 0 :(得分:2)

我认为沿着这些方向的事情是最佳实践:

displayclient.xhtml:

<f:metadata>
    <f:viewParam name=“entityId” 
                 value="#{bean.clientM}” 
                 required="true" 
                 converter=“clientModelConverter”
                 converterMessage="Bad request. Unknown ClientModel.”
                 requiredMessage="Bad request. Please use a link from within the system.">
    </f:viewParam>
</f:metadata>

转换器:

@ManagedBean    
@RequestScoped 
public class ClientModelConverter implements Converter {

    @EJB
    private ClientService clientService;

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        // TODO: check if value is instanceof ClientModel
        return String.valueOf(((ClientModel) value).getId());
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
       // TODO: catch NumberFormatException and throw ConverterException
       return clientService.find(Integer.valueOf(value));
    }

}

使用例如:

调用页面
<h:link value=“Display” outcome="displayClient">
    <f:param name=“entityId" value=“#{…}” />
</h:link>

或只是一个原始网址,例如displayClient.xhtml?entityId=123

深受启发 What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?JSF 2.0 view parameters to pass objects

答案 1 :(得分:0)

  1. 将entityId存储在会话中,例如SessionScoped Bean
  2. 在View Scoped托管bean中,添加@PostConstruct方法,您将从会话中获取entityId并使用此方法填充数据

答案 2 :(得分:0)

我做了类似的事情,原因完全相同:提供一个jsf页面的外部链接。

在ViewScoped bean中,使用@PostConstruct方法强制对Get Param进行故障安全扫描

@PostConstruct
public void scanEntityId(){

    int entityId = 0; // or some other default value 

    try{
        // Try to fetch entityId from url with GET
        int entityId = Integer.getInteger(FacesContext.getExternalContext().getRequestParameterMap().get("entityId")  );
    }catch(Exception e){
        // Did not find anything from GET
    }

    // TODO: do stuff using the entityId's value. e.g.:
    if(entityId >0){
        this.clientM = this.clientS.find(entityId);
    }
}

只需确保处理在Get params中找不到 entityId var的情况

如果您想从同一应用的其他xhtml页面链接到该页面,可以使用 f:param

<h:link value="Go in a page that uses thatViewScoped Bean"
    outcome="#{thatViewScopedBean.takeMeToThatPage}" >      
    <f:param name="entityId" value="#{somebean.somevar.entityId}" />
</h:link>

还可以找到一个很好的教程here 您可能还希望see this answer和此article查看更多选项并获得更清晰的视图。