使用 AngularJS、WebAPI 2 和 Oauth 2 時,如何將授權資訊發送回我的客戶端應用程序?
我有一個
AngularJS客戶端應用程序,它使用javascript(不是咖啡腳本或打字稿)Oauth2 對WebAPI 2使用最新的Identity 2. 我的應用程序中的所有軟體都是最新的,並且基於this example. 我的客戶端瀏覽器目標是 IE9 及更高版本。請注意,我對上面的範例做了一些小的更改,因為我沒有對使用轉換發送到伺服器的所有數據進行 urlencode。相反,我只在下面的身份驗證方法中進行 urlencode:
user.authenticate = function (userName, password, rememberMe, successCallback, errorCallback) { var config = { method: 'POST', url: '/Token', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, data: 'grant_type=password&username=' + encodeURIComponent(userName) + '&password=' + encodeURIComponent(password), };我正在使用 VS2013 Update 2 進行開發,在伺服器上,我使用 C#、最新的實體框架和 SQL Server 2012。
登錄我的客戶端呼叫 WebAPI 的 /Token 方法並傳遞使用者 ID 和密碼。WebAPI 然後用一個令牌響應我儲存的客戶端。對於 WebAPI 的每個請求,都會將令牌發送回並進行身份驗證:
$http.defaults.headers.common.Authorization = 'Bearer ' + user.data.bearerToken;到目前為止,這工作得很好,但就目前而言,應用程序無法區分分配給他們不同角色的使用者之間的區別。
某些 WebAPI 方法只能由具有特定角色的使用者執行。我想調整我的前端 AngularJS 應用程序的菜單,以便只有當使用者具有此角色時,相應的連結才會可見。我確實意識到這不會阻止使用者檢查 HTML 和發布,但我並不擔心這一點,因為我仍然會使用方法修飾來限制非角色使用者執行操作的能力。
有人可以給我一個範例,說明如何僅使用我在問題中提到的上述產品套件以及 JavaScript Web Tokens 來做到這一點,如果它們有助於使解決方案保持最新狀態。據我了解,角色由聲明處理,但我不明白如何添加這些並使用令牌將它們發送回客戶端。我在網際網路上做了很多研究,但我找不到任何好的例子,因為我認為其中大部分都是非常新的,而且沒有多少人有機會探索 SPA 如何使用這些最新的軟體成分。
在回答這個問題時請注意,我不是在尋找可以告訴社區如何在伺服器上設置角色的答案,也不是在尋找解釋在伺服器上提供角色檢查的重要性的答案。我想幾乎每個人都知道這一點。我真正認為有用的是一些非常詳細的技術建議,帶有範常式式碼和解釋。為了保持答案的重點,如果不滿足此需求的答案未作為建議答案發布,可能會對每個人都有幫助。
先感謝您。
您的問題的簡短答案是
ApplicationOAuthProvider.CreateProperties方法。它預設為您創建,位於WebApi2/Provider/ApplicationOAuthProvider.cs下,預設情況下它只發送userName//WepApi2/Providers/ApplicationOAuthProvider.cs public static AuthenticationProperties CreateProperties(string userName) { IDictionary<string, string> data = new Dictionary<string, string> { { "userName", userName } }; return new AuthenticationProperties(data); }我會進行以下更新(以防我稍後需要發送更多使用者數據):
public static AuthenticationProperties CreateProperties(string userName, ClaimsIdentity oAuthIdentity) { IDictionary<string, string> data = new Dictionary<string, string> { { "userName", userName}, { "roles",string.Join(",",oAuthIdentity.Claims.Where(c=> c.Type == ClaimTypes.Role).Select(c => c.Value).ToArray())} }; return new AuthenticationProperties(data); }如果您沒有對 WebApi 項目進行重大更改,
ApplicationOAuthProvider.CreateProperties僅在兩個地方引用,只需更新呼叫程式碼以傳遞oAuthIdentity,user.UserName您將獲得與訪問令牌響應一起發送的使用者角色:{ "access_token": "ZpxAZyYuvCaWgShUz0c_XDLFqpbC0-DIeXl_tuFbr11G-5hzBzSUxFNwNPahsasBD9t6mDDJGHcuEqdvtBT4kDNQXFcjWYvFP7U2Y0EvLS3yejdSvUrh2v1N7Ntz80WKe5G_wy2t11eT0l48dgdyak8lYcl3Nx8D0cgwlQm-pePIanYZatdPFP9q5jzhD-_k9SF-ARTHgf0ePnbvhLBi1MCYQjvfgPKlbBHt0M5qjwGAeFg1IhSVj0gb4g9QTXoiPhRmxGBmjOpGgzxXixavmrpM7cCBFLoR3DCGnIJo6pwT-6VArxlB8-ZyyOZqh_6gGtptd0lIu8iJRUIGwO9HFNkROdoE9T4buwLnhPpWpy9geBjPVwsB1K3xnbch26YbklhxIHVybBxeIVXd17QTw_LjlQ5TJdqpAYfiZ5B9Nx2AFYYYe3--aemh4y1XOIvN", "token_type": "bearer", "expires_in": 1209599, "userName": "MK", "roles": "Admin,Public", ".issued": "Fri, 23 May 2014 17:36:54 GMT", ".expires": "Fri, 06 Jun 2014 17:36:54 GMT" }現在您有了可用的角色,您可以使用 Angular 條件指令根據使用者角色顯示/隱藏操作。
如果您需要更多說明,請告訴我。
編輯:
用屬性裝飾你的控制器方法
Authorize是有效的,因為HttpContext.Current.User.Identity它實際上是一個ClaimsIdentity. 但為了不在應用程序內部硬編碼安全邏輯,我更喜歡使用ClaimsAuthorizationManagerpublic ActionResult Secure() { if(!ClaimsPrincipalPermission.CheckAccess("resource", "action")) return new HttpUnauthorizedResult(); ViewBag.Message = "You are allowed to perform action on resource."; return View(); }角色創建使用
RoleManager:RoleManager roleManger = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>()); roleManager.Create(new IdentityRole() { Name = "Admin" });角色分配使用
UserManager:userManager.AddToRole(user.Id, "Admin");