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


150

Ця тема була для мене неймовірно заплутаною. Я новичок у програмах HTTP, але мені потрібно розробити клієнт iPhone, який споживає дані JSON звідкись. Я вибрав веб-API від MS, тому що це здалося досить простим, але коли мова заходить про автентифікацію користувачів, все стає досить засмучуючим.

Я вражений тим, як мені не вдалося знайти чіткого прикладу того, як автентифікувати користувача прямо з екрана входу до використання Authorizeатрибута над моїми ApiControllerметодами через кілька годин Google.

Це не питання, а запит про приклад того, як це точно зробити. Я переглянув наступні сторінки:

Незважаючи на те, що вони пояснюють, як обробляти несанкціоновані запити, вони не демонструють чітко щось подібне LoginControllerабо щось подібне, щоб запитувати облікові дані користувачів та перевіряти їх.

Кожен, хто бажає написати приємний простий приклад або вказати мені в правильному напрямку, будь ласка?

Дякую.


1
Я відповів на зразок того ж питання про це: stackoverflow.com/questions/11775594 / ...
cuongle

Для Web Api з asp.net ви можете просто використовувати модуль cookie та форма автентифікації формату, як це було б із додатком mvc (якщо ви хочете). Тож у своєму веб-коді api ви можете перевірити головного, щоб перевірити, чи користувач увійшов, наприклад (такий же, як раніше).
Елліот

Подивіться також на мою відповідь для stackoverflow.com/questions/11775594/…
Варун Чаттерджи

Я настійно рекомендую багатьом людям читати статтю asp.net/web-api/overview/security/… .
Youngjae

Відповіді:


176

Я вражений тим, як мені не вдалося знайти чіткого прикладу того, як автентифікувати користувача прямо з екрана входу до використання атрибута "Авторизувати" через мої методи ApiController через кілька годин роботи в Google.

Це тому, що ви плутаєтеся в цих двох поняттях:

  • Автентифікація - це механізм, за допомогою якого системи можуть безпечно ідентифікувати своїх користувачів. Системи аутентифікації дають відповіді на запитання:

    • Хто користувач?
    • Чи дійсно користувач тим, ким він / вона представляє себе?
  • Авторизація - це механізм, за допомогою якого система визначає, який рівень доступу конкретного аутентифікованого користувача повинен мати захищені ресурси, контрольовані системою. Наприклад, система управління базами даних може бути спроектована таким чином, щоб надати певним визначеним особам можливість отримувати інформацію з бази даних, але не можливість змінювати дані, що зберігаються в даті бази даних, надаючи іншим особам можливість змінювати дані. Системи авторизації надають відповіді на запитання:

    • Чи має право користувач X отримати доступ до ресурсу R?
    • Чи має право користувач X виконувати операцію P?
    • Чи користувач X має право виконувати операцію P на ресурсі R?

AuthorizeАтрибут в MVC використовується для застосування правил доступу, наприклад:

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

Вищезазначене правило дозволить отримати доступ до методу лише користувачам у ролях адміністраторів та супер користувачів

Ці правила також можна встановити у файлі web.config, використовуючи locationелемент. Приклад:

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

Однак перед тим, як виконувати ці правила авторизації, вам потрібно пройти автентифікацію на поточному веб-сайті .

Хоча ці пояснюють, як обробляти несанкціоновані запити, вони не демонструють чітко щось на кшталт LoginController або щось подібне, щоб запитувати облікові дані користувачів та перевіряти їх.

Звідси ми могли розділити проблему на два:

  • Ідентифікуйте користувачів, коли користуються послугами Web API в межах однієї веб-програми

    Це був би найпростіший підхід, оскільки ви покладаєтесь на автентифікацію в ASP.Net

    Це простий приклад:

    Web.config

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

    Користувачів буде переспрямовано до маршруту облікового запису / входу , там ви зробите власні елементи керування, щоб запитати облікові дані користувачів, а потім встановите cookie автентифікації, використовуючи:

        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);
  • Перехресна аутентифікація

    Цей випадок буде, коли ви відкриваєте лише послуги Web API у веб-додатку, тому у вас буде інший клієнт, який споживає послуги, клієнт може бути іншим веб-додатком або будь-яким додатком .Net (Win Forms, WPF, консоль, служба Windows, тощо)

    Наприклад, припустимо, що ви будете користуватися послугою Web API з іншої веб-програми в тому ж мережевому домені (в межах інтрамережі), в цьому випадку ви можете покластися на автентифікацію Windows, надану ASP.Net.

    <authentication mode="Windows" />

    Якщо ваші послуги доступні в Інтернеті, вам потрібно буде передати аутентифіковані жетони до кожної служби Web API.

    Для отримання додаткової інформації вийдіть на наступні статті:


3
Оце Так! Це я називаю відповіддю. Отже, для висновку. Я планую виконати наступне: 1. Створіть контролер облікового запису методом входу, який отримує ім’я користувача та пароль через HTTPS та повертає результат входу та маркер. 2. Клієнт зберігає маркер і надсилає його як заголовок (більше немає HTTPS) у запиті, який перевіряється веб-сервером. Це хороший підхід? Тоді моє останнє сумнів - як контролювати підробку маркерів та їх закінчення. Чи можливо це?
Луїс Агілар

6
@Jupaol Я думаю, що я розмовляю з багатьма розробниками Web API, я не можу використовувати автентифікацію форм, оскільки у мене немає веб-сайту, а клієнти не використовують браузер, а також не можу використовувати інтегровану автентифікацію, оскільки користувачі можуть знаходитись у будь-якій точці світу на будь-якому пристрої ( отже, Web API), і що я використовую?
markmnl

21
Я не розумію, чому ця відповідь отримує стільки голосів. Йдеться не про веб-API ASP.NET, а про ASP.NET MVC.
Бастієн Вандамме

3
Я хотів би ще раз зазначити коментар B413 і зазначити, що це питання спеціально задає веб-API
Julien

6
Це найбільш відповідна «неправильна» відповідь на ПС? Відповідь насправді не говорить про веб-api, який сильно відрізняється від веб-програми mvc! Like @ B413 Я повністю шокований!
stt106

15

Якщо ви хочете пройти автентифікацію на ім’я користувача та пароль та без файлу cookie авторизації, атрибут MVC4 Authorize не вийде з поля. Однак ви можете додати наступний допоміжний метод до свого контролера, щоб прийняти основні заголовки аутентифікації. Викликайте його з початку методів вашого контролера.

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

З боку клієнта цей помічник створює HttpClientзаголовок аутентифікації на місці:

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

Просто хотів прокоментувати, що я шукав простий спосіб використовувати галузевий стандарт для передачі облікових даних у заголовку. Цей приклад показав основи як із сервера, так і з боку клієнта, і було все, що мені потрібно.
da_jokker

9

Я працюю над проектом MVC5 / Web API і мені потрібно було отримати дозвіл на методи Web Api. Коли мій перегляд індексу завантажується вперше, я дзвоню до методу «API» Web API, який я вважаю, створюється автоматично.

Код клієнтської сторони (CoffeeScript) для отримання маркера:

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

У разі успіху викликається наступне, що зберігає маркер аутентифікації локально:

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

Тоді, якщо мені потрібно здійснити виклик Ajax до методу Web API, який має тег [Авторизувати], я просто додаю наступний заголовок до мого виклику Ajax:

{ "Authorization": "Bearer " + window.authenticationToken }

Звідки response.access_tokenпоходить. Ви встановлюєте його з c # кодом ..?
shashwat

Об'єкт 'відповідь' повертається методом 'token'.
ПрофНімрод

Я не розглядав ролі. Цей підхід просто дає токен доступу, щоб ви могли викликати методи WebApi, прикрашені тегом [Авторизувати]. Імовірно, коли ви закликаєте будь-який із цих методів, ви можете перевірити наявність ролей. stackoverflow.com/questions/19689570/mvc-5-check-user-role може допомогти.
ProfNimrod

І де в цьому рішенні ви насправді автентифікуєте свого користувача?
Крейг Бретт

Кінцева точка / лексеми створюється автоматично для будь-якого нового проекту Web API. Код, що стоїть за цим пунктом, є користувачем. Це трохи складніше, якщо ви додали контролер Web API до існуючого проекту MVC.
ПрофНімрод
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.