with tutorial tables net mvc español customizing custom asp authentication asp.net-identity claims-based-identity asp.net-core visual-studio-2015

tutorial - customizing asp net authentication with identity



¿Cómo utilizar la autenticación de Active Directory de Windows y las declaraciones basadas en la identidad? (5)

Problema

Queremos usar Windows Active Directory para autenticar a un usuario en la aplicación. Sin embargo, no queremos utilizar grupos de Active Directory para gestionar la autorización de controladores / vistas.

Hasta donde yo sé, no hay una manera fácil de casar AD y reclamos basados ​​en identidad.

Metas

  • Autentica usuarios con Active Directory local
  • Usar el marco de identidad para administrar reclamos

Intentos (falla)

  • Windows.Owin.Security.ActiveDirectory - Doh. Esto es para Azure AD. Sin soporte LDAP. ¿Podrían haberlo llamado AzureActiveDirectory en su lugar?
  • Autenticación de Windows: esto está bien con la autenticación NTLM o Keberos. Los problemas comienzan con: i) tokens y reclamos son administrados por AD y no puedo entender cómo usar los reclamos de identidad con él.
  • LDAP: ¿Pero esto parece estar forzándome a realizar manualmente la autenticación de formularios para usar los reclamos de identidad? Seguramente debe haber una manera más fácil?

Cualquier ayuda sería más que apreciada. Me he quedado atrapado en este problema durante bastante tiempo y agradecería la opinión externa sobre el tema.


¿Sabe cómo implementar System.Web.Security.MembershipProvider personalizado? Debería poder usar esto (anular ValidateUser ) junto con System.DirectoryServices.AccountManagement.PrincipalContext.ValidateCredentials() para autenticarse contra el directorio activo.

try: var pc = new PrincipalContext(ContextType.Domain, "example.com", "DC=example,DC=com"); pc.ValidateCredentials(username, password); var pc = new PrincipalContext(ContextType.Domain, "example.com", "DC=example,DC=com"); pc.ValidateCredentials(username, password);


Calzar su solución anterior me empujó hacia una dirección que funcionó para mí en MVC6-Beta3 Identityframework7-Beta3 EntityFramework7-Beta3:

// POST: /Account/Login [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null) { if (!ModelState.IsValid) { return View(model); } // // Check for user existance in Identity Framework // ApplicationUser applicationUser = await _userManager.FindByNameAsync(model.eID); if (applicationUser == null) { ModelState.AddModelError("", "Invalid username"); return View(model); } // // Authenticate user credentials against Active Directory // bool isAuthenticated = await Authentication.ValidateCredentialsAsync( _applicationSettings.Options.DomainController, _applicationSettings.Options.DomainControllerSslPort, model.eID, model.Password); if (isAuthenticated == false) { ModelState.AddModelError("", "Invalid username or password."); return View(model); } // // Signing the user step 1. // IdentityResult identityResult = await _userManager.CreateAsync( applicationUser, cancellationToken: Context.RequestAborted); if(identityResult != IdentityResult.Success) { foreach (IdentityError error in identityResult.Errors) { ModelState.AddModelError("", error.Description); } return View(model); } // // Signing the user step 2. // await _signInManager.SignInAsync(applicationUser, isPersistent: false, authenticationMethod:null, cancellationToken: Context.RequestAborted); return RedirectToLocal(returnUrl); }


En ASPNET5 (beta6), la idea es usar CookieAuthentication e Identity: deberá agregar su clase de inicio:

public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddAuthorization(); services.AddIdentity<MyUser, MyRole>() .AddUserStore<MyUserStore<MyUser>>() .AddRoleStore<MyRoleStore<MyRole>>() .AddUserManager<MyUserManager>() .AddDefaultTokenProviders(); }

En la sección de configuración, agregue:

private void ConfigureAuth(IApplicationBuilder app) { // Use Microsoft.AspNet.Identity & Cookie authentication app.UseIdentity(); app.UseCookieAuthentication(options => { options.AutomaticAuthentication = true; options.LoginPath = new PathString("/App/Login"); }); }

Entonces, necesitarás implementar:

Microsoft.AspNet.Identity.IUserStore Microsoft.AspNet.Identity.IRoleStore Microsoft.AspNet.Identity.IUserClaimsPrincipalFactory

y extender / anular:

Microsoft.AspNet.Identity.UserManager Microsoft.AspNet.Identity.SignInManager

De hecho, he configurado un proyecto de muestra para mostrar cómo se puede hacer esto. GitHub Link .

Probé en la beta8 y con algunas adaptaciones pequeñas (como Context => HttpContext) funcionó también.


Podrías usar ClaimTransformation, esta tarde lo hice funcionar usando el artículo y el código a continuación. Estoy accediendo a una aplicación con Autenticación de Ventana y luego agregando reclamos basados ​​en permisos almacenados en una Base de Datos SQL. Este es un buen artículo que debería ayudarte.

https://github.com/aspnet/Security/issues/863

En resumen ...

services.AddScoped<IClaimsTransformer, ClaimsTransformer>(); app.UseClaimsTransformation(async (context) => { IClaimsTransformer transformer = context.Context.RequestServices.GetRequiredService<IClaimsTransformer>(); return await transformer.TransformAsync(context); }); public class ClaimsTransformer : IClaimsTransformer { private readonly DbContext _context; public ClaimsTransformer(DbContext dbContext) { _context = dbContext; } public async Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context) { System.Security.Principal.WindowsIdentity windowsIdentity = null; foreach (var i in context.Principal.Identities) { //windows token if (i.GetType() == typeof(System.Security.Principal.WindowsIdentity)) { windowsIdentity = (System.Security.Principal.WindowsIdentity)i; } } if (windowsIdentity != null) { //find user in database by username var username = windowsIdentity.Name.Remove(0, 6); var appUser = _context.User.FirstOrDefault(m => m.Username == username); if (appUser != null) { ((ClaimsIdentity)context.Principal.Identity).AddClaim(new Claim("Id", Convert.ToString(appUser.Id))); /*//add all claims from security profile foreach (var p in appUser.Id) { ((ClaimsIdentity)context.Principal.Identity).AddClaim(new Claim(p.Permission, "true")); }*/ } } return await System.Threading.Tasks.Task.FromResult(context.Principal); } }


Simplemente presione AD con el nombre de usuario y la contraseña en lugar de autenticar contra su base de datos

// POST: /Account/Login [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { if (ModelState.IsValid) { var user = await UserManager.FindByNameAsync(model.UserName); if (user != null && AuthenticateAD(model.UserName, model.Password)) { await SignInAsync(user, model.RememberMe); return RedirectToLocal(returnUrl); } else { ModelState.AddModelError("", "Invalid username or password."); } } return View(model); } public bool AuthenticateAD(string username, string password) { using(var context = new PrincipalContext(ContextType.Domain, "MYDOMAIN")) { return context.ValidateCredentials(username, password); } }