2013-04-10 29 views
2

我正在使用JSF 2.2。我试图使用JSF作为纯模板语言。但是,有一个问题。是谁在我的环境中创建一个JSF页面任何用户都可以做这样的事情:如何在JSF页面上禁用#{session}?

#{session.getAttribute('user').getApiKey()} 

在这里我有一个存储在会话和getApiKey()方法是该类中的吸气用户对象。

是否存在'web.xml'配置或其他一些技巧,我可以用它来在JSF页面上完全禁用会话对象?

回答

2

是否存在'web.xml'配置或其他一些技巧,我可以用它来在JSF页面上完全禁用会话对象?

手动解析模板与允许标记的白名单,属性和EL表达式(注意:不要使用黑名单,黑客会发现你无法想象的方式)。例如,下列词汇具有作为​​同样的效果:

  • #{request.session.getAttribute('user').apiKey}
  • #{sessionScope.user.apiKey}
  • #{user.apiKey}
  • #{facesContext.externalContext.sessionMap.user.apiKey}
  • #{facesContext.externalContext.session.getAttribute('user').apiKey}

毕竟,JSF/Facelets的可能这个工作的错误工具为客户提供某种将在服务器上执行的模板。而不是寻找BB/Wiki/Markdown -like标记或whitelisted HTML,你通过<h:outputText escape="false">显示。

1

也许吧。隐式变量由特定的ELResolver提供。从ELResolvers列表中删除那个,或者预先添加一个自己的解析器,该解析器总是为该列表的所有隐式变量返回null,这应该能够做到。

副手,我不知道JSF是否提供了一个公共API来做到这一点,或者规范甚至允许这样的事情。

无论哪种方式,如果你只需要一个模板引擎,有一个自定义状态,基于组件的Web应用程序框架更容易的选择...

+0

EL解析器是应用程序范围这将由此也打败 “自己的” 代码工作。 – BalusC 2013-04-10 22:51:34

+0

如果我们已经在JSF内部开始探索,那么可能有很多方法。例如,我们可以使用一个专用的FacesContextFactory和一个不同配置的EL-Context。 – meriton 2013-04-10 23:05:54

0

这里是我做过什么来解决这个问题。这个类从本质上撤销对页面上所有核心对象的访问。另外,我添加了一个实用变量来访问上下文路径。我已经试过这个,并且似乎是工作!

package com.example.templates.jsf; 

import javax.el.ELContext; 
import javax.el.ELException; 
import javax.el.PropertyNotFoundException; 
import javax.faces.component.UIComponent; 
import javax.faces.context.ExternalContext; 
import javax.faces.context.FacesContext; 

import com.sun.faces.component.CompositeComponentStackManager; 
import com.sun.faces.el.ImplicitObjectELResolver; 
import com.sun.faces.util.MessageUtils; 

/** 
* This class revokes access to server page context objects 
*/ 
public class CustomImplicitObjectELResolver extends ImplicitObjectELResolver { 

public static final int CONTEXT_PATH = 19; 

public CustomImplicitObjectELResolver(){ 
    super(); 

    // Revoke access to variables that can potentially 
    // give access to internal class objects. 
    IMPLICIT_OBJECTS.remove("facesContext"); 
    IMPLICIT_OBJECTS.remove("session"); 
    IMPLICIT_OBJECTS.remove("sessionScope"); 
    IMPLICIT_OBJECTS.remove("application"); 
    IMPLICIT_OBJECTS.remove("applicationScope"); 
    IMPLICIT_OBJECTS.remove("request"); 
    IMPLICIT_OBJECTS.remove("requestScope"); 
    IMPLICIT_OBJECTS.remove("view"); 
    IMPLICIT_OBJECTS.remove("viewScope"); 
    IMPLICIT_OBJECTS.remove("initParam"); 
    IMPLICIT_OBJECTS.remove("component");  
    IMPLICIT_OBJECTS.remove("cookie"); 
    IMPLICIT_OBJECTS.remove("header"); 
    IMPLICIT_OBJECTS.remove("headerValues"); 
    IMPLICIT_OBJECTS.remove("flowScope"); 

    // My own utility method 
    IMPLICIT_OBJECTS.put("contextPath", CONTEXT_PATH); 
} 

@Override 
public Object getValue(ELContext context,Object base, Object property) 
     throws ELException { 
    // variable resolution is a special case of property resolution 
    // where the base is null. 
    if (base != null) { 
     return null; 
    } 
    if (property == null) { 
     String message = MessageUtils.getExceptionMessageString 
      (MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "property"); 
     throw new PropertyNotFoundException(message); 
    } 

    Integer index = IMPLICIT_OBJECTS.get(property.toString()); 

    if (index == null) { 
     return null; 
    } else { 
     FacesContext facesContext = (FacesContext) context.getContext(FacesContext.class); 
     ExternalContext extCtx = facesContext.getExternalContext(); 
      switch (index) { 

      case COMPOSITE_COMPONENT: 
       // The following five lines violate the specification. 
       // The specification states that the 'cc' implicit object 
       // always evaluates to the current composite component, 
       // however, this isn't desirable behavior when passing 
       // attributes between nested composite components, so we 
       // need to alter the behavior so that the components behave 
       // as the user would expect. 
       /* BEGIN DEVIATION */ 
       CompositeComponentStackManager manager = 
         CompositeComponentStackManager.getManager(facesContext); 
       Object o = manager.peek(); 
       /* END DEVIATION */ 
       if (o == null) { 
        o = UIComponent.getCurrentCompositeComponent(facesContext); 
       } 
       context.setPropertyResolved(o != null); 
       return o; 
      case PARAM: 
       context.setPropertyResolved(true); 
       return extCtx.getRequestParameterMap(); 
      case PARAM_VALUES: 
       context.setPropertyResolved(true); 
       return extCtx.getRequestParameterValuesMap(); 
      case CONTEXT_PATH: 
       context.setPropertyResolved(true); 
       return extCtx.getRequestContextPath(); 
      case RESOURCE: 
       context.setPropertyResolved(true); 
       return facesContext.getApplication().getResourceHandler(); 
      default: 
       return null; 
     } 
    } 
} 

}

接下来,在faces-config.xml中,添加如下条目:

<application> 
    <el-resolver> 
     com.example.templates.jsf.CustomImplicitObjectELResolver 
    </el-resolver> 
</application>