2012-09-12 27 views
10

Đó là một bài viết đã lỗi thời, nhưng http://msdn.microsoft.com/en-us/library/ff650308.aspx#paght000026_step3 minh họa những gì tôi muốn làm. Tôi đã chọn Nancy làm khung web vì nó đơn giản và phương pháp tiếp cận thấp. Vì vậy, tôi cần một cách để xác thực đối với Active Directory bằng cách sử dụng Nancy.Làm thế nào tôi có thể xác thực đối với Active Directory ở Nancy?

Trong ASP.NET, có vẻ như bạn chỉ có thể chuyển đổi giữa nhà cung cấp thành viên dựa trên db và Active Directory chỉ bằng một số cài đặt trong tệp web.config của bạn. Tôi không cần điều đó một cách cụ thể, nhưng khả năng chuyển đổi giữa dev và sản xuất sẽ thật tuyệt vời.

Làm cách nào để thực hiện điều này?

+1

Bằng cách này, nếu điều này không có sẵn ngay bây giờ, tôi sẽ góp phần nó .. bất cứ hướng dẫn tại đó hướng sẽ cũng hữu ích. –

+0

Tôi vừa thêm một vấn đề vào repo Nancy: https://github.com/NancyFx/Nancy/issues/742 –

Trả lời

13

Thực sự giải pháp đơn giản hơn nhiều so với khả năng của nó. Chỉ cần nghĩ về Active Directory như một kho lưu trữ cho người dùng của bạn (giống như một cơ sở dữ liệu). Tất cả những gì bạn cần làm là truy vấn AD để xác minh rằng tên người dùng và mật khẩu đã nhập là hợp lệ. SO, chỉ cần sử dụng Xác nhận biểu mẫu của Nancy và xử lý sự kết nối với AD trong việc triển khai IUserMapper của bạn. Dưới đây là những gì tôi đã đưa ra cho mapper người dùng của tôi:

public class ActiveDirectoryUserMapper : IUserMapper, IUserLoginManager 
{ 
    static readonly Dictionary<Guid, long> LoggedInUserIds = new Dictionary<Guid, long>(); 

    readonly IAdminUserValidator _adminUserValidator; 
    readonly IAdminUserFetcher _adminUserFetcher; 
    readonly ISessionContainer _sessionContainer; 

    public ActiveDirectoryUserMapper(IAdminUserValidator adminUserValidator, IAdminUserFetcher adminUserFetcher, ISessionContainer sessionContainer) 
    { 
     _adminUserValidator = adminUserValidator; 
     _adminUserFetcher = adminUserFetcher; 
     _sessionContainer = sessionContainer; 
    } 

    public IUserIdentity GetUserFromIdentifier(Guid identifier, NancyContext context) 
    { 
     _sessionContainer.OpenSession(); 
     var adminUserId = LoggedInUserIds.First(x => x.Key == identifier).Value; 
     var adminUser = _adminUserFetcher.GetAdminUser(adminUserId); 
     return new ApiUserIdentity(adminUser); 
    } 

    public Guid Login(string username, string clearTextPassword, string domain) 
    { 
     var adminUser = _adminUserValidator.ValidateAndReturnAdminUser(username, clearTextPassword, domain); 
     var identifier = Guid.NewGuid(); 
     LoggedInUserIds.Add(identifier, adminUser.Id); 
     return identifier; 
    } 
} 

Tôi đang giữ một kỷ lục trong cơ sở dữ liệu của tôi để xử lý vai trò, vì vậy lớp này handle xác minh với AD và lấy người sử dụng từ cơ sở dữ liệu:

public class AdminUserValidator : IAdminUserValidator 
{ 
    readonly IActiveDirectoryUserValidator _activeDirectoryUserValidator; 
    readonly IAdminUserFetcher _adminUserFetcher; 

    public AdminUserValidator(IAdminUserFetcher adminUserFetcher, 
           IActiveDirectoryUserValidator activeDirectoryUserValidator) 
    { 
     _adminUserFetcher = adminUserFetcher; 
     _activeDirectoryUserValidator = activeDirectoryUserValidator; 
    } 

    #region IAdminUserValidator Members 

    public AdminUser ValidateAndReturnAdminUser(string username, string clearTextPassword, string domain) 
    { 
     _activeDirectoryUserValidator.Validate(username, clearTextPassword, domain); 

     return _adminUserFetcher.GetAdminUser(1);    
    } 

    #endregion 
} 

Và lớp này thực sự xác nhận rằng sự kết hợp giữa tên người dùng/mật khẩu tồn tại trong Active Directory:

public class ActiveDirectoryUserValidator : IActiveDirectoryUserValidator 
{ 
    public void Validate(string username, string clearTextPassword, string domain) 
    { 
     using (var principalContext = new PrincipalContext(ContextType.Domain, domain)) 
     { 
      // validate the credentials 
      bool isValid = principalContext.ValidateCredentials(username, clearTextPassword); 
      if (!isValid) 
       throw new Exception("Invalid username or password."); 
     } 

    } 
} 
+0

Nitor nhỏ: thay vì 'LoggedInUserIds.First (x => x.Key == identifier) ​​.Value' , bạn không thể làm 'LoggedInUserIds [identifier]'? Ngoài ra 'LoggedInUserIds [identifier] = adminUser.Id' trong phương thức' Login'. –

+0

Điều này có thể được thực hiện như một gói Nuget Nancy.ActiveDirectoryAuthentication không? – pashute

+0

@pashute [Thảo luận AD] (https://github.com/NancyFx/Nancy/issues/742) tại bộ theo dõi vấn đề của Nancy (liên kết ngược với câu trả lời này) – Omni

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