2013/6/28

使用 VS2013 Preview 開發 ASP.NET 專案並登入 AD

下載 Visual Studio 2013 Preview 之後, 我迫不急待地把它安裝起來, 並且建立了幾個測試用的專案。我把幾個值得注意的細節記錄起來, 同時供大家做個參考。

首先, 如果你的系統已經安裝了 VS2012 的話, 我建議你先去下載並安裝 VS2012 Update 3, 如此, 這兩個版本的專案才能正確地共用。

其次, 如果你建立一個 ASP.NET Web Form 專案, 而且你選擇使用「個別使用者帳戶」的驗證方式的話, 那麼你可能會遇到一件意外的事情 (不是每次都會發生), 就是在你什麼都還沒做之前, 就會發生專案無法編譯的情況。你有可能看到 "IAppBuilder" 未定義, 或者 "Newtonsoft.json" 找不到之類的莫名其妙的編譯錯誤。

所幸, 這個錯誤是可以解決的。萬一遇到了, 你只需要使用 NuGet 去安裝 Json.Net 以及 Owin 這兩個套件, 這樣就可以了。

另外, 如果你為專案選擇使用「Windows 驗證」這種驗證方式, 那麼你要如何使用程式去存取使用者身分和資訊? 假設你是在公司裡, 並且透過 Active Directory 登入網域, 那麼, 你可以透過 DirectoryService 命名空間下的類別去取得使用者資訊。以下是我的範例程式:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;

namespace WebApplication2
{
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
PrincipalContext pc = null;
UserPrincipal principal = null;
try
{
var username = Thread.CurrentPrincipal.Identity.Name;
pc = new PrincipalContext(ContextType.Domain, "你的網域");
principal = UserPrincipal.FindByIdentity(pc, username);

var firstName = principal.GivenName ?? string.Empty;
var lastName = principal.Surname ?? string.Empty;
lb.Text = string.Format("Hello, {0} {1}!", firstName, lastName);
}
catch(Exception ex) {

}
finally
{
if (principal != null) principal.Dispose();
if (pc != null) pc.Dispose();
}
}
}
}

程式中「你的網域」請使用你的網域名稱取代, 例如 "ABCD" 或者 "abcd.com"。

如此, 照理說, 如果使用者一開機就已經登入網域, 那麼他一開啟網頁, 就應該已經是登入的狀況 (除非他沒有權限)。

上面這個程式也可以改得更簡單一些, 例如

string roleToCheck = "Administrators";
ViewBag.Message = string.Format("{0} belongs to {1}? {2}",
User.Identity.Name, roleToCheck, User.IsInRole(roleToCheck));

如果你希望在程式中經由 AD 做些管理性的工具, 那麼步驟稍為繁複一點。你必須先在 Web.config 檔案中加入 connectionString 等等:

<configuration>
<connectionStrings>
<add name="ADService" connectionString="LDAP://ABCD/DC=abcd,DC=com,DC=tw" />
</connectionStrings>
<system.web>
<membership defaultProvider="AspNetActiveDirectoryMembershipProvider">
<providers>
<add name="AspNetActiveDirectoryMembershipProvider" connectionStringName="ADService"
type="System.Web.Security.ActiveDirectoryMembershipProvider,
System.Web, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a"
connectionUsername="具管理權限的帳號"
connectionPassword="密碼"
connectionProtection="None"
attributeMapUsername="sAMAccountName"
applicationName="/" />
</providers>
</membership></configuration>

上面假設你的網域名稱是 "abcd.com"; 請把帳號和密碼填上去, 然後你就有權限取得 AD 中的資訊了。程式的部份如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;

namespace WebApplication2
{
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
lb.Text = Membership.GetUser("johnny.net").UserName;
}
}
}

在如上的程式中, 你可以透過 Membership 類別從 AD 取得 "johnny.net" 這個使用者的 UserName (以及其它相關) 資訊。

此外, 如果你另外安裝了 ASP.NET and Web Tools Refresh (只有英文版) 的話, 那麼在新建 Web Application 的時候, 會額外出現一個 Organization Account 驗證方式, 如下圖所示:

Configure Authentication

可惜的是, 我不建議你安裝這個 Refresh 更新, 因為這個套件只有英文版本, 安裝了它之後, 會導致你在新建 Web Application 專案時, 如果按下「設定驗證」按鈕, 會出現例外狀況而無法繼續, 必須重啟 VS2013 Preview 才行。還好這是有解法的, 就是去下載 VS2013 Preview 的英文版語言套件並且安裝, 然後把介面切換成英文版。

暫時切換回英文介面雖然可以解決這個問題, 但如果你把這個 Refresh 更新解除安裝的話, 它會一併把 VS2013 Preview 中的 Web Application 樣版一併解除安裝! 換句話說, 你就再也無法新建 Web Application 專案了。不過, 這個現象也是有解法的, 就是重新執行 VS2013 Preview 的安裝程式, 然後使用「修復」功能即可。

這個 Refresh 更新到底提供了什麼功能呢? 根據上述的文件,

"This release updates Visual Studio 2013 Preview with updates for ASP.NET and associating tooling. Features and updates include: • One ASP.NET with updated templates • Extensible Scaffolding Fx with new Web Forms Scaffolds and improved MVC scaffolds • VS tooling enhancements - Libra, Browser Link • New Authentication & Identity Model • New Web API and SignalR functionality."

如前所述, 安裝這個更新之後, 它新增了 Web Application 一個 Organization Account 驗證方式, 其主要功能是讓你可以進行雲端 SSO 驗證方式。如果你沒有這個需求, 也不需要另外幾個小功能增強, 那麼你就沒有安裝這個更新的必要。如本文一開始講的, 透過 Windows 驗證就足以進行 AD 身份驗證了。

至於 VS2012 的話, 你可以採用 MSDN 上建議的做法以登入網域。雖然這篇文章適用的是 .NET Framework 3.5, 但我使用 VS2012 測試過, 遵照文章內描述的程序處理後, 證實它完全可用。事實上, 你也可以透過它的範例程式中的 GetGroups() 方法, 在使用者登入時同時取回他在 AD 上的所屬 Groups 列表。

不過有個值得注意的地方, 就是 GetGroups 只能在使用者認證成功 (或者使用 IsAuthenticated() 方法) 之後才能呼叫。因為, 我個人是直接在 Login 網頁內進行 IsAuthenticated() 方法後立即取得 Groups 並存進 Cookies 裡面備用。當然, 你不一定要存在 Cookies 裡, 存在你認為合適的地方也可以。總之, 你不能在整個認證程序結束以後才去呼叫 GetGroups() 方法就對了。

沒有留言:

張貼留言