2012-06-13 35 views
121

Estoy buscando autenticar a un usuario desde una aplicación cliente mientras uso el ASP.NET Web API. He visto todos los videos en el sitio y también he leído this forum post.Autenticación de la API web de ASP.NET

Al colocar el atributo [Authorize] correctamente se devuelve un estado 401 Unauthorized. Sin embargo, necesito saber cómo permitir que un usuario inicie sesión en la API.

Quiero proporcionar credenciales de usuario desde una aplicación de Android a la API, obtener el usuario conectado y, a continuación, tener todas las llamadas API posteriores pre-autenticadas.

+0

Hola Mujtaba. ¿Pudiste implementar esto? –

Respuesta

136

permitir que un usuario inicie sesión en el API

Es necesario enviar una cookie de autenticación de formularios válidos junto con la solicitud. Esta cookie generalmente la envía el servidor al autenticar (acción LogOn) llamando al método [FormsAuthentication.SetAuthCookie (consulte MSDN).

lo que el cliente necesita para realizar 2 pasos:

  1. envía una solicitud HTTP a una acción LogOn enviando el nombre de usuario y contraseña. Por turnos, esta acción llamará al método FormsAuthentication.SetAuthCookie (en caso de que las credenciales sean válidas) que a su vez establecerá la cookie de autenticación de formularios en la respuesta.
  2. Envíe una solicitud HTTP a una acción protegida [Authorize] enviándola junto con la cookie de autenticación de formularios que recuperó en la primera solicitud.

Tomemos un ejemplo. Suponga que tiene 2 controladores de API definidas en su aplicación web:

El primer responsable de gestión de la autenticación:

public class AccountController : ApiController 
{ 
    public bool Post(LogOnModel model) 
    { 
     if (model.Username == "john" && model.Password == "secret") 
     { 
      FormsAuthentication.SetAuthCookie(model.Username, false); 
      return true; 
     } 

     return false; 
    } 
} 

y el segundo contiene las acciones protegidas que sólo los usuarios autorizados pueden ver:

[Authorize] 
public class UsersController : ApiController 
{ 
    public string Get() 
    { 
     return "This is a top secret material that only authorized users can see"; 
    } 
} 

Ahora podríamos escribir una aplicación cliente consumiendo esta API. Aquí está un ejemplo trivial aplicación de consola (asegúrese de que ha instalado los Microsoft.AspNet.WebApi.Client y Microsoft.Net.Http paquetes NuGet):

using System; 
using System.Net.Http; 
using System.Threading; 

class Program 
{ 
    static void Main() 
    { 
     using (var httpClient = new HttpClient()) 
     { 
      var response = httpClient.PostAsJsonAsync(
       "http://localhost:26845/api/account", 
       new { username = "john", password = "secret" }, 
       CancellationToken.None 
      ).Result; 
      response.EnsureSuccessStatusCode(); 

      bool success = response.Content.ReadAsAsync<bool>().Result; 
      if (success) 
      { 
       var secret = httpClient.GetStringAsync("http://localhost:26845/api/users"); 
       Console.WriteLine(secret.Result); 
      } 
      else 
      { 
       Console.WriteLine("Sorry you provided wrong credentials"); 
      } 
     } 
    } 
} 

Y así es como los 2 peticiones HTTP se ven en el alambre: solicitud

Autenticación:

POST /api/account HTTP/1.1 
Content-Type: application/json; charset=utf-8 
Host: localhost:26845 
Content-Length: 39 
Connection: Keep-Alive 

{"username":"john","password":"secret"} 
respuesta

autenticación:

HTTP/1.1 200 OK 
Server: ASP.NET Development Server/10.0.0.0 
Date: Wed, 13 Jun 2012 13:24:41 GMT 
X-AspNet-Version: 4.0.30319 
Set-Cookie: .ASPXAUTH=REMOVED FOR BREVITY; path=/; HttpOnly 
Cache-Control: no-cache 
Pragma: no-cache 
Expires: -1 
Content-Type: application/json; charset=utf-8 
Content-Length: 4 
Connection: Close 

true 

Solicitud de datos protegidos:

GET /api/users HTTP/1.1 
Host: localhost:26845 
Cookie: .ASPXAUTH=REMOVED FOR BREVITY 

Respuesta de datos protegidos:

HTTP/1.1 200 OK 
Server: ASP.NET Development Server/10.0.0.0 
Date: Wed, 13 Jun 2012 13:24:41 GMT 
X-AspNet-Version: 4.0.30319 
Cache-Control: no-cache 
Pragma: no-cache 
Expires: -1 
Content-Type: application/json; charset=utf-8 
Content-Length: 66 
Connection: Close 

"This is a top secret material that only authorized users can see" 
+0

¿Va a mantener una sesión para la aplicación de Android? –

+0

Entender, pero ¿puede publicar un código de muestra para el segundo punto? Gracias por tu respuesta. –

+2

Escribir un cliente HTTP de Android es un tema para otra pregunta. No está relacionado con ASP.NET MVC y ASP.NET MVC Web API, de lo que se trataba su pregunta. Le recomendaría que comenzara un nuevo hilo etiquetando explícitamente con Java y Android en el que pregunta cómo escribir un cliente HTTP que envía solicitudes utilizando cookies. –

12

tomo androide como ejemplo.

public abstract class HttpHelper { 

private final static String TAG = "HttpHelper"; 
private final static String API_URL = "http://your.url/api/"; 

private static CookieStore sCookieStore; 

public static String invokePost(String action, List<NameValuePair> params) { 
    try { 
     String url = API_URL + action + "/"; 
     Log.d(TAG, "url is" + url); 
     HttpPost httpPost = new HttpPost(url); 
     if (params != null && params.size() > 0) { 
      HttpEntity entity = new UrlEncodedFormEntity(params, "UTF-8"); 
      httpPost.setEntity(entity); 
     } 
     return invoke(httpPost); 
    } catch (Exception e) { 
     Log.e(TAG, e.toString()); 
    } 

    return null; 
} 

public static String invokePost(String action) { 
    return invokePost(action, null); 
} 

public static String invokeGet(String action, List<NameValuePair> params) { 
    try { 
     StringBuilder sb = new StringBuilder(API_URL); 
     sb.append(action); 
     if (params != null) { 
      for (NameValuePair param : params) { 
       sb.append("?"); 
       sb.append(param.getName()); 
       sb.append("="); 
       sb.append(param.getValue()); 
      } 
     } 
     Log.d(TAG, "url is" + sb.toString()); 
     HttpGet httpGet = new HttpGet(sb.toString()); 
     return invoke(httpGet); 
    } catch (Exception e) { 
     Log.e(TAG, e.toString()); 
    } 

    return null; 
} 

public static String invokeGet(String action) { 
    return invokeGet(action, null); 
} 

private static String invoke(HttpUriRequest request) 
     throws ClientProtocolException, IOException { 
    String result = null; 
    DefaultHttpClient httpClient = new DefaultHttpClient(); 

    // restore cookie 
    if (sCookieStore != null) { 
     httpClient.setCookieStore(sCookieStore); 
    } 

    HttpResponse response = httpClient.execute(request); 

    StringBuilder builder = new StringBuilder(); 
    BufferedReader reader = new BufferedReader(new InputStreamReader(
      response.getEntity().getContent())); 
    for (String s = reader.readLine(); s != null; s = reader.readLine()) { 
     builder.append(s); 
    } 
    result = builder.toString(); 
    Log.d(TAG, "result is (" + result + ")"); 

    // store cookie 
    sCookieStore = ((AbstractHttpClient) httpClient).getCookieStore(); 
    return result; 
} 

Atención por favor: i.localhost no se pueden utilizar. El dispositivo Android mira localhost como el propio host. ii.Si implementa la API web en IIS, se debe abrir la autenticación de formulario.

0

utilizar este código y el acceso de base de datos

[HttpPost] 
[Route("login")] 
public IHttpActionResult Login(LoginRequest request) 
{ 
     CheckModelState(); 
     ApiResponse<LoginApiResponse> response = new ApiResponse<LoginApiResponse>(); 
     LoginResponse user; 
     var count = 0; 
     RoleName roleName = new RoleName(); 
     using (var authManager = InspectorBusinessFacade.GetAuthManagerInstance()) 
     { 
      user = authManager.Authenticate(request); 
     } reponse(ok) 
} 
Cuestiones relacionadas