Autenticación de la API web de ASP.NET

Estoy buscando autenticar a un usuario desde una aplicación cliente mientras uso ASP.NET Web API . He visto todos los videos en el sitio y también he leído esta publicación en el foro .

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.

Deseo proporcionar credenciales de usuario desde una aplicación de Android a la API, obtener el inicio de sesión del usuario y, luego, autenticar previamente todas las llamadas subsiguientes a la API.

permitir que un usuario inicie sesión en la API

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

Entonces el cliente necesita realizar 2 pasos:

  1. Envíe una solicitud HTTP a una acción LogOn enviando el nombre de usuario y la 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, configurará la cookie de autenticación de formularios en la respuesta.
  2. Envíe una solicitud HTTP a una acción protegida [Authorize] enviando a lo largo de la cookie de autenticación de formularios que recuperó en la primera solicitud.

Tomemos un ejemplo. Supongamos que tiene 2 controladores API definidos en su aplicación web:

El primero responsable de manejar 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 que contiene acciones protegidas que solo 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í hay un ejemplo de aplicación de consola trivial (asegúrese de haber instalado los paquetes Microsoft.AspNet.WebApi.Client y Microsoft.Net.Http 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().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 se ven las 2 solicitudes HTTP en el cable:

Solicitud de 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 de 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 para 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" 

Tomo Android 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 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 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(); // restre 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 puede ser utilizado. 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.

Use este código y acceda a la base de datos

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