Saltar al contenido

Confusión de autenticación DB-First con ASP.NET Web API 2 + EF6

Recuerda que en la informática cualquier problema casi siempere suele tener más de una resoluciones, por lo tanto te mostramos lo más óptimo y eficiente.

Solución:

Tu dices:

Quiero implementar un sistema de inicio de sesión / registro (para poder implementar roles y permisos en el futuro y restringir ciertas solicitudes de API).

¿Cómo configuro la autenticación en una aplicación Web API 2, que tiene una entidad de usuario existente?

Definitivamente significa que tu NO necesita identidad ASP.NET. ASP.NET Identity es una tecnología para manejar todas las cosas de los usuarios. En realidad, no “crea” el mecanismo de autenticación. ASP.NET Identity utiliza el mecanismo de autenticación OWIN, que es otra cosa.

Lo que buscas no es “cómo usar la identidad ASP.NET con mi tabla de usuarios existente”, pero “Cómo configurar la autenticación OWIN usando mi tabla de usuarios existente”

Para utilizar la autenticación OWIN, siga estos pasos:

Instale los paquetes:

Owin
Microsoft.AspNet.Cors
Microsoft.AspNet.WebApi.Client
Microsoft.AspNet.WebApi.Core
Microsoft.AspNet.WebApi.Owin
Microsoft.AspNet.WebApi.WebHost
Microsoft.Owin
Microsoft.Owin.Cors
Microsoft.Owin.Host.SystemWeb
Microsoft.Owin.Security
Microsoft.Owin.Security.OAuth

Crear Startup.cs archivo dentro de la carpeta raíz (ejemplo):

Asegúrate de eso [assembly: OwinStartup] está configurado correctamente

[assembly: OwinStartup(typeof(YourProject.Startup))]
namespace YourProject

    public class Startup
    
        public void Configuration(IAppBuilder app)
        
            var config = new HttpConfiguration();
            //other configurations

            ConfigureOAuth(app);
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            app.UseWebApi(config);
        

        public void ConfigureOAuth(IAppBuilder app)
        
            var oAuthServerOptions = new OAuthAuthorizationServerOptions()
            
                AllowInsecureHttp = true,
                TokenEndpointPath = new PathString("/api/security/token"),
                AccessTokenExpireTimeSpan = TimeSpan.FromHours(2),
                Provider = new AuthorizationServerProvider()
            ;

            app.UseOAuthAuthorizationServer(oAuthServerOptions);
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
        
    

    public class AuthorizationServerProvider : OAuthAuthorizationServerProvider
    
        public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        
            context.Validated();
        

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        
            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[]  "*" );

            try
            
                //retrieve your user from database. ex:
                var user = await userService.Authenticate(context.UserName, context.Password);

                var identity = new ClaimsIdentity(context.Options.AuthenticationType);

                identity.AddClaim(new Claim(ClaimTypes.Name, user.Name));
                identity.AddClaim(new Claim(ClaimTypes.Email, user.Email));

                //roles example
                var rolesTechnicalNamesUser = new List();

                if (user.Roles != null)
                
                    rolesTechnicalNamesUser = user.Roles.Select(x => x.TechnicalName).ToList();

                    foreach (var role in user.Roles)
                        identity.AddClaim(new Claim(ClaimTypes.Role, role.TechnicalName));
                

                var principal = new GenericPrincipal(identity, rolesTechnicalNamesUser.ToArray());

                Thread.CurrentPrincipal = principal;

                context.Validated(identity);
            
            catch (Exception ex)
            
                context.SetError("invalid_grant", "message");
            
        
    

Utilizar el [Authorize] attribute para autorizar las acciones.

Llama api/security/token con GrantType, UserName, y Password para obtener la ficha de portador. Como esto:

"grant_type=password&username=" + username + "&password=" password;

Envíe el token dentro del HttpHeader Authorization como Bearer "YOURTOKENHERE". Como esto:

headers:  'Authorization': 'Bearer ' + token 

¡Espero eso ayude!

Dado que su esquema de base de datos no es compatible con el UserStore Debes implementar tu propio UserStore y UserPasswordStore las clases luego las inyectan a UserManager. Considere este simple ejemplo:

Primero escriba su clase de usuario personalizada e impleméntela IUser interfaz:

class User:IUser

    public int ID get;set;
    public string Usernameget;set;
    public string Password_hash get;set;
    // some other properties 

Ahora crea tu personalizado UserStore y IUserPasswordStore clase como esta:

public class MyUserStore : IUserStore, IUserPasswordStore

    private readonly MyDbContext _context;

    public MyUserStore(MyDbContext context)
    
        _context=context;
    

    public Task CreateAsync(AppUser user)
    
        // implement your desired logic such as
        // _context.Users.Add(user);
    

    public Task DeleteAsync(AppUser user)
    
        // implement your desired logic
    

    public Task FindByIdAsync(string userId)
    
        // implement your desired logic
    

    public Task FindByNameAsync(string userName)
    
        // implement your desired logic
    

    public Task UpdateAsync(AppUser user)
    
        // implement your desired logic
    

    public void Dispose()
    
        // implement your desired logic
    

    // Following 3 methods are needed for IUserPasswordStore
    public Task GetPasswordHashAsync(AppUser user)
    
        // something like this:
        return Task.FromResult(user.Password_hash);
    

    public Task HasPasswordAsync(AppUser user)
    
        return Task.FromResult(user.Password_hash != null);
    

    public Task SetPasswordHashAsync(AppUser user, string passwordHash)
    
        user.Password_hash = passwordHash;
        return Task.FromResult(0);
    

Ahora tiene su propia tienda de usuarios, simplemente inyéctela al administrador de usuarios:

public class ApplicationUserManager: UserManager

    public static ApplicationUserManager Create(IdentityFactoryOptions options, IOwinContext context)
    
         var manager = new ApplicationUserManager(new MyUserStore(context.Get()));
         // rest of code
    

También tenga en cuenta que debe heredar directamente su clase de contexto de base de datos de DbContext no IdentityDbContext ya que ha implementado su propia tienda de usuario.

Aquí tienes las comentarios y valoraciones

Si te animas, eres capaz de dejar un tutorial acerca de qué le añadirías a este post.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *