Otentikasi Pengguna di ASP.NET Web API

150

Topik ini sangat membingungkan bagi saya. Saya pemula dalam aplikasi HTTP tetapi perlu mengembangkan klien iPhone yang mengkonsumsi data JSON dari suatu tempat. Saya memilih Web API dari MS karena sepertinya cukup mudah tetapi ketika menyangkut otentikasi pengguna, banyak hal yang cukup membuat frustrasi.

Saya kagum bagaimana saya tidak dapat menemukan contoh yang jelas tentang cara mengotentikasi pengguna langsung dari layar masuk ke menggunakan Authorizeatribut di atas ApiControllermetode saya setelah beberapa jam Googling.

Ini bukan pertanyaan tetapi permintaan untuk contoh bagaimana melakukan ini dengan tepat. Saya telah melihat halaman-halaman berikut:

Meskipun ini menjelaskan cara menangani permintaan yang tidak sah, ini tidak menunjukkan dengan jelas sesuatu seperti LoginControlleratau sesuatu seperti itu untuk meminta kredensial pengguna dan memvalidasinya.

Adakah yang mau menulis contoh sederhana yang bagus atau mengarahkan saya ke arah yang benar?

Terima kasih.

Luis Aguilar
sumber
1
Saya telah menjawab pertanyaan yang sama tentang ini: stackoverflow.com/questions/11775594/…
cuongle
Untuk Web Api dengan asp.net, Anda bisa menggunakan modul cookie dan autentikasi form seperti yang Anda lakukan dengan aplikasi mvc (jika Anda mau). Jadi dalam kode api web Anda, Anda kemudian dapat memeriksa kepala sekolah untuk melihat apakah pengguna login, misalnya (sama seperti sebelumnya).
Elliot
Lihat juga jawaban saya untuk stackoverflow.com/questions/11775594/…
Varun Chatterji
Saya sangat merekomendasikan banyak orang membaca artikel asp.net/web-api/overview/security/… .
Youngjae

Jawaban:

176

Saya kagum bagaimana saya tidak dapat menemukan contoh yang jelas tentang bagaimana mengotentikasi pengguna langsung dari layar masuk ke menggunakan atribut Otorisasi atas metode ApiController saya setelah beberapa jam Googling.

Itu karena Anda bingung tentang dua konsep ini:

  • Otentikasi adalah mekanisme di mana sistem dapat mengidentifikasi penggunanya dengan aman. Sistem otentikasi memberikan jawaban atas pertanyaan:

    • Siapa pengguna itu?
    • Apakah pengguna benar-benar mewakili dirinya?
  • Otorisasi adalah mekanisme di mana sistem menentukan tingkat akses yang harus dimiliki pengguna terotentikasi tertentu untuk mendapatkan sumber daya yang dikendalikan oleh sistem. Sebagai contoh, sistem manajemen basis data mungkin dirancang untuk memberikan individu tertentu dengan kemampuan untuk mengambil informasi dari database tetapi tidak kemampuan untuk mengubah data yang disimpan dalam basis data, sementara memberi individu lain kemampuan untuk mengubah data. Sistem otorisasi memberikan jawaban atas pertanyaan:

    • Apakah pengguna X diizinkan untuk mengakses sumber daya R?
    • Apakah pengguna X diizinkan untuk melakukan operasi P?
    • Apakah pengguna X diizinkan untuk melakukan operasi P pada sumber daya R?

The Authorizeatribut dalam MVC digunakan untuk menerapkan aturan akses, misalnya:

 [System.Web.Http.Authorize(Roles = "Admin, Super User")]
 public ActionResult AdministratorsOnly()
 {
     return View();
 }

Aturan di atas hanya akan memungkinkan pengguna dalam peran Admin dan Pengguna Super untuk mengakses metode ini

Aturan-aturan ini juga dapat diatur di file web.config, menggunakan locationelemen. Contoh:

  <location path="Home/AdministratorsOnly">
    <system.web>
      <authorization>
        <allow roles="Administrators"/>
        <deny users="*"/>
      </authorization>
    </system.web>
  </location>

Namun, sebelum aturan otorisasi tersebut dijalankan, Anda harus disahkan ke situs web saat ini .

Meskipun ini menjelaskan cara menangani permintaan yang tidak sah, ini tidak menunjukkan dengan jelas sesuatu seperti LoginController atau sesuatu seperti itu untuk meminta kredensial pengguna dan memvalidasinya.

Dari sini, kami dapat membagi masalah menjadi dua:

  • Otentikasi pengguna saat mengonsumsi layanan API Web dalam aplikasi Web yang sama

    Ini akan menjadi pendekatan yang paling sederhana, karena Anda akan mengandalkan Otentikasi di ASP.Net

    Ini adalah contoh sederhana:

    Web.config

    <authentication mode="Forms">
      <forms
        protection="All"
        slidingExpiration="true"
        loginUrl="account/login"
        cookieless="UseCookies"
        enableCrossAppRedirects="false"
        name="cookieName"
      />
    </authentication>

    Pengguna akan diarahkan ke rute akun / login , di sana Anda akan membuat kontrol khusus untuk meminta kredensial pengguna dan kemudian Anda akan mengatur cookie otentikasi menggunakan:

        if (ModelState.IsValid)
        {
            if (Membership.ValidateUser(model.UserName, model.Password))
            {
                FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                return RedirectToAction("Index", "Home");
            }
            else
            {
                ModelState.AddModelError("", "The user name or password provided is incorrect.");
            }
        }
    
        // If we got this far, something failed, redisplay form
        return View(model);
  • Otentikasi lintas platform

    Kasus ini akan terjadi ketika Anda hanya mengekspos layanan API Web dalam aplikasi Web karena itu, Anda akan memiliki klien lain yang mengkonsumsi layanan tersebut, klien dapat berupa aplikasi Web lain atau aplikasi .Net (Formulir Win, WPF, konsol, layanan Windows, dll)

    Sebagai contoh, asumsikan bahwa Anda akan menggunakan layanan Web API dari aplikasi web lain pada domain jaringan yang sama (dalam intranet), dalam hal ini Anda bisa mengandalkan otentikasi Windows yang disediakan oleh ASP.Net.

    <authentication mode="Windows" />

    Jika layanan Anda terpapar di Internet, maka Anda harus memberikan token yang diautentikasi ke setiap layanan Web API.

    Untuk info lebih lanjut, ambil rampasan ke artikel berikut:

