การรับรองความถูกต้อง ASP.NET Web API


122

ฉันกำลังมองหาในการตรวจสอบผู้ใช้จากโปรแกรมประยุกต์ไคลเอ็นต์ในขณะที่ใช้เว็บ ASP.NET API ฉันได้ดูวิดีโอทั้งหมดบนไซต์และอ่านโพสต์ในฟอรัมนี้ด้วย

การใส่[Authorize]แอตทริบิวต์อย่างถูกต้องจะส่งคืน401 Unauthorizedสถานะ อย่างไรก็ตามฉันต้องการทราบวิธีอนุญาตให้ผู้ใช้เข้าสู่ระบบ API

ฉันต้องการให้ข้อมูลรับรองผู้ใช้จากแอปพลิเคชัน Android ไปยัง API ให้ผู้ใช้เข้าสู่ระบบจากนั้นจึงมีการตรวจสอบสิทธิ์การเรียกใช้ API ที่ตามมาทั้งหมด


สวัสดี Mujtaba คุณสามารถใช้สิ่งนี้ได้หรือไม่?
Vivek Chandraprakash

ขั้นแรกให้ใช้ CORS เพื่อป้องกันการโจมตีที่ไม่ต้องการจากโดเมนอื่น จากนั้นส่งคุกกี้การตรวจสอบความถูกต้องของฟอร์มที่ถูกต้องพร้อมกับคำขอและในที่สุดก็อนุญาตการร้องขอโดยโทเค็น การรวมกันนี้ทำให้เว็บ API ของคุณปลอดภัยและเหมาะสมที่สุด
Majedur Rahaman

คำตอบ:


137

อนุญาตให้ผู้ใช้เข้าสู่ระบบ API

คุณต้องส่งคุกกี้ Forms Authentication ที่ถูกต้องพร้อมกับคำขอ โดยปกติเซิร์ฟเวอร์จะส่งคุกกี้นี้เมื่อตรวจสอบสิทธิ์ ( LogOnการดำเนินการ) โดยเรียกใช้[FormsAuthentication.SetAuthCookieเมธอด (ดูMSDN )

ดังนั้นลูกค้าต้องดำเนินการ 2 ขั้นตอน:

  1. ส่งคำขอ HTTP เพื่อLogOnดำเนินการโดยส่งชื่อผู้ใช้และรหัสผ่าน ในทางกลับกันการดำเนินการนี้จะเรียกใช้FormsAuthentication.SetAuthCookieเมธอด (ในกรณีที่ข้อมูลรับรองถูกต้อง) ซึ่งจะตั้งค่าคุกกี้การตรวจสอบรูปแบบในการตอบกลับ
  2. ส่งคำขอ HTTP ไปยังการ[Authorize]ดำเนินการที่ได้รับการป้องกันโดยการส่งไปตามคุกกี้การตรวจสอบความถูกต้องของแบบฟอร์มที่เรียกมาในคำขอแรก

ลองมาเป็นตัวอย่าง สมมติว่าคุณมีตัวควบคุม API 2 ตัวที่กำหนดไว้ในเว็บแอปพลิเคชันของคุณ:

คนแรกที่รับผิดชอบในการจัดการการรับรองความถูกต้อง:

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

และรายการที่สองมีการดำเนินการที่มีการป้องกันซึ่งมีเพียงผู้ใช้ที่ได้รับอนุญาตเท่านั้นที่สามารถมองเห็น:

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

ตอนนี้เราสามารถเขียนแอปพลิเคชันไคลเอนต์ที่ใช้ API นี้ได้ นี่คือตัวอย่างแอปพลิเคชันคอนโซลที่ไม่สำคัญ (ตรวจสอบให้แน่ใจว่าคุณได้ติดตั้งMicrosoft.AspNet.WebApi.ClientและMicrosoft.Net.Httpแพ็คเกจ 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");
            }
        }
    }
}

และนี่คือลักษณะของคำขอ HTTP 2 รายการบนสาย:

คำขอรับรองความถูกต้อง:

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

การตอบสนองการรับรองความถูกต้อง:

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

ขอข้อมูลที่มีการป้องกัน:

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

การตอบสนองสำหรับข้อมูลที่มีการป้องกัน:

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"

จะรักษาเซสชันสำหรับแอปพลิเคชัน Android หรือไม่
Mujtaba Hassan

มีประเด็น แต่คุณช่วยโพสต์โค้ดตัวอย่างสำหรับจุดที่สองได้ไหม ขอบคุณสำหรับคำตอบ.
Mujtaba Hassan

2
การเขียนไคลเอ็นต์ HTTP ของ Android เป็นประเด็นสำหรับคำถามอื่น มันไม่เกี่ยวข้องกับ ASP.NET MVC และ ASP.NET MVC Web API ซึ่งเป็นคำถามของคุณ ฉันอยากจะแนะนำให้คุณเริ่มเธรดใหม่ที่ติดแท็กอย่างชัดเจนด้วย Java และ Android ซึ่งคุณจะถามเกี่ยวกับวิธีการเขียนไคลเอนต์ HTTP ที่ส่งคำขอโดยใช้คุกกี้
Darin Dimitrov

จริงๆแล้วในเอกสารของ MVC4 WebApi พวกเขาได้เขียนไว้ว่า WebAPI มีเป้าหมายสำหรับลูกค้าบุคคลที่สามโดยเฉพาะไคลเอนต์มือถือ (และแน่นอนว่าเป็นเช่นนั้น) สมมติว่าเรามีไคลเอนต์แอปพลิเคชันบนเดสก์ท็อปคุณสามารถโพสต์ข้อมูลโค้ดง่ายๆได้ไหม ขอบคุณ
Mujtaba Hassan

2
ดูคำถามนี้ (และคำตอบ) เกี่ยวกับการใช้การตรวจสอบสิทธิ์พื้นฐาน HTTP: stackoverflow.com/questions/10987455/…
Jim Harte

12

ฉันใช้ Android เป็นตัวอย่าง

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

โปรดทราบ: ไม่สามารถใช้ i.localhost ได้ อุปกรณ์ Android มีลักษณะเป็น localhost เป็นโฮสต์ ii หากปรับใช้เว็บ API ใน IIS ต้องเปิดการพิสูจน์ตัวตนแบบฟอร์ม


0

ใช้รหัสนี้และเข้าถึงฐานข้อมูล

[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) 
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.