122 votes

Authentification API Web ASP.NET

Je suis à la recherche d'authentifier un utilisateur à partir d'une application client tout en utilisant le ASP.NET l'API Web. J'ai regardé toutes les vidéos sur le site et aussi de lire ce post sur le forum.

Mettre la [Authorize] attribut renvoie correctement un 401 Unauthorized statut. Cependant, j'ai besoin de savoir comment permettre à un utilisateur de se connecter à l'API.

Je veux fournir à l'utilisateur des informations d'identification à partir d'une application Android à l'API, obtenir de l'utilisateur connecté, et alors tous les appels d'API pré-authentifié.

137voto

Darin Dimitrov Points 528142

permettre à un utilisateur de se connecter à l'API

Vous avez besoin d'envoyer un valide cookie d'Authentification de Formulaires avec la demande. Ce cookie est généralement envoyé par le serveur lors de l'authentification (LogOn action) par l'appel de la [FormsAuthentication.SetAuthCookie méthode (voir MSDN).

Donc, le client doit effectuer 2 étapes:

  1. Envoyer une requête HTTP à un LogOn action par l'envoi du nom d'utilisateur et mot de passe. À tour de rôle cette action fera appel à la FormsAuthentication.SetAuthCookie méthode (dans le cas où les informations sont valides) qui à son tour permettra de définir le cookie d'authentification de formulaires dans la réponse.
  2. Envoyer une requête HTTP à un [Authorize] protégé de l'action en envoyant le long du cookie d'authentification de formulaires, il est récupéré de la première demande.

Prenons un exemple. Supposons que vous disposez de 2 contrôleurs d'API définies dans votre application web:

Le premier responsable de la gestion de l'authentification:

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

et la deuxième contenant protégés actions que seuls les utilisateurs autorisés peuvent voir:

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

Maintenant, nous pourrions écrire une application cliente la consommation de cette API. Voici une simple application console exemple (assurez-vous que vous avez installé l' Microsoft.AspNet.WebApi.Client et Microsoft.Net.Http packages 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");
            }
        }
    }
}

Et voici comment les 2 requêtes HTTP regard sur le fil:

Demande d'authentification:

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

Réponse d'authentification:

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

Demande de la protection des données:

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

Réponse de la protection des données:

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"

12voto

user2293998 Points 101

Je prends Android comme exemple.

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

Attention s'il vous plaît: i.localhost ne peut pas être utilisé. L'appareil Android a l'hôte local. Si vous déployez l'API Web dans IIS, l'authentification par formulaire doit être ouverte.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X