Jupaol
sumber
3
Wow! Itulah yang saya sebut jawaban. Jadi, untuk menyimpulkan. Saya berencana melakukan hal berikut: 1. Buat pengontrol akun dengan metode Login yang menerima nama pengguna dan kata sandi melalui HTTPS dan mengembalikan hasil masuk dan token. 2. Klien menyimpan token dan mengirimkannya sebagai header (tidak ada HTTPS lagi) dalam permintaan yang divalidasi oleh server web. Apakah itu pendekatan yang baik? Maka keraguan terakhir saya adalah bagaimana cara mengontrol token yang merusak dan kedaluwarsa. Apakah ini mungkin?
Luis Aguilar
6
@Jupaol Saya pikir saya berbicara untuk banyak pengembang API Web, saya tidak dapat menggunakan Formulir Otentikasi karena saya tidak memiliki situs web dan klien tidak menggunakan browser, saya juga tidak dapat menggunakan otentikasi Terpadu karena pengguna dapat berada di mana saja di dunia pada perangkat apa pun ( karenanya Web API), jadi apa yang saya gunakan?
markmnl
21
Saya tidak mengerti mengapa jawaban ini mendapat banyak dukungan. Ini bukan tentang ASP.NET Web API tetapi tentang ASP.NET MVC.
Bastien Vandamme
3
Saya ingin mengulangi komentar B413 dan menunjukkan bahwa pertanyaan ini secara khusus meminta Web API
Julien
6
Apakah ini jawaban 'salah' yang paling banyak dipilih pada SO? Jawabannya sebenarnya tidak berbicara tentang api web yang sangat berbeda dari aplikasi web mvc! Seperti @ B413 saya sangat terkejut!
stt106
15

Jika Anda ingin mengautentikasi terhadap nama pengguna dan kata sandi dan tanpa cookie otorisasi , atribut MVC4 Authorize tidak akan berfungsi di luar kotak. Namun, Anda dapat menambahkan metode pembantu berikut ke controller Anda untuk menerima header otentikasi dasar. Sebut saja dari awal metode pengendali Anda.

void EnsureAuthenticated(string role)
{
    string[] parts = UTF8Encoding.UTF8.GetString(Convert.FromBase64String(Request.Headers.Authorization.Parameter)).Split(':');
    if (parts.Length != 2 || !Membership.ValidateUser(parts[0], parts[1]))
        throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "No account with that username and password"));
    if (role != null && !Roles.IsUserInRole(parts[0], role))
        throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "An administrator account is required"));
}

Dari sisi klien, penolong ini membuat HttpClientdengan tajuk otentikasi di tempat:

static HttpClient CreateBasicAuthenticationHttpClient(string userName, string password)
{
    var client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(UTF8Encoding.UTF8.GetBytes(userName + ':' + password)));
    return client;
}
Edward Brey
sumber
Hanya ingin berkomentar bahwa saya sedang mencari cara sederhana untuk menggunakan standar industri untuk lulus kredensial di header. Contoh ini menunjukkan dasar-dasar dari kedua sisi server dan klien dan semua yang saya butuhkan.
da_jokker
9

Saya sedang mengerjakan proyek MVC5 / Web API dan harus bisa mendapatkan otorisasi untuk metode Web Api. Ketika tampilan indeks saya pertama kali dimuat saya membuat panggilan ke metode API Web 'token' yang saya percaya dibuat secara otomatis.

Kode sisi klien (CoffeeScript) untuk mendapatkan token adalah:

getAuthenticationToken = (username, password) ->
    dataToSend = "username=" + username + "&password=" + password
    dataToSend += "&grant_type=password"
    $.post("/token", dataToSend).success saveAccessToken

Jika berhasil berikut ini disebut, yang menyimpan token otentikasi secara lokal:

saveAccessToken = (response) ->
    window.authenticationToken = response.access_token

Kemudian jika saya perlu membuat panggilan Ajax ke metode API Web yang memiliki tag [Otorisasi] saya cukup menambahkan header berikut untuk panggilan Ajax saya:

{ "Authorization": "Bearer " + window.authenticationToken }
ProfNimrod
sumber
Dari mana response.access_tokendatangnya. Apakah Anda mengaturnya dari kode c # ..?
shashwat
Objek 'respons' dikembalikan oleh metode 'token'.
ProfNimrod
Saya belum melihat peran. Pendekatan ini hanya memberi Anda token akses sehingga Anda dapat memanggil metode WebApi yang dihiasi dengan tag [Otorisasi]. Presuambly, ketika Anda memanggil salah satu dari metode itu Anda bisa memeriksa peran. stackoverflow.com/questions/19689570/mvc-5-check-user-role mungkin membantu.
ProfNimrod
Dan di mana dalam solusi ini Anda benar-benar mengotentikasi pengguna Anda?
Craig Brett
Titik akhir / token dibuat secara otomatis untuk proyek API Web baru. Kode di balik ini adalah tempat pengguna diautentikasi. Ini sedikit lebih rumit jika Anda telah menambahkan kontroler Web API ke proyek MVC yang ada.
ProfNimrod