2009-11-02 80 views
1

是否可以阻止某個操作直接從瀏覽器執行,但仍可以從網站內部重定向到該操作?我知道這聽起來很愚蠢,但這是我想要的:ASP.Net中的會話固定MVC

假設有兩條路線,和Index2HomeController

www.website.com/home將導致索引被執行,然後我想執行一些代碼,然後重定向(或服務器傳輸)到www.website.com/home/index2

我不希望網址www.website.com/home/index2被用戶直接訪問,而不會先去home/index

有什麼我可以做的,以停用/激活路線在運行時?

編輯:對不起,這個問題是名爲「會話固定」因爲我需要Index到之前Index2運行,以確保我們正在殺死所有會話中Index和以前Index2執行更新它們。

由於Index2需要會話才能完成工作,我無法在相同的請求中終止會話並執行Index2中的代碼。

回答

1

好的,這就是我們最終做的。任何人看到這種方法的任何警告?

Index() 
{ 
    expire all session and forms-Authententication cookies 
} 

Index2() 
{ 
    if(Session.IsNewSession) 
    { 
     redirect to Index action 
    } 
    else 
    { 
    Show view 
    } 
} 
1

如果用戶被重定向到www.website.com/home/index2,那麼他們必須提出瀏覽器請求,即使它自動代表他們進行。防止這種情況的唯一方法是對檢查HTTP Referer的Index2操作執行檢查。

另一個選擇是讓Index返回Index2的ActionResult,這樣URL保持在/ home/index,但是返回Index2的結果,並且就用戶而言,他們從不被重定向。

+0

我想過使用referrer,但那不安全。 如果我返回ActionResult,這是否就像在同一個Action中執行這兩段代碼一樣? – Teto 2009-11-02 20:04:04

+0

您可以先執行常規Index操作的幕後代碼,然後在所有特定的Index()代碼之後有一行像'return Index2();'。 – 2009-11-02 20:57:01

3

如果您進行重定向,則不是。如果你做了一個重定向,它就會像控制器在瀏覽器(它所做的那樣)發生時一樣,出現在控制器上。您可以使用TempData進行一些操作 - 例如,在那裏設置一個標記,並且只在標記位於TempData時執行操作 - 但如果它不是來自瀏覽器的下一個請求,它將會失敗。也就是說,您可能會通過AJAX獲得另一個請求,該請求位於原始和重定向之間。 TempData將被該請求消除。

另一方面,如果您只是想執行代碼,則不要將Index2作爲公共方法公開並直接調用它。如果它在同一個控制器中,這應該是正常的。你最終會得到相同的URL,但如果它只是得到你想要的這個正確的視圖,那應該沒問題。

+0

謝謝,TempData可能是一個選項。將嘗試並讓你知道我是如何去的。請告訴我它不只是2.0功能? – Teto 2009-11-02 20:08:45

+0

TempData在MVC 1.0中可用。 – tvanfosson 2009-11-02 20:15:45

0

您可以定義路由:

routes.MapRoute(
      "Index2Redirect", 
      "HomeController/Index2", 
      new { controller = "HomeController", action = "Index", id = "" } 
     ); 

編輯:

不,這是不好的。

+0

如果Index重定向到Index2,那麼這會導致無限循環的重定向不是嗎? – tvanfosson 2009-11-02 19:59:21

1

你可以把一個ActionFilter,並從那裏做你的會議清理/等。這樣,您的代碼將始終在Index2之前執行 - 並且在您爲其添加此屬性的任何操作之前執行。

public class AbandonSessionAttribute: ActionFilterAttribute 
{ 
    public void OnActionExecuting(ActionFilterContext context) 
    { 
     if (Session.User.IsAuthenticated || Session.Count > 0) // <<-- this is the important line 
     { 
     Session.Clear(); 
     FormsAuthentication.SignOut(); // and so on 
     context.Result = new RedirectResult("/Index2"); 
     } 
    } 
} 

// now, if this is called with non-empty session, it will be cleared and user will be redirected again here 
[AbandonSession] 
public ActionResult Index2() 
{ 
} 

注意「這是重要的路線」。您需要檢測是否允許用戶輸入Index2。我通過檢查Session是否爲空來做到這一點。但是,在重定向MVC添加它自己的Session變量之後,Session永遠不會是空的,並且過濾器會一次又一次地重定向。您需要找出Session中可以呈現的內容。從你的問題中,不清楚(對我來說)如果任何導航到Index2應該清除會話 - 即在站點瀏覽期間。如果是這樣,上面的代碼是可以的,如果沒有的話 - 這取決於你決定如何檢測這個(例如,把某些東西放在某些頁面的會話中,並從其他頁面刪除)。

同樣,我不明白爲什麼會話不會爲你工作(順便說一句TempData 通過會話)。如果檢測到該請求的操作篩選器不是「乾淨」的,則會出現登錄,會話變量等 - 因此您要清理此問題並重新將重定向到同一操作 - 這會導致創建新會話等。這次過濾器沒有找到任何東西 - 因爲會話剛剛被清除 - 所以動作被允許執行。

+0

我的問題是,我需要確保完全「殺死」會話。即使用表單驗證cookie以及ASP.Net_SessionId之一。 Session.Abandon()和FormsAuthentication.SignOut()方法。 只有當新請求來自客戶端時(以及新的sessionId),新會話纔會啓動,因此所有這些使用會話的解決方案對我們都沒有用(因爲將從下一個請求開始使用新的會話ID)。一些示例代碼可能有幫助嗎? – Teto 2009-11-03 03:06:26