2012-09-12 2 views
10

Это устаревшая статья, но http://msdn.microsoft.com/en-us/library/ff650308.aspx#paght000026_step3 иллюстрирует, что я хочу делать. Я выбрал Nancy как свою веб-структуру из-за простоты и подхода с низкой оценкой. Итак, мне нужен способ аутентификации Active Directory с помощью Nancy.Как проверить подлинность Active Directory в Нэнси?

В ASP.NET похоже, что вы можете просто переключаться между поставщиком членства на основе db и Active Directory только по некоторым параметрам в файле web.config. Я не нуждаюсь в этом конкретно, но способность переключаться между dev и production будет потрясающей.

Как это можно сделать?

+1

Кстати, если это не доступно прямо сейчас, я буду способствовать его .. любое руководство в том, что направление Будьте полезны. –

+0

Я только что добавил проблему в репозиторий Нэнси: https://github.com/NancyFx/Nancy/issues/742 –

ответ

13

Действительно решение намного проще, чем может показаться. Просто подумайте о Active Directory как репозитории для своих пользователей (точно так же, как база данных). Все, что вам нужно сделать, это запрос AD, чтобы убедиться, что введенное имя пользователя и пароль действительны. ТАК, просто используйте Nancy's Forms Validation и обработайте связь с AD в вашей реализации IUserMapper. Вот что я придумал для моего пользователя картографа:

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; 
    } 
} 

Веда записи в моей базе данных для обработки ролей, поэтому этот класс ручки проверки с AD и извлечения пользователя из базы данных:

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 
} 

И этот класс фактически подтверждает, что комбинация имени пользователя/пароль существует в 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

Незначительный nitpick: вместо 'LoggedInUserIds.First (x => x.Key == identifier) ​​.Value' , не могли бы вы просто сделать 'LoggedInUserIds [идентификатор]'? Также 'LoggedInUserIds [identifier] = adminUser.Id' в методе' Login'. –

+0

Это может быть сделано как пакет Nuget Nancy.ActiveDirectoryAuthentication? – pashute

+0

@pashute [обсуждение AD] (https://github.com/NancyFx/Nancy/issues/742) в журнале отслеживания проблем Nancy (который ссылается на этот ответ) – Omni