Authentification de l'API Web ASP.NET

122

Je cherche à authentifier un utilisateur à partir d'une application client tout en utilisant le API Web ASP.NET . J'ai regardé toutes les vidéos sur le site et j'ai également lu ce message du forum .

Mettre le [Authorize] attribut correctement renvoie un 401 Unauthorizedstatut. Cependant, j'ai besoin de savoir comment autoriser un utilisateur à se connecter à l'API.

Je souhaite fournir les informations d'identification de l'utilisateur d'une application Android à l'API, que l'utilisateur soit connecté, puis que tous les appels d'API ultérieurs soient pré-authentifiés.

Mujtaba Hassan
la source
Salut Mujtaba. Avez-vous pu mettre en œuvre cela?
Vivek Chandraprakash
Commencez par utiliser CORS pour éviter les attaques indésirables provenant d'autres domaines. Envoyez ensuite un cookie d'authentification par formulaire valide avec la demande et autorisez enfin la demande par jeton. Cette combinaison rend toujours votre API Web sécurisée et optimisée.
Majedur Rahaman

Réponses:

137

autoriser un utilisateur à se connecter à l'API

Vous devez envoyer un cookie d'authentification par formulaire valide avec la demande. Ce cookie est généralement envoyé par le serveur lors de l'authentification ( LogOnaction) en appelant la [FormsAuthentication.SetAuthCookieméthode (voir MSDN ).

Le client doit donc effectuer 2 étapes:

  1. Envoyez une requête HTTP à une LogOnaction en envoyant le nom d'utilisateur et le mot de passe. À son tour, cette action appellera la FormsAuthentication.SetAuthCookieméthode (au cas où les informations d'identification sont valides) qui à son tour définira le cookie d'authentification par formulaire dans la réponse.
  2. Envoyez une requête HTTP à une [Authorize]action protégée en envoyant le cookie d'authentification par formulaire récupéré lors de la première requête.

Prenons un exemple. Supposons que vous ayez 2 contrôleurs d'API définis 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 le second contenant des actions protégées 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";
    }
}

Nous pourrions maintenant écrire une application cliente utilisant cette API. Voici un exemple d'application console trivial (assurez-vous d'avoir installé les packages Microsoft.AspNet.WebApi.Clientet 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");
            }
        }
    }
}

Et voici à quoi ressemblent les 2 requêtes HTTP 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 données protégées:

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

Réponse pour les données protégé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"
Darin Dimitrov
la source
Va-t-il maintenir une session pour l'application Android?
Mujtaba Hassan
J'ai compris, mais pouvez-vous s'il vous plaît poster un exemple de code pour le deuxième point. Merci pour votre réponse.
Mujtaba Hassan
2
L'écriture d'un client HTTP Android est un sujet pour une autre question. Il n'est pas lié à ASP.NET MVC et à l'API Web ASP.NET MVC, ce sur quoi portait votre question. Je vous recommanderais de démarrer un nouveau fil de discussion explicitement avec Java et Android dans lequel vous demandez comment écrire un client HTTP qui envoie des demandes à l'aide de cookies.
Darin Dimitrov
En fait, dans la littérature de MVC4 WebApi, ils ont écrit que WebAPI est la cible des clients tiers, en particulier des clients mobiles (et bien sûr, c'est le cas). Disons que nous avons un client d'application de bureau, pouvez-vous publier un simple extrait de code s'il vous plaît. Merci
Mujtaba Hassan
2
Voir également cette question (et réponse) sur l'utilisation de l'authentification de base HTTP: stackoverflow.com/questions/10987455/...
Jim Harte
12

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 : i.localhost ne peut pas être utilisé. L'appareil Android regarde l'hôte local comme lui-même hôte. ii.Si vous déployez l'API Web dans IIS, l'authentification par formulaire doit être ouverte.

user2293998
la source
0

Utilisez ce code et accédez à la base de données

[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) 
}
Sanila Salim
la source