2014-09-27 56 views
0

我在這裏撞着我的頭撞牆。請幫忙。 我開發了一個MVC 4.0 web應用程序。 我正在使用Facebook SDK登錄到網站。 爲了討論起見,我有兩個操作方法:索引和信息。 索引是用戶點擊「使用Facebook登錄」按鈕的地方,並且在他輸入他的憑證後,他應該被重定向到信息操作方法。 (從那裏他可以註銷)。 這是該指數方法:如何拒絕匿名用戶直接調用操作方法?

[AllowAnonymous] 
    public ActionResult Index() 
    { 
     return View(); 
    } 

我在web.config中有這樣的:

 <authentication mode="Forms"> 
      <forms loginUrl="~/Home/Index" timeout="2880" /> 
     </authentication> 

這些都是我在Facebook的開發者進入我的應用程序的設置:

帆布網址:

http://localhost/[AppName]/ 

安全帆布網址:

https://localhost/[AppName]/ 

網站網址:

http://localhost/[AppName]/ 

有效的OAuth重定向的URI:

http://localhost/ 

http://localhost/[AppName]/home/index 

的問題是:

我想要做的只提供給授權用戶信息的操作方法,所以很自然,我飾它與[授權]屬性:

[Authorize] 
    public ActionResult Info() 
    { 
     var client = new FacebookClient(); 
     var oauthResult = client.ParseOAuthCallbackUrl(Request.Url); 
     // Build the Return URI form the Request Url 
     var redirectUri = new UriBuilder(Request.Url); 
     redirectUri.Path = Url.Action("Info", "Home"); 

     // Exchange the code for an access token 
     dynamic result = client.Get("/oauth/access_token", 
      new { client_id = AppId, 
       redirect_uri = redirectUri.Uri.AbsoluteUri, 
       client_secret = SecId, 
       code = oauthResult.Code }); 
     // Read the auth values 
     string accessToken = result.access_token; 
     Session["access_token"] = accessToken; 
     DateTime expires = DateTime.UtcNow.AddSeconds(Convert.ToDouble(result.expires)); 

     // Get the user's profile information 

     dynamic me = client.Get("/me", 
      new 
      { 
       fields = "first_name,last_name,email,picture", 
       access_token = accessToken 
      }); 

     var userInfo = new InfoModel() 
     { 
      firstName = me.first_name, 
      lastName = me.last_name, 
      emailId = me.email, 
      picture = me.picture, 
      accessToken = result.access_token 
     }; 
     return View("Info", userInfo); 
    } 

所以現在我有兩個unwated scenraios:我可以登錄到我的應用程序,但在登錄後,我被重定向到Home/Index,而不是Home/Info。

OR

我可以正常登錄(我重定向到首頁/信息登錄後,如預期),但我也可以直接瀏覽到信息的操作方法(因爲我不得不刪除[授權]屬性在

才能登錄。這就像一個魔方!

對不起後是漫長的,但我有詳細說明。

回答

0

我發現答案。 這是涉及一點點的解決方法,但它是一樣的OD:

[AllowAnonymous] 
    public ActionResult Info() 
    { 
     if (Request.Url.AbsoluteUri.Contains("Home/Info?code")) 
     { 
      var client = new FacebookClient(); 
      var oauthResult = client.ParseOAuthCallbackUrl(Request.Url); 
      // Build the Return URI form the Request Url 
      var redirectUri = new UriBuilder(Request.Url); 
      redirectUri.Path = Url.Action("Info", "Home"); 

      // Exchange the code for an access token 
      dynamic result = client.Get("/oauth/access_token", 
       new 
       { 
        client_id = AppId, 
        redirect_uri = redirectUri.Uri.AbsoluteUri, 
        client_secret = SecId, 
        code = oauthResult.Code 
       }); 
      // Read the auth values 
      string accessToken = result.access_token; 
      Session["access_token"] = accessToken; 
      DateTime expires = DateTime.UtcNow.AddSeconds(Convert.ToDouble(result.expires)); 

      // Get the user's profile information 

      dynamic me = client.Get("/me", 
       new 
       { 
        fields = "first_name,last_name,email,picture", 
        access_token = accessToken 
       }); 

      var userInfo = new InfoModel() 
      { 
       firstName = me.first_name, 
       lastName = me.last_name, 
       emailId = me.email, 
       picture = me.picture, 
       accessToken = result.access_token 
      }; 

      FormsAuthentication.SetAuthCookie(userInfo.emailId, true); 
      return View("Info", userInfo); 
     } 
     else 
      return View("Index"); 
    } 

正如你看到的,我在操作方法開始一個條件: 當且僅當URL包含單詞「代碼」,那麼用戶可以進行身份​​驗證,否則,他是重定向回到第一頁。 如果「代碼」這個詞存在,這意味着用戶有一個令牌,因此他已經正確地輸入了他的憑證,所以現在他的細節可以被提取。 在提取過程結束,只是重定向到視圖之前,我補充說:

FormsAuthentication.SetAuthCookie(userInfo.emailId, true); 

爲了挽救餅乾。這是[Authorize]屬性正確運行所需的內容,否則代碼的行爲就像您未通過身份驗證一樣,即使您是這樣。

現在我可以安全地將[Authorize]屬性添加到所有我希望僅供認證用戶使用的操作方法。 不要忘記將[AllowAnonymous]屬性添加到用作身份驗證過程一部分的每個操作方法,否則用戶將無法瀏覽其各自的視圖。

順便說一句, 如果用戶嘗試鍵入,他會得到一個錯誤,因爲他仍然需要令牌。