2014-09-27 90 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]属性添加到用作身份验证过程一部分的每个操作方法,否则用户将无法浏览其各自的视图。

顺便说一句, 如果用户尝试键入,他会得到一个错误,因为他仍然需要令牌。