Идея состоит в том, чтобы добавить аутентификацию в методе ConfigureServices в файле Startup.cs:

ел реализовать аутентификацию форм с членством в моем приложении asp.net MVC Core. В предыдущем приложении мы установили аутентификацию на основе форм, как показано ниже, и хотели использовать ее в ядре .net.

  [HttpPost]
public ActionResult Login(LoginModel model, string returnUrl)
{
  if (!this.ModelState.IsValid)
  {
      return this.View(model);
   }

   //Authenticate
   if (!Membership.ValidateUser(model.UserName, model.Password))
   {
       this.ModelState.AddModelError(string.Empty, "The user name or 
   password provided is incorrect.");
   return this.View(model);
   }
   else
   {
       FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
        return this.RedirectToAction("Index", "Home");
   }
 return this.View(model);
   }

В моем конфиге:

  <membership defaultProvider="ADMembership">
       <providers>
         <add name="ADMembership" 
           type="System.Web.Security.ActiveDirectoryMembershipProvider" 
           connectionStringName="ADConnectionString" 
           attributeMapUsername="sAMAccountName" />
       </providers>
   </membership>

Таким образом, мы используем активный каталог здесь в членстве.

Это все еще применимо в ядре .net.

Если нет, то что еще доступно в ядре .net для аутентификации форм и AD.

Был бы признателен за вклад.

Ответы на вопрос(3)

Откройте решение. Щелкните правой кнопкой мыши на Project и выберите Properties. Перейдите на вкладку «Отладка». Установите флажок Включить проверку подлинности Windows. Убедитесь, что анонимная аутентификация отключена.

Вот документ Microsoft,https://docs.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth

Ура!

 aman20 окт. 2017 г., 20:09
Я не ищу аутентификацию Windows, но формирует аутентификацию, где я бы проходил аутентификацию через AD
Решение Вопроса

вы можете сделать это в приложении Core MVC. Вы включаете аутентификацию формы и используетеLDAP как пользовательский магазин на заднем плане.

Вот как я настраиваю вещи, чтобы вы начали:

Startup.cs
public class Startup
{
    ...
    public void ConfigureServices(IServiceCollection services)
    {
        ...
        // Read LDAP settings from appsettings
        services.Configure<LdapConfig>(this.Configuration.GetSection("ldap"));

        // Define an interface for authentication service,
        // We used Novell.Directory.Ldap as implementation.
        services.AddScoped<IAuthenticationService, LdapAuthenticationService>();

        // Global filter is enabled to protect the whole site
        services.AddMvc(config =>
        {
            var policy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();
            config.Filters.Add(new AuthorizeFilter(policy));
            ...
        });

        // Form authentication and cookies settings
        var cookiesConfig = this.Configuration.GetSection("cookies").Get<CookiesConfig>();
        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options =>
        {
            options.Cookie.Name = cookiesConfig.CookieName;
            options.LoginPath = cookiesConfig.LoginPath;
            options.LogoutPath = cookiesConfig.LogoutPath;
            options.AccessDeniedPath = cookiesConfig.AccessDeniedPath;
            options.ReturnUrlParameter = cookiesConfig.ReturnUrlParameter;
        });
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        // Redirects all HTTP requests to HTTPS
        if (env.IsProduction())
        {
            app.UseRewriter(new RewriteOptions()
                .AddRedirectToHttpsPermanent());
        }

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/error");
        }

        app.UseStaticFiles();

        app.UseStatusCodePagesWithReExecute("/error", "?code={0}");

        app.UseAuthentication();

        app.UseMvc(routes =>
        {
            ...
        });
    }
}
appsettings.json
{
  "connectionStrings": {
    "appDbConnection": xxx
  },
  "ldap": {
    "url": "xxx.loc",
    "bindDn": "CN=Users,DC=xxx,DC=loc",
    "username": "xxx",
    "password": "xxx",
    "searchBase": "DC=xxx,DC=loc",
    "searchFilter": "(&(objectClass=user)(objectClass=person)(sAMAccountName={0}))"
  },
  "cookies": {
    "cookieName": "xxx",
    "loginPath": "/account/login",
    "logoutPath": "/account/logout",
    "accessDeniedPath": "/account/accessDenied",
    "returnUrlParameter": "returnUrl"
  }
}
IAuthenticationService.cs
namespace DL.SO.Services.Core
{
    public interface IAuthenticationService
    {
        IAppUser Login(string username, string password);
    }
}
LdapAuthenticationService.cs

Ldap реализация службы аутентификации, используяNovell.Directory.Ldap библиотека для общения с активным каталогом. Вы можете Nuget эту библиотеку.

using Microsoft.Extensions.Options;
using Novell.Directory.Ldap;
...
using DL.SO.Services.Core;

namespace DL.SO.Services.Security.Ldap
{
    public class LdapAuthenticationService : IAuthenticationService
    {
        private const string MemberOfAttribute = "memberOf";
        private const string DisplayNameAttribute = "displayName";
        private const string SAMAccountNameAttribute = "sAMAccountName";
        private const string MailAttribute = "mail";

        private readonly LdapConfig _config;
        private readonly LdapConnection _connection;

        public LdapAuthenticationService(IOptions<LdapConfig> configAccessor)
        {
            // Config from appsettings, injected through the pipeline
            _config = configAccessor.Value;
            _connection = new LdapConnection();
        }

