Autenticazione API Web ASP.NET


122

Sto cercando di autenticare un utente da un'applicazione client durante l'utilizzo dell'API Web ASP.NET . Ho guardato tutti i video sul sito e ho letto anche questo post sul forum .

Mettere l' [Authorize]attributo correttamente restituisce uno 401 Unauthorizedstato. Tuttavia, ho bisogno di sapere come consentire a un utente di accedere all'API.

Desidero fornire le credenziali utente da un'applicazione Android all'API, ottenere l'accesso dell'utente e quindi la pre-autenticazione di tutte le chiamate API successive.


Ciao Mujtaba. Sei riuscito a implementarlo?
Vivek Chandraprakash

Per prima cosa usa CORS per prevenire colpi indesiderati da altri domini. Quindi invia un cookie di autenticazione moduli valido insieme alla richiesta e infine autorizza la richiesta tramite token. Questa combinazione rende sempre la tua API web sicura e ottimizzata.
Majedur Rahaman,

Risposte:


137

consentire a un utente di accedere all'API

È necessario inviare un cookie di autenticazione moduli valido insieme alla richiesta. Questo cookie viene solitamente inviato dal server durante l'autenticazione ( LogOnazione) chiamando il [FormsAuthentication.SetAuthCookiemetodo (vedere MSDN ).

Quindi il cliente deve eseguire 2 passaggi:

  1. Invia una richiesta HTTP a LogOnun'azione inviando il nome utente e la password. A sua volta, questa azione chiamerà il FormsAuthentication.SetAuthCookiemetodo (nel caso in cui le credenziali siano valide) che a sua volta imposterà il cookie di autenticazione dei moduli nella risposta.
  2. Invia una richiesta HTTP a [Authorize]un'azione protetta inviando insieme al cookie di autenticazione moduli recuperato nella prima richiesta.

Facciamo un esempio. Supponi di avere 2 controller API definiti nella tua applicazione web:

Il primo responsabile della gestione dell'autenticazione:

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;
    }
}

e il secondo contenente azioni protette che solo gli utenti autorizzati possono vedere:

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

Ora potremmo scrivere un'applicazione client che utilizza questa API. Ecco un banale esempio di applicazione console (assicurati di aver installato i pacchetti Microsoft.AspNet.WebApi.Cliente Microsoft.Net.HttpNuGet):

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");
            }
        }
    }
}

Ed ecco come appaiono le 2 richieste HTTP sul filo:

Richiesta di autenticazione:

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"}

Risposta di autenticazione:

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

Richiesta di dati protetti:

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

Risposta per dati protetti:

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"

Manterrà una sessione per l'applicazione Android?
Mujtaba Hassan

Ho capito ma puoi pubblicare un codice di esempio per il secondo punto. Grazie per la tua risposta.
Mujtaba Hassan

2
La scrittura di un client HTTP Android è un argomento per un'altra domanda. Non è correlato a ASP.NET MVC e ASP.NET MVC Web API, che è l'oggetto della tua domanda. Ti consiglio di avviare un nuovo thread taggando esplicitamente con Java e Android in cui chiedi come scrivere un client HTTP che invia richieste utilizzando i cookie.
Darin Dimitrov

In realtà nella letteratura di MVC4 WebApi hanno scritto che WebAPI è target per client di terze parti, in particolare client mobili (e naturalmente lo è). Diciamo che abbiamo un client per applicazioni desktop, puoi pubblicare un semplice snippet di codice per favore. Grazie
Mujtaba Hassan

2
Vedi anche questa domanda (e risposta) sull'utilizzo dell'autenticazione di base HTTP: stackoverflow.com/questions/10987455/…
Jim Harte

12

Prendo Android come esempio.

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;
}

Attenzione per favore : i.localhost non può essere utilizzato. Il dispositivo Android sembra host locale come esso stesso host. ii. se si distribuisce l'API Web in IIS, è necessario aprire l'autenticazione del modulo.


0

Usa questo codice e accedi al database

[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) 
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.