我一直在試圖弄清楚這一點,現在閱讀很多博客,MSDN文檔,示例代碼和其他stackoverflow問題,並且尚未得到此上班。在Web角色和客戶端應用程序之間共享ASP.NET簡單會員身份驗證
這是我的場景:
我使用Windows Azure來承載兩個Web角色。一個是我的MVC4 web API,另一個是我使用web API的MVC4 web應用程序。我還有許多使用.NET的客戶端應用程序,它們將訪問Web API。
所以我的主要組成部分是:
- 的Web API
- Web App的
- .NET客戶端
我想使用在Web應用程序 '託管' 的形式驗證。我正在使用內置的simplemembership身份驗證機制,它工作得很好。我可以創建並登錄到Web App中的帳戶。
現在我還想使用這些相同的帳戶從Web應用程序和任何.NET客戶端應用程序對Web API進行身份驗證。
我讀過很多方法來做到這一點,最簡單的似乎是在Web API上使用基本身份驗證。目前我正在處理這個代碼,因爲它似乎解決了我的確切問題:Mixing Forms Authentication, Basic Authentication, and SimpleMembership
我無法得到這個工作。我成功登錄到我的Web應用程序(127.0.0.1:81),並且當我嘗試調用需要驗證的Web API(例如127.0.0.1:8081/api/values)時,調用失敗,出現401(未授權)迴應。在單步執行代碼時,WebSecurity.IsAuthenticated返回false。 WebSecurity.Initialized返回true。
我實現了這個代碼,我試圖打電話給我的Web API從我的Web應用程序使用下面的代碼(登錄後):
using (var handler = new HttpClientHandler())
{
var cookie = FormsAuthentication.GetAuthCookie(User.Identity.Name, false);
handler.CookieContainer.Add(new Cookie(cookie.Name, cookie.Value, cookie.Path, cookie.Domain));
using (var client = new HttpClient())
{
//client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
// "Basic",
// Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(
// string.Format("{0}:{1}", User.Identity.Name, "123456"))));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Cookie",
Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(User.Identity.Name)));
string response = await client.GetStringAsync("http://127.0.0.1:8080/api/values");
ViewBag.Values = response;
}
}
正如你所看到的,我都嘗試使用該cookie以及用戶名/密碼。很明顯,我想使用cookie,但在這一點上,如果有任何工作,這將是一個很好的步驟!
我ValuesController在我的Web API正確裝飾:
// GET api/values
[BasicAuthorize]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
在我在我的Web API的Global.asax.cs,我初始化SimpleMembership:
// initialize our SimpleMembership connection
try
{
WebSecurity.InitializeDatabaseConnection("AzureConnection", "User", "Id", "Email", autoCreateTables: false);
}
catch (Exception ex)
{
throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex);
}
這種成功和WebSecurity後說它已經初始化,所以我猜這部分工作正常。
我的配置文件具有匹配的驗證設置,根據需要按照MSDN。
這裏是API配置:
<authentication mode="Forms">
<forms protection="All" path="/" domain="127.0.0.1" enableCrossAppRedirects="true" timeout="2880" />
</authentication>
<machineKey decryption="AES" decryptionKey="***" validation="SHA1" validationKey="***" />
這裏是Web應用程序配置:
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" protection="All" path="/" domain="127.0.0.1" enableCrossAppRedirects="true" timeout="2880" />
</authentication>
<machineKey decryption="AES" decryptionKey="***" validation="SHA1" validationKey="***" />
注意,我在當地嘗試這種(因此127.0.0.1域),但引用數據庫託管在Azure上。
我沒有必要從.NET客戶端應用程序嘗試這些,因爲我甚至無法在Web角色之間使用它。對於客戶端應用程序,理想情況下,我將進行網絡通話,傳遞用戶名/密碼,檢索cookie,然後使用cookie進一步提供Web API請求。
我想得到我工作的東西,因爲它看起來非常簡單並且符合我的要求。
我還沒有嘗試其他解決方案,如Thinktecture,因爲它具有比我需要的更多功能,而且似乎沒有必要。
我錯過了什麼?
我已經多次閱讀過這個問題,但我仍然不確定問題是什麼,或者發生了什麼故障。當您嘗試使用服務器端代碼從Web應用程序調用Web API時,它失敗嗎?什麼是失敗?您是否收到任何錯誤或是否是意外的行爲? –
對於初學者,我不建議從服務器端代碼調用Web API。這是不必要的網絡流量。看看這個建議的架構[http://stackoverflow.com/questions/14887871/creating-a-service-layer-for-my-mvc-application/14896644#14896644],它可以讓你直接訪問你的應用程序域。您仍然可以使用自定義ClaimsAuthorizationManager在沒有Web API調用的情況下處理授權。 –
對不起,不把我的具體錯誤在那裏。我花了很多時間試圖把所有的細節都放進去,並且錯過了最重要的一個細節。從服務器端代碼調用時,確實無法使用Web API進行授權。 –