12

Tôi đang làm việc trên ứng dụng mạng nội bộ MVC 4 và đang sử dụng xác thực Windows. Tôi muốn thêm vào đối tượng người dùng mà phương thức xác thực sử dụng (@User) và nhận dữ liệu đó từ thư mục hoạt động (chẳng hạn như email, số điện thoại, v.v.).Nhận thông tin người dùng Active Directory với xác thực Windows trong MVC 4

Tôi biết tôi có thể tạo thuộc tính ủy quyền tùy chỉnh và thêm nó vào bộ điều khiển mà tất cả các bộ điều khiển khác của tôi kế thừa, nhưng tôi không biết đây có phải là phương pháp phù hợp để thực hiện những gì tôi muốn hay không.

Mục tiêu cuối cùng của tôi rất đơn giản, tôi muốn đối tượng @User có các thuộc tính bổ sung được điền thông qua Active Directory. Cảm ơn vì những giúp đỡ của bạn.

Trả lời

28

Tôi vừa thêm câu hỏi của riêng mình vào StackOverflow với giải pháp của mình để giúp những người khác gặp vấn đề này, khi tôi thấy câu hỏi hiện tại của bạn. Có vẻ như đây sẽ là một điều rất phổ biến, nhưng thông tin về cách thực hiện nó chỉ được trải ra giữa nhiều nguồn và khó theo dõi. Không chỉ có một nguồn tài nguyên hoàn chỉnh, vì vậy hy vọng điều này sẽ giúp bạn và những người khác.

Cách tốt nhất để làm điều này là sử dụng phần mở rộng UserPrincipal. Về cơ bản, bạn đang phân lớp UserPrincipal từ System.DirectoryServices.AccountManagement và thêm thuộc tính bổ sung của riêng bạn. Điều này được kích hoạt thông qua các phương pháp ExtensionGetExtensionSet (hơi huyền diệu).

[DirectoryRdnPrefix("CN")] 
[DirectoryObjectClass("user")] 
public class UserPrincipalExtended : UserPrincipal 
{ 
    public UserPrincipalExtended(PrincipalContext context) : base(context) 
    { 
    } 

    public UserPrincipalExtended(PrincipalContext context, string samAccountName, string password, bool enabled) 
     : base(context, samAccountName, password, enabled) 
    { 
    } 

    [DirectoryProperty("title")] 
    public string Title 
    { 
     get 
     { 
      if (ExtensionGet("title").Length != 1) 
       return null; 

      return (string)ExtensionGet("title")[0]; 
     } 

     set 
     { 
      ExtensionSet("title", value); 
     } 
    } 

    [DirectoryProperty("department")] 
    public string Department 
    { 
     get 
     { 
      if (ExtensionGet("department").Length != 1) 
       return null; 

      return (string)ExtensionGet("department")[0]; 
     } 

     set 
     { 
      ExtensionSet("department", value); 
     } 
    } 

    public static new UserPrincipalExtended FindByIdentity(PrincipalContext context, string identityValue) 
    { 
     return (UserPrincipalExtended)FindByIdentityWithType(context, typeof(UserPrincipalExtended), identityValue); 
    } 

    public static new UserPrincipalExtended FindByIdentity(PrincipalContext context, IdentityType identityType, string identityValue) 
    { 
     return (UserPrincipalExtended)FindByIdentityWithType(context, typeof(UserPrincipalExtended), identityType, identityValue); 
    } 
} 

Hai thuộc tính trên lớp cần được tùy chỉnh cho cá thể AD của bạn. Giá trị cho DirectoryRdnPrefix cần phải là RDN (tên phân biệt tương đối) trong AD, trong khi giá trị cho DirectoryObjectClass cần phải là tên loại đối tượng thư mục trong AD cho lớp userObject. Đối với thiết lập Dịch vụ miền AD điển hình, cả hai đều nên được sử dụng trong mã được trình bày ở trên, nhưng đối với thiết lập LDS, chúng có thể khác nhau. Tôi đã thêm hai thuộc tính mới mà tổ chức của tôi sử dụng, "tiêu đề" và "bộ phận". Từ đó, bạn có thể có ý tưởng về cách thêm bất kỳ thuộc tính nào khác mà bạn thích: về cơ bản bạn chỉ cần tạo thuộc tính bằng mẫu mà tôi đã cung cấp tại đây. Thuộc tính có thể được đặt tên bất cứ thứ gì bạn thích, nhưng giá trị chuỗi được chuyển đến DirectoryProperty và bên trong khối mã phải khớp với tên thuộc tính từ AD. Với điều đó tại chỗ, bạn có thể sử dụng PrincipalContext với lớp con của mình thay vì UserPrincipal để lấy lại đối tượng người dùng với các thuộc tính bạn cần thêm.

UserPrincipalExtended user = UserPrincipalExtended.FindByIdentity(
    new PrincipalContext(ContextType.Domain), User.Identity.Name); 

Và truy cập vào tài sản của bạn giống như bất kỳ khác trên UserPrincipal dụ:

// User's title 
user.Title 

Nếu bạn không quen với System.DirectoryServices.AccountManagement.UserPrincipal, có một vài thuộc tính người dùng nướng trong: GivenName, Surname, DisplayName vv Đặc biệt đối với hoàn cảnh của bạn, vì bạn đã đề cập đến điện thoại và email cụ thể, có VoiceTelephoneNumberEmailAddress. Bạn có thể xem danh sách đầy đủ trong số MSDN docs. Nếu tất cả những gì bạn cần là thông tin tích hợp, bạn không cần phải mở rộng UserPrincipal như tôi đã trình bày ở trên. Bạn chỉ cần làm:

UserPrincipal user = UserPrincipal.FindByIdentity(
    new PrincipalContext(ContextType.Domain), User.Identity.Name); 

Nhưng, 9 lần trong số 10, số lần cài sẵn sẽ không đủ, vì vậy bạn nên biết cách để phần còn lại dễ dàng.

Cuối cùng, tôi không muốn phải thêm @using dòng vào bất kỳ chế độ xem nào sử dụng điều này, vì vậy tôi đã tiếp tục và thêm các không gian tên vào web.config của Views của thư mục.Phần đó là quan trọng, nó cần phải được thêm vào web.config của thư mục Views, không phải của dự án (và mỗi thư mục riêng của từng khu vực Views nếu bạn đang sử dụng các Vùng).

<system.web.webPages.razor> 
    ... 
    <pages pageBaseType="System.Web.Mvc.WebViewPage"> 
     <namespaces> 
      ... 
      <add namespace="System.DirectoryServices.AccountManagement" /> 
      <add namespace="Namespace.For.Your.Extension" /> 
     </namespaces> 
    </pages> 
</system.web.webPages.razor> 
+0

Tôi thích phần mở rộng này, nhưng tôi không có kinh nghiệm với các lớp userprincipal. Tôi đã thay thế các kiểu UserPrincipal của mình bằng lớp mới này nhưng có lỗi khi gọi phương thức FindByIdentity tĩnh. Thông tin bổ sung: Các đối tượng chính của kiểu UserPrincipalExtended không thể được sử dụng trong một truy vấn đối với cửa hàng này. Bất kỳ ý tưởng về lý do tại sao nó không thành công? –

-1
[DirectoryRdnPrefix("CN")] 
[DirectoryObjectClass("user")] 

Những chưa được công nhận. Bạn vừa tạo ra một điều khiển trong dự án dao cạo 4 mvc của bạn?

tôi không thể cũng tìm hoặc thêm tài liệu tham khảo System.DirectoryServices.AccountManagement

Các vấn đề liên quan