Autenticación de usuario en ASP.NET API WEB


Este tema ha sido increíblemente confuso para mí. Soy un novato en aplicaciones HTTP, pero necesito desarrollar un cliente de iPhone que consuma datos JSON desde algún lugar. Elegí Web API de MS porque parecía bastante fácil, pero cuando se trata de autenticar usuarios, las cosas se vuelven bastante frustrantes.

Me sorprende cómo no he sido capaz de encontrar un ejemplo claro de cómo autenticar a un usuario desde la pantalla de inicio de sesión hasta el uso del atributo Authorize sobre mis métodos ApiController después de varias horas de Googleando.

Esto no es una pregunta, sino una solicitud de un ejemplo de cómo hacer esto exactamente. He mirado las siguientes páginas:

Aunque estos explican cómo manejar solicitudes no autorizadas, no demuestran claramente algo como un LoginController o algo así para pedir credenciales de usuario y validarlas.

Cualquiera dispuesto a escribir un buen ejemplo simple o señalarme en la dirección correcta, por favor?

Gracias.

Author: chridam, 2012-07-31

3 answers

Me sorprende cómo no he sido capaz de encontrar un ejemplo claro de cómo autenticar a un usuario desde la pantalla de inicio de sesión hasta el uso del atributo Authorize sobre mis métodos ApiController después de varias horas de Googlear.

Eso es porque te estás confundiendo acerca de estos dos conceptos:

  • La autenticación es el mecanismo mediante el cual los sistemas pueden identificar de forma segura a sus usuarios. Los sistemas de autenticación proporcionan una respuesta a la preguntas:

    • ¿Quién es el usuario?
    • ¿Es el usuario realmente quien él / ella se representa a sí mismo?
  • La autorización es el mecanismo por el cual un sistema determina qué nivel de acceso debe tener un usuario autenticado particular a los recursos asegurados controlados por el sistema. Por ejemplo, un sistema de gestión de bases de datos podría diseñarse para proporcionar a ciertas personas especificadas la capacidad de recuperar información de una base de datos, pero no capacidad de cambiar los datos almacenados en la base de datos, mientras que da a otras personas la capacidad de cambiar los datos. Los sistemas de autorización proporcionan respuestas a las preguntas:

    • ¿Está autorizado el usuario X para acceder al recurso R?
    • ¿Está autorizado el usuario X para realizar la operación P?
    • ¿Está autorizado el usuario X para realizar la operación P en el recurso R?

El atributo Authorize en MVC se usa para aplicar reglas de acceso, por ejemplo:

 [System.Web.Http.Authorize(Roles = "Admin, Super User")]
 public ActionResult AdministratorsOnly()
 {
     return View();
 }

La regla anterior permitirá solo usuarios en los roles Admin y Superusuario para acceder al método

Estas reglas también se pueden establecer en la web.archivo de configuración, usando el elemento location. Ejemplo:

  <location path="Home/AdministratorsOnly">
    <system.web>
      <authorization>
        <allow roles="Administrators"/>
        <deny users="*"/>
      </authorization>
    </system.web>
  </location>

Sin embargo, antes de que se ejecuten esas reglas de autorización, debe estar autenticado en el sitio web actual.

A pesar de que estos explican cómo manejar solicitudes no autorizadas, estos no demuestran claramente algo como un LoginController o algo así para pedir credenciales de usuario y validarlas.

Desde aquí, podríamos dividir el problema en dos:

  • Autenticar usuarios al consumir los servicios Web API dentro de la misma aplicación Web

    Este sería el enfoque más simple, ya que dependería de la autenticación en ASP.Net

    Este es un ejemplo simple:

    Web.config

    <authentication mode="Forms">
      <forms
        protection="All"
        slidingExpiration="true"
        loginUrl="account/login"
        cookieless="UseCookies"
        enableCrossAppRedirects="false"
        name="cookieName"
      />
    </authentication>
    

    Los usuarios serán redirigidos a la cuenta /inicio de sesión route, allí renderizaría controles personalizados para solicitar credenciales de usuario y luego establecería la cookie de autenticación usando:

        if (ModelState.IsValid)
        {
            if (Membership.ValidateUser(model.UserName, model.Password))
            {
                FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                return RedirectToAction("Index", "Home");
            }
            else
            {
                ModelState.AddModelError("", "The user name or password provided is incorrect.");
            }
        }
    
        // If we got this far, something failed, redisplay form
        return View(model);
    
  • Autenticación multiplataforma

    Este caso sería cuando está solo exponiendo servicios Web API dentro de la aplicación Web por lo tanto, tendría otro cliente consumiendo los servicios, el cliente podría ser otra aplicación Web o cualquier aplicación. Net (Win Forms, WPF, console, Windows service, etc)

    Por ejemplo, supongamos que va a consumir el servicio Web API desde otra aplicación web en el mismo dominio de red (dentro de una intranet), en este caso podría confiar en la autenticación de Windows proporcionada por ASP.Net.

    <authentication mode="Windows" />
    

    Si sus servicios están expuestos en Internet, entonces tendría que pasar los tokens autenticados a cada servicio Web API.

    Para obtener más información, lleve un botín a lo siguiente artículos:

 175
Author: Jupaol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-01 14:11:21

Si desea autenticarse con un nombre de usuario y contraseña y sin una cookie de autorización, el atributo MVC4 Authorize no funcionará fuera de la caja. Sin embargo, puede agregar el siguiente método auxiliar a su controlador para aceptar encabezados de autenticación básicos. Llámelo desde el principio de los métodos de su controlador.

void EnsureAuthenticated(string role)
{
    string[] parts = UTF8Encoding.UTF8.GetString(Convert.FromBase64String(Request.Headers.Authorization.Parameter)).Split(':');
    if (parts.Length != 2 || !Membership.ValidateUser(parts[0], parts[1]))
        throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "No account with that username and password"));
    if (role != null && !Roles.IsUserInRole(parts[0], role))
        throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "An administrator account is required"));
}

Desde el lado del cliente, este ayudante crea un HttpClient con el encabezado de autenticación en su lugar:

static HttpClient CreateBasicAuthenticationHttpClient(string userName, string password)
{
    var client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(UTF8Encoding.UTF8.GetBytes(userName + ':' + password)));
    return client;
}
 14
Author: Edward Brey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-13 02:45:37

Estoy trabajando en un proyecto MVC5/Web API y necesitaba poder obtener autorización para los métodos Web Api. Cuando mi vista de índice se carga por primera vez, hago una llamada al método Web API 'token' que creo que se crea automáticamente.

El código del lado del cliente (CoffeeScript) para obtener el token es:

getAuthenticationToken = (username, password) ->
    dataToSend = "username=" + username + "&password=" + password
    dataToSend += "&grant_type=password"
    $.post("/token", dataToSend).success saveAccessToken

Si tiene éxito, se llama a lo siguiente, lo que guarda el token de autenticación localmente:

saveAccessToken = (response) ->
    window.authenticationToken = response.access_token

Entonces si necesito hacer una llamada Ajax a un método Web API que tiene el [Authorize] tag Simplemente añado el siguiente encabezado a mi llamada Ajax:

{ "Authorization": "Bearer " + window.authenticationToken }
 9
Author: ProfNimrod,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-16 16:36:10