none
No se encuentra servicio RRS feed

  • Pregunta

  • Buenas,

    Tengo la siguiente Api Web:

    [Route("api/Account")]
    [ApiController]
    public class AccountController : ControllerBase
    {
    	private readonly IAccount account;
    
    	public AccountController(IAccount account)
    	{
    		this.account = account;
    	}
    
    	[Route("login/{usuario}/{clave}")]
    	[HttpGet]
    	public async Task<ObjectResult> Login(string usuario, string clave)
    	{
    		int code = StatusCodes.Status404NotFound;
    		string mensaje = "Correcto";
    		Capacitador entidad = null;
    
    		try
    		{
    			entidad = await account.LoginAsync(usuario, clave);
    
    			if (entidad != null)
    				code = StatusCodes.Status200OK;
    		}
    		catch (Exception ex)
    		{
    			code = StatusCodes.Status500InternalServerError;
    			mensaje = ex.Message;
    		}
    
    		return StatusCode(code, new { Mensaje = mensaje, Data = entidad });
    	}
    }

    Al invocar con la siguiente Url:

    http://localhost:38515/api/Account/login/48194752/BL6jqvQPHU/RlJjcREpRmA==

    No lo encuentra el servicio, devuelve 404.

    ¿Algo estoy haciendo mal en el ruteo?

    jueves, 1 de agosto de 2019 20:04

Respuestas

  • hola

    Recuerdo que me sucedio que a veces no resuelve la url por algun caracter, prueba de cambiar la contraseña poniendo caracteres simple

    Ademas de verdad vas a pasar la contraseña en la url ?

    mmm eso es una pesima idea, deberia ir como parte del POST, no se autentica usando GET

    tu action deberia ser

    [Route("login")]
    [HttpPost]
    public async Task<ObjectResult> Login(string usuario, string clave)
    {

    y envias el usuario y contraseña como parte de body del request

    No recmendaria por seguridad enviar la autenticacion de esa forma, por supuesto todo esto ademas en un enalce seguron con https, el canal encriptado con SSL

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    • Marcado como respuesta eduar2083 sábado, 3 de agosto de 2019 12:11
    jueves, 1 de agosto de 2019 21:29

Todas las respuestas

  • Hola, has puesto un punto de ruptura en la entrada del método de acción y has verificado que entra el flujo del programa? Porque según veo, inicializas la variable code con un 404 y si sigues la lógica si el login es igual a null entonces haces el return de ese código. Entiendo entonces que ese 404 es porque el login no es correcto 

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    jueves, 1 de agosto de 2019 20:57
    Moderador
  • hola

    Recuerdo que me sucedio que a veces no resuelve la url por algun caracter, prueba de cambiar la contraseña poniendo caracteres simple

    Ademas de verdad vas a pasar la contraseña en la url ?

    mmm eso es una pesima idea, deberia ir como parte del POST, no se autentica usando GET

    tu action deberia ser

    [Route("login")]
    [HttpPost]
    public async Task<ObjectResult> Login(string usuario, string clave)
    {

    y envias el usuario y contraseña como parte de body del request

    No recmendaria por seguridad enviar la autenticacion de esa forma, por supuesto todo esto ademas en un enalce seguron con https, el canal encriptado con SSL

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    • Marcado como respuesta eduar2083 sábado, 3 de agosto de 2019 12:11
    jueves, 1 de agosto de 2019 21:29
  • Hola.

    Primero creo que el decorador es [Route("api/[Controller]")] y no [Route("api/Account")] como lo puse.

    Al parecer la clave contenía caracteres especiales (incluyendo la barra), tuve que enviar los parámetros por QueryString:

    http://localhost:38515/api/Account/login?usuario=42481949&clave=BL6jqvQPHU/RlJjcREpRmA==

    y con eso ya llega el request al servicio y devuelve los datos. Sin embargo, tienes razón Leandro, ya cambié el verbo, quedó de la siguiente manera:

    [Route("login")]
    [HttpPost]
    public async Task<ObjectResult> Login(string usuario, string clave)
    {
    	int code = StatusCodes.Status200OK;
    	Capacitador entidad = null;
    	string mensaje = "Correcto";
    	int codigoError = 0;
    
    	try
    	{
    		entidad = await account.LoginAsync(usuario, clave);
    	}
    	catch (Exception ex)
    	{
    		code = StatusCodes.Status500InternalServerError;
    		mensaje = ex.Message;
    		codigoError = 1;
    	}
    
    	var rpta = new RptaService<Capacitador>
    	{
    		Mensaje = mensaje,
    		CodigoError = codigoError,
    		Entidad = entidad
    	};
    
    	return StatusCode(code, rpta);
    }

    Usando postman ya me devuelve los datos del usuario:

    El servicio sólo estará disponible a través de un canal seguro pero además quisiera poder agregar autenticación (NetworkCredential), ¿cómo se hace esto en el lado del servicio? Yo he enviado las crendenciales desde el cliente, por ejemplo webCliente.Credentials = new NetworkCredential(user, pass) pero desconozco cómo el se hace en el servicio para dar válidas las credenciales que recibe.



    • Editado eduar2083 jueves, 1 de agosto de 2019 22:06
    jueves, 1 de agosto de 2019 22:02
  • Hola, una vez recibidas las credenciales puedes validarlas vía Active Directory. Recuerda referenciar System.DirectoryServices.AccountManagement

    Básicamente tendrías que hacer lo siguiente que es 

    using(PrincipalContext pc = new PrincipalContext(ContextType.Domain, "YOURDOMAIN"))
    {
        // validate the credentials
        bool isValid = pc.ValidateCredentials(userName, password);
    }


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos


    jueves, 1 de agosto de 2019 22:29
    Moderador
  • hola

    >>pero además quisiera poder agregar autenticación (NetworkCredential), ¿cómo se hace esto en el lado del servicio?

    para que ? estas validando contra una entidad entiendo que es una base de datos, esa es tu implementacion

    si usas active directory vas a tener que crear los usuario en windows y mantener dos sistemas de autenticacion, eso no tiene ninguna utilidad

    se implementa uno u otro no ambos

    si vas a integrar la autenticacion contra windows eso se configura en el IIS, pero entonces no pasas ningun usuario y password al servicio

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    jueves, 1 de agosto de 2019 23:39
  • Hola,

    Creo que no me expliqué bien. Lo que necesito es darle mayor seguridad al servicio. Aparte de que se consumirá solo por el canal seguro, se le deberá enviar usuario y clave (Authorization) para ser consumido. Por ejemplo, en el postman las credenciales se envían así, utilizando Basic Auth:

    Desde una aplicación Net Core (consumidor) estoy utilizando un objeto WebClient para consumir el servicio y las credenciales se envían en su propiedad Credentials:

    webClient.Credentials = new NetworkCredential(user, pass);

    sin embargo, desconozco en qué parte en el lado del servicio se configuran estas credenciales para que el servicio las dé por válidas. Cabe señalar que ambas soluciones (cliente y servicio) son nuevas.




    • Editado eduar2083 viernes, 2 de agosto de 2019 12:55
    viernes, 2 de agosto de 2019 12:48
  • hola

    >>desconozco en qué parte en el lado del servicio se configuran estas credenciales

    se configuran en el IIS, cuando integras el sitio al dominio de windows

    Windows Authentication <windowsAuthentication>

    tienes que habilitar la feature en el iis para poder seleccionarla

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    viernes, 2 de agosto de 2019 18:05