2012-10-12 161 views
2

我一直在學習如何授權在ASP.Net WebApi中工作,我遇到了另一篇文章(ASP.NET Web API Authentication)中Darin Dimitrov的回答,我需要一些幫助來理解爲什麼我得到一個401ASP.NET WebApi FormsAuthentication 401(未授權)問題

繼Darin的代碼,我創建了一個項目的WebAPI並添加以下控制器和型號:

AccountController.cs

using System.Web.Http; 
using System.Web.Security; 
using AuthTest.Models; 

namespace AuthTest.Controllers 
{ 
    public class AccountController : ApiController 
    { 
     public bool Post(LogOnModel model) 
     { 
      if (model.Username == "john" && model.Password == "secret") 
      { 
       FormsAuthentication.SetAuthCookie(model.Username, false); 
       return true; 
      } 

      return false; 
     } 
    } 
} 

UsersController.cs

using System.Web.Http; 

namespace AuthTest.Controllers 
{ 
    [Authorize] 
    public class UsersController : ApiController 
    { 
     public string Get() 
     { 
      return "This is top secret material that only authorized users can see"; 
     } 
    } 
} 

LogOnModel.cs

namespace AuthTest.Models 
{ 
    public class LogOnModel 
    { 
     public string Username { get; set; } 
     public string Password { get; set; } 
    } 
} 

我已經創建了兩個按鈕,一個Web窗體應用程序,用於測試目的的標籤。

Default.aspx.cs

using System; 
using System.Net.Http; 
using System.Threading; 

namespace AuthTestWebForms 
{ 
    public partial class _Default : System.Web.UI.Page 
    { 
     protected void Page_Load(object sender, EventArgs e) 
     { 
     } 

     protected void ButtonAuthorizeClick(object sender, EventArgs e) 
     { 
      using (var httpClient = new HttpClient()) 
      { 
       var response = httpClient.PostAsJsonAsync(
        "http://localhost/authtest/api/account", 
        new { username = "john", password = "secret" }, 
        CancellationToken.None 
       ).Result; 
       response.EnsureSuccessStatusCode(); 

       bool success = response.Content.ReadAsAsync<bool>().Result; 
       if (success) 
       { 
        //LabelResponse.Text = @"Credentials provided"; 
        var secret = httpClient.GetStringAsync("http://localhost/authtest/api/users"); 
        LabelResponse.Text = secret.Result; 
       } 
       else 
       { 
        LabelResponse.Text = @"Sorry, you provided the wrong credentials"; 
       } 
      } 
     } 

     protected void ButtonTestAuthClick(object sender, EventArgs e) 
     { 
      using (var httpClient = new HttpClient()) 
      { 
       var secret = httpClient.GetStringAsync("http://localhost/authtest/api/users"); 
       LabelResponse.Text = secret.Result; 
      } 
     } 
    } 
} 

當我點擊按鈕,並運行ButtonAuthorizeClick()它觸發的賬戶控制器,然後觸發對用戶的控制,一切都很好。

如果我然後單擊ButtonTestAuthClick(),我得到一個401(未授權)錯誤。

當我在Chrome或FireFox中尋找ASPXAUTH cookie時,我沒有看到一個,所以我不能100%確定爲什麼ButtonAuthorizeClick()能夠工作,而我需要做什麼才能使ButtonTestAuthClick()工作。

感謝任何人的幫助可以拋開我的路。

回答

1

您正在呼叫中間帶有認證的web api。爲什麼不不通過ajax在客戶端驗證用戶?

這裏的問題是每次你通過HttpClient向web api發送一個請求,它實際上是一個由服務器處理的新的web請求。所有的cookie信息都不會保留在當前請求中。爲了支持這種情況,你需要自己處理cookie。

例如:如果響應中有cookieAssistant,則將cookie ASPXAUTH設置爲ButtonAuthorizeClick方法中的asp.net標頭。 將Cookie ASPXAUTH設置爲HttpRequestMessage並通過HttpClient發送。

Web api最近添加了一個使用HttpServer創建進程內服務器的支持,並可以直接向當前進程中的當前消息處理程序發送請求。所以,你可以編寫代碼,如:

HttpClient c = new HttpClient(new HttpServer(GlobalConfiguration.DefaultHandler)); 
c.GetStringAsync("http://localhost/api/Values").Wait(); 

要發送的進程內您的要求,使餅乾頭在web API動作在當前請求的管道將仍。登記入住似乎不在RTM版本中。你可以試試它每晚建立http://aspnetwebstack.codeplex.com/discussions/353867

6

我有一個類似的問題,雖然不是通過Web窗體客戶端頁面,而是通過JavaScript和AJAX調用。原來,我在web.config中留下了「無」的身份驗證模式。顯然,您必須在這裏打開Forms身份驗證才能使FormsAuthentication.SetAuthCookie()方法產生任何效果。

<authentication mode="Forms" /> 

一旦我解決了這個疏忽,一切都開始正常工作。 :-)

+0

Dang ...我的測試應用程序和api都有「Forms」設置,我仍然得到相同的響應。不過謝謝你的回答。 –

+0

解決了我的問題,謝謝 – JGilmartin

0

雖然晚了,但ButtonTestAuthClick中的客戶端不是瀏覽器。這裏是httpClient對象。因此,您需要以編程方式設置從其他按鈕生成的Cookie。