        public IAppUser Login(string username, string password)
        {
            _connection.Connect(_config.Url, LdapConnection.DEFAULT_PORT);
            _connection.Bind(_config.Username, _config.Password);

            var searchFilter = String.Format(_config.SearchFilter, username);
            var result = _connection.Search(_config.SearchBase, LdapConnection.SCOPE_SUB, searchFilter,
            new[] { MemberOfAttribute, DisplayNameAttribute, SAMAccountNameAttribute, MailAttribute }, false);

            try
            {
                var user = result.next();
                if (user != null)
                {
                    _connection.Bind(user.DN, password);
                    if (_connection.Bound)
                    {
                        var accountNameAttr = user.getAttribute(SAMAccountNameAttribute);
                        if (accountNameAttr == null)
                        {
                            throw new Exception("Your account is missing the account name.");
                        }

                        var displayNameAttr = user.getAttribute(DisplayNameAttribute);
                        if (displayNameAttr == null)
                        {
                            throw new Exception("Your account is missing the display name.");
                        }

                        var emailAttr = user.getAttribute(MailAttribute);
                        if (emailAttr == null)
                        {
                            throw new Exception("Your account is missing an email.");
                        }

                        var memberAttr = user.getAttribute(MemberOfAttribute);
                        if (memberAttr == null)
                        {
                            throw new Exception("Your account is missing roles.");
                        }

                        return new AppUser
                        {
                            DisplayName = displayNameAttr.StringValue,
                            Username = accountNameAttr.StringValue,
                            Email = emailAttr.StringValue,
                            Roles = memberAttr.StringValueArray
                                .Select(x => GetGroup(x))
                                .Where(x => x != null)
                                .Distinct()
                                .ToArray()
                        };
                    }
                }
            }
            finally
            {
                _connection.Disconnect();
            }

            return null;
        }
    }
}
AccountController.cs

Затем, наконец, после того, как пользователь проверен, вам нужно построить принципал из заявок пользователя на вход в систему, который будет генерировать cookie за сценой.

public class AccountController : Controller
{
    private readonly IAuthenticationService _authService;

    public AccountController(IAuthenticationService authService)
    {
        _authService = authService;
    }

    ...
    [HttpPost]
    [AllowAnonymous]
    public async Task<IActionResult> Login(LoginViewModel model)
    {
        if (ModelState.Valid)
        {
            try
            {
                var user = _authService.Login(model.Username, model.Password);
                if (user != null)
                {
                    var claims = new List<Claim>
                    {
                        new Claim(ClaimTypes.Name, user.Username),
                        new Claim(CustomClaimTypes.DisplayName, user.DisplayName),
                        new Claim(ClaimTypes.Email, user.Email)
                    }

                    // Roles
                    foreach (var role in user.Roles)
                    {
                        claims.Add(new Claim(ClaimTypes.Role, role));
                    }

                    // Construct Principal
                    var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, _authService.GetType().Name));

                    await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, 
                        principal,
                        new AuthenticationProperties
                        {
                            IsPersistent = model.RememberMe
                        }
                    );

                    return Redirect(Url.IsLocalUrl(model.ReturnUrl)
                        ? model.ReturnUrl
                        : "/");              
                }

                ModelState.AddModelError("", @"Your username or password is incorrect.");
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("", ex.Message);
            }
        }
        return View(model);
    }
}
 aman24 окт. 2017 г., 20:45
ХОРОШО. Еще один вопрос. Хотя я могу использовать эту функцию conn.Bind (ldapVersion, "domainname \\" + username, password); это кажется довольно медленным. Требуется около 10 -12 секунд для подключения. Это ожидаемое поведение
 aman24 окт. 2017 г., 18:50
Я начал использовать ваш код выше и получил роман от Nuget. При попытке создать соединение ldap, как показано ниже: я получаю сообщение об ошибке conn.Bind (имя пользователя, пароль); Ошибка: 80090308: LdapErr: DSID-0C09042F, комментарий: ошибка AcceptSecurityContext, данные 52e, v2580 У меня есть хост как: xx.com:389 и чтобы он работал, мне нужно передать имя домена как: conn.Bind (ldapVersion, "имя домена \\" + имя пользователя, пароль); Почему я должен жестко закодировать доменное имя
 aman20 окт. 2017 г., 20:09
Спасибо Дэвид. Я бы попытался интегрировать Novel AD и реализовать это решение. Даст вам знать, как это происходит.
 David Liang24 окт. 2017 г., 19:17
Интересно. Это я не знаю. Мне не нужно было передавать доменное имя с именем пользователя. Пожалуйста, обратитесь к их документации [github.com/dsbenghe/Novell.Directory.Ldap.NETStandard] для большего количества конфигураций. И чтобы проверить настройки AD, я также скачал Active Directory Explorer [docs.microsoft.com/en-us/sysinternals/downloads/adexplorer] так что вы можете проверить свои имя пользователя и пароль.
 David Liang24 окт. 2017 г., 21:30
Нет, это странно. Мой бежит быстро. Теперь я помню, что мы сталкивались с подобной проблемой раньше со старым проектом ASP.NET MVC. Мы создалиActiveDirectoryRoleProvider который наследует отRoleProvider и AD был в Server 2003. Этот метод занял 7 секунд, чтобы закончить. Мы не могли понять причину. Позже мы переместили AD на Server 2008 и использовали новый метод для общения с AD. С тех пор это займет всего пару мс. Это может иметь отношение к вашему серверу AD или даже к машине, на которой вы запускаете свой код. Может быть, если ваша машина уже подключена к домену, код будет работать быстрее? Я не знаю.

MVC Core Как заставить / установить глобальную авторизацию для всех действий?

Идея состоит в том, чтобы добавить аутентификацию в методе ConfigureServices в файле Startup.cs:

services.AddMvc(config =>
{
    var policy = new AuthorizationPolicyBuilder()
                     .RequireAuthenticatedUser()
                     .RequireRole([Your AD security group name in here without domain name]) // This line adds authorization to users in the AD group only
                     .Build();
    config.Filters.Add(new AuthorizeFilter(policy));
});

Ваш ответ на вопрос