Подтвердить что ты не робот

Веб-интерфейс ASP.net Web API RESTful + Обычная аутентификация

Я реализую веб-службу RESTful с помощью ASP.Net Web Api. Я пришел к выводу, что для проверки подлинности используется обычная проверка подлинности + SSL. Каков наилучший/правильный способ его реализации?

Моя первая попытка состояла в том, чтобы сделать это вручную, проанализировав заголовок авторизации, расшифровав и проверив пользователя по моей базе данных. Это работает, но мне интересно, не хватает ли чего-то.

Я видел некоторые решения, используя роли и принципы пользователей. Хотя я не уверен, что они на самом деле делают, я почти уверен, что мне это не понадобится, поскольку в моей базе данных я определяю своих пользователей и их роли.

Кроме того, я еще не совсем понял, есть ли пользователи службы должны отправлять учетные данные с каждым запросом или они каким-то образом кэшируются. Должна ли моя служба делать что-то для того, чтобы это произошло, или полностью для потребителя, чтобы справиться с этим?

И последний вопрос о клиентах, делающих запросы с javascript. Будут ли какие-либо проблемы с "кросс-доменом", если они попытаются использовать эту услугу?

4b9b3361

Ответ 1

Jamie Kurtze дает хорошее объяснение использования базовой аутентификации здесь Основы безопасности веб-API ASP.NET

С моей точки зрения, если вы хотите, чтобы ваши запросы не были апатридом, каждый запрос потребует установки поля проверки подлинности

Jamie Kurtze переносит необходимый код в класс, полученный от DelegateHandler, а Рик Страл проверяет, действительно ли вызов действителен с использованием фильтра. Вы можете прочитать больше в своем блоге на эту тему в Фильтр авторизации базовой аутентификации WebAPI

Ответ 2

Используйте базовую аутентификацию для первоначального (входного) запроса, добавив атрибут [BasicHttpAuthorize] к соответствующим контроллерам/методам. Укажите Users и Roles с атрибутом если это необходимо. Определите BasicHttpAuthorizeAttribute как специализированный AuthorizeAttribute следующим образом:

public class BasicHttpAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        if (Thread.CurrentPrincipal.Identity.Name.Length == 0) { // If an identity has not already been established by other means:
            AuthenticationHeaderValue auth = actionContext.Request.Headers.Authorization;
            if (string.Compare(auth.Scheme, "Basic", StringComparison.OrdinalIgnoreCase) == 0) {
                string credentials = UTF8Encoding.UTF8.GetString(Convert.FromBase64String(auth.Parameter));
                int separatorIndex = credentials.IndexOf(':');
                if (separatorIndex >= 0) {
                    string userName = credentials.Substring(0, separatorIndex);
                    string password = credentials.Substring(separatorIndex + 1);
                    if (Membership.ValidateUser(userName, password))
                        Thread.CurrentPrincipal = actionContext.ControllerContext.RequestContext.Principal = new GenericPrincipal(new GenericIdentity(userName, "Basic"), System.Web.Security.Roles.Provider.GetRolesForUser(userName));
                }
            }
        }
        return base.IsAuthorized(actionContext);
    }
}

У первоначального ответа есть ключ API для пользователя. Используйте клавиши API для последующих вызовов. Таким образом, аутентификация клиента остается действительной, даже если пользователь меняет имя пользователя или пароль. Однако при смене пароля дайте пользователю возможность "отключать клиентов", которую вы реализуете, удалив ключ API на сервере.