Аутентифікація веб-API ASP.NET


122

Я хочу перевірити автентифікацію користувача з клієнтської програми під час використання веб-API ASP.NET . Я переглянув усі відео на сайті, а також прочитав цю публікацію на форумі .

[Authorize]Правильно поставлений атрибут повертає a401 Unauthorized статус. Однак мені потрібно знати, як дозволити користувачеві входити в API.

Я хочу надати облікові дані користувачів із програми Android для API, ввійти в систему користувача та попередньо підтвердити всі наступні дзвінки API.


Привіт Муджтаба. Ви змогли це здійснити?
Вівек Чандрапракаш

Спочатку використовуйте CORS для запобігання небажаного потрапляння з домену інших. Потім надішліть дійсне cookie форми автентифікації разом із запитом та нарешті авторизуйте запит токеном. Ця комбінація завжди робить вашу веб-програму безпечною та оптимізованою.
Majedur Rahaman

Відповіді:


137

дозволити користувачеві входити в API

Потрібно надіслати дійсне cookie форми автентифікації разом із запитом. Цей файл cookie зазвичай надсилається сервером при автентифікації ( LogOnдії) за допомогою виклику [FormsAuthentication.SetAuthCookieметоду (див. MSDN ).

Отже, клієнту необхідно виконати 2 етапи:

  1. Надішліть запит HTTP на LogOnдію, надіславши ім’я користувача та пароль. У свою чергу ця дія викличе FormsAuthentication.SetAuthCookieметод (у випадку, якщо облікові дані є дійсними), який, у свою чергу, встановить у відповіді файл cookie автентичності форм.
  2. Надішліть HTTP-запит на [Authorize]захищену дію, надіславши разом із файлом cookie автентифікації, який він отримав у першому запиті.

Візьмемо приклад. Припустимо, у вашому веб-додатку визначено 2 контролери API:

Перший, хто відповідає за обробку автентифікації:

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.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");
            }
        }
    }
}

Ось як виглядають 2 запити HTTP на дроті:

Запит на аутентифікацію:

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?
Муджтаба Хассан

Зрозумів, але чи можете ви, будь ласка, опублікувати зразок коду для другої точки. Дякую за вашу відповідь.
Муджтаба Хассан

2
Написання Android HTTP-клієнта є предметом іншого питання. Це не пов'язано з веб-API ASP.NET MVC та ASP.NET MVC, про що йшлося у вашому запитанні. Я рекомендую вам почати новий потік, явно позначаючи теги Java та Android, в якому ви запитаєте про те, як написати клієнт HTTP, який надсилає запити за допомогою файлів cookie.
Дарин Димитров

Насправді в літературі MVC4 WebApi вони написали, що WebAPI призначений для сторонніх клієнтів, особливо мобільних клієнтів (і, звичайно, це є). Скажімо, у нас є клієнт настільних програм, чи можете ви опублікувати простий фрагмент коду, будь ласка. Спасибі
Муджтаба Хассан

2
Також дивіться це питання (і відповідь) щодо використання базової автентифікації HTTP: stackoverflow.com/questions/10987455/…
Jim Harte

12

Я беру для прикладу андроїд.

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) 
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.