Otentikasi API Web ASP.NET

122

Saya mencari untuk mengotentikasi pengguna dari aplikasi klien saat menggunakan API Web ASP.NET . Saya telah menonton semua video di situs dan juga membaca posting forum ini .

Menempatkan [Authorize]atribut dengan benar mengembalikan 401 Unauthorizedstatus. Namun, saya perlu tahu cara mengizinkan pengguna untuk masuk ke API.

Saya ingin memberikan kredensial pengguna dari aplikasi Android ke API, meminta pengguna masuk, dan kemudian meminta semua panggilan API berikutnya diautentikasi sebelumnya.

Mujtaba Hassan
sumber
Hai Mujtaba. Apakah Anda dapat menerapkan ini?
Vivek Chandraprakash
Pertama gunakan CORS untuk mencegah klik yang tidak diinginkan dari domain lain. Kemudian kirim cookie Autentikasi Formulir yang valid bersama dengan permintaan dan terakhir otorisasi permintaan dengan token. Kombinasi ini selalu membuat api web Anda aman dan dioptimalkan.
Majedur Rahaman

Jawaban:

137

memungkinkan pengguna untuk masuk ke API

Anda perlu mengirim cookie Otentikasi Formulir yang valid bersama dengan permintaan. Cookie ini biasanya dikirim oleh server saat mengautentikasi ( LogOntindakan) dengan memanggil [FormsAuthentication.SetAuthCookiemetode (lihat MSDN ).

Jadi klien perlu melakukan 2 langkah:

  1. Kirim permintaan HTTP ke suatu LogOntindakan dengan mengirimkan nama pengguna dan kata sandi. Secara bergiliran tindakan ini akan memanggil FormsAuthentication.SetAuthCookiemetode (jika kredensial valid) yang pada gilirannya akan mengatur cookie otentikasi formulir dalam respons.
  2. Mengirim permintaan HTTP ke [Authorize]tindakan yang dilindungi dengan mengirimkan cookie otentikasi bentuk yang diambilnya dalam permintaan pertama.

Mari kita ambil contoh. Misalkan Anda memiliki 2 pengontrol API yang ditentukan dalam aplikasi web Anda:

Yang pertama bertanggung jawab untuk menangani otentikasi:

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

dan yang kedua berisi tindakan dilindungi yang hanya dapat dilihat oleh pengguna yang berwenang:

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

Sekarang kita bisa menulis aplikasi klien yang menggunakan API ini. Berikut contoh aplikasi konsol trivial (pastikan Anda telah menginstal Microsoft.AspNet.WebApi.Clientdan Microsoft.Net.Httppaket 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");
            }
        }
    }
}

Dan inilah tampilan 2 permintaan HTTP di kabel:

Permintaan otentikasi:

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

Respon otentikasi:

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

Permintaan untuk data yang dilindungi:

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

Tanggapan untuk data yang dilindungi:

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
sumber
Apakah akan mempertahankan sesi untuk aplikasi Android?
Mujtaba Hassan
Paham tapi bisakah Anda memposting kode contoh untuk poin kedua. Terima kasih atas jawaban anda.
Mujtaba Hassan
2
Menulis klien HTTP Android adalah subjek untuk pertanyaan lain. Ini tidak terkait dengan ASP.NET MVC dan ASP.NET MVC Web API yang merupakan pertanyaan Anda. Saya akan merekomendasikan Anda memulai utas baru yang secara eksplisit memberi tag dengan Java dan Android di mana Anda bertanya tentang cara menulis klien HTTP yang mengirimkan permintaan menggunakan cookie.
Darin Dimitrov
Sebenarnya dalam literatur MVC4 WebApi mereka telah menulis bahwa WebAPI adalah target klien pihak ketiga khususnya klien mobile (dan tentu saja). Katakanlah kami memiliki klien aplikasi desktop, dapatkah Anda mengeposkan cuplikan kode sederhana. Terima kasih
Mujtaba Hassan
2
Juga lihat pertanyaan ini (dan jawaban) tentang menggunakan otentikasi dasar HTTP: stackoverflow.com/questions/10987455/…
Jim Harte
12

Saya mengambil android sebagai contoh.

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

Mohon perhatian : i.localhost tidak dapat digunakan. Perangkat Android terlihat localhost sebagai host itu sendiri. ii.Jika menyebarkan API web di IIS, otentikasi Formulir harus dibuka.

pengguna2293998
sumber
0

Gunakan kode ini dan akses 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) 
}
Sanila Salim
sumber