Аутентификация пользователя в веб-интерфейсе ASP.NET

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

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

Это не вопрос, а запрос на пример того, как это сделать. Я просмотрел следующие страницы:

Несмотря на то, что они объясняют, как обрабатывать несанкционированные запросы, они не демонстрируют явно что-то вроде LoginController или что-то подобное, чтобы запрашивать учетные данные пользователя и проверять их.

Любой, кто хочет написать хороший простой пример или указать мне в правильном направлении, пожалуйста?

Спасибо.

Ответ 1

Я поражен тем, как я не смог найти ясный пример того, как аутентифицировать пользователя прямо с экрана входа в систему, используя атрибут Authorize поверх моих методов 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 или что-то в этом роде, чтобы запрашивать учетные данные пользователя и проверять их.

Отсюда мы могли бы разделить проблему на две части:

  • Аутентификация пользователей при использовании служб веб-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);
    
  • Кросс-платформенная аутентификация

    Этот случай будет, когда вы раскрываете только службы веб-API в веб-приложении, поэтому у вас будет другой клиент, который будет использовать эти услуги, клиентом может быть другое веб-приложение или любое приложение .Net( Win Forms, WPF, консоль, служба Windows и т.д.)

    Например, предположим, что вы будете использовать службу веб-API из другого веб-приложения в том же сетевом домене (внутри интрасети), в этом случае вы можете положиться на аутентификацию Windows, предоставляемую ASP.Net.

    <authentication mode="Windows" />
    

    Если ваши службы отображаются в Интернете, вам необходимо передать аутентифицированные токены каждой службе веб-API.

    Для получения дополнительной информации возьмите добычу в следующие статьи:

Ответ 2

Если вы хотите пройти аутентификацию против имени пользователя и пароля и без файла 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;
}

Ответ 3

Я работаю над проектом MVC5/Web API и должен иметь возможность получить авторизацию для методов Web 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, который имеет тег [Authorize], я просто добавляю следующий заголовок к моему вызову Ajax:

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