2013-11-26 52 views
2

我的web.xml中有一個安全約束,因此「restrict」文件夾內的所有頁面都受到保護,用戶無法手動輸入它們。將參數發送到受限制的頁面(無GET方法)

的web.xml

<security-constraint> 
    <display-name>restrict</display-name> 
    <web-resource-collection> 
     <web-resource-name>Restric Access</web-resource-name> 
     <url-pattern>/restrict/*</url-pattern> 
     <http-method>DELETE</http-method> 
     <http-method>PUT</http-method> 
     <http-method>HEAD</http-method> 
     <http-method>OPTIONS</http-method> 
     <http-method>TRACE</http-method> 
     <http-method>GET</http-method> 
    </web-resource-collection> 
    <auth-constraint /> 
</security-constraint> 

在這些頁面中的一個,我想傳遞參數給使用下面的導航規則的其他頁面。

faces-config.xml中

<navigation-rule> 
    <from-view-id>/restrict/ranking.xhtml</from-view-id> 
    <navigation-case> 
     <from-outcome>editPerson</from-outcome> 
     <to-view-id>/restrict/person.xhtml</to-view-id> 
     <redirect include-view-params="true"> 
      <view-param> 
       <name>idPerson</name> 
       <value>#{ranking.person.idPerson}</value> 
      </view-param>   
     </redirect> 
    </navigation-case> 
</navigation-rule> 

但是這是不可能的,因爲我限制了GET方法,而我得到"Access to the requested resource has been denied"。 那麼,將參數傳遞給其他頁面的正確方法是什麼?

  1. 使用@SessionScoped @ManagedBean來設置一個會話變量,並重新設置它,只要我在其他頁面中使用?

  2. 使用FacesContext.getCurrentInstance()。getExternalContext()。getSessionMap()在我使用它們時立即添加和刪除屬性?

  3. 還是什麼?

我很擔心前兩個建議,因爲用戶可能會在瀏覽器中打開很多選項卡來使用我的應用程序,所以對於所有選項卡只有一個值。


編輯:關於我得到的錯誤,還有在控制檯沒有堆棧跟蹤我正在重定向到的頁面是這樣的:

HTTP Status 403 - Access to the requested resource has been denied 
type Status report 
message Access to the requested resource has been denied 
description Access to the specified resource has been forbidden. 
Apache Tomcat/7.0.47 

爲了解決這個錯誤,我可以簡單地刪除我的安全約束中的<http-method>GET</http-method>,但我可以手動輸入頁面。

+0

是誰提出這個例外?你能發佈你的堆棧跟蹤的相關位嗎? –

+0

看到我編輯的問題Harsha。謝謝。 – qxlab

+0

爲什麼你需要''?如果你不希望資源是冪等的,就省略它。如果您只是基於位於'/ WEB-INF'中的模板/包含已經不可公開訪問的情況下將結果有條件地呈現在相同視圖中,那麼整個安全約束也沒有多大意義。 – BalusC

回答

1

您已經封鎖了GET,所以<redirect>絕對不會起作用,因爲它實際上會創建一個新的GET請求。又見What is the difference between redirect and navigation/forward and when to use what?

你能做什麼?如果實際上不是通過使用includes等方式有條件地在同一視圖中呈現結果的選項(以便您可以繼續使用相同的視圖範圍的bean實例),那麼您應該只執行一次POST導航而不用重定向。您可能已經認識到導航會在創建新視圖之前立即銷燬綁定到當前視圖的所有視圖範圍的bean。因此,在「當前」視圖作用域bean中只能執行「previous」視圖作用域bean的@ManagedProperty是不可能的。它會給你一個沒有原始屬性的全新實例。

然而,因爲沒有一個重定向的POST導航都發生在很相同要求,你其實並不需要沿着session範圍內通過的任何數據,它的工作好通過請求範圍。您只需立即在與目標頁面關聯的視圖範圍bean的@PostConstruct中抓取它。這些數據絕對不會在其他請求中共享。

基本過程可以去如下(後臺bean和屬性名稱只是學歷到目前爲止提供基於信息猜測):

<h:dataTable value="#{ranking.persons}" var="person"> 
    <h:column>#{person.id}</h:column> 
    <h:column>#{person.name}</h:column> 
    <h:column>#{person.email}</h:column> 
    <h:column><h:commandButton value="edit" action="#{ranking.editPerson(person)}" /></h:column> 
</h:dataTable> 
@ManagedBean(name="ranking") 
@ViewScoped 
public class RankingBacking implements Serializable { 

    private List<Person> persons; 

    public String editPerson(Person person) { 
     ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext(); 
     ec.getRequestMap().put("person", person); 
     return "editPerson"; 
    } 

    // ... 
} 
@ManagedBean(name="person") 
@ViewScoped 
public class PersonBacking implements Serializable { 

    private Person current; 

    @PostConstruct 
    public void init() { 
     ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext(); 
     current = (Person) ec.getRequestMap().get("person"); 
    } 

    // ... 
} 
<h:outputText value="#{person.current.id}" /> 
<h:inputText value="#{person.current.name}" /> 
<h:inputText value="#{person.current.email}" /> 
... 
<h:commandButton value="Save" ... /> 
+0

非常感謝!以這種方式使用請求對我來說是全新的! – qxlab

+0

很高興爲您服務。 – BalusC

相關問題