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

Бок о бок Базовая и форма аутентификации с помощью ASP.NET Web API

Отказ от ответственности: позвольте мне начать с того, что я новичок в MVC4 + Web Api + Web Services в целом + JQuery. Я мог бы атаковать это под неправильным углом.

Я пытаюсь создать веб-приложение MVC App + Web API в С# для .NET 4 для развертывания в Azure. Веб-api будет использоваться мобильными клиентами (iOS, используя RestKit).

Приложение Web MVC будет относительно простым. Мы хотели бы использовать Аутентификацию форм для этого и SimpleMembership - что мы добились и отлично работаем.

Мы будем использовать методы Web API из сценариев JQuery (Knockout), чтобы заполнить части веб-страниц. Поэтому мы ожидаем, что JQuery будет использовать тот же идентификатор, аутентифицированный с помощью аутентификации по формам.

Однако идея состоит в том, что веб-Api может быть вызван непосредственно мобильными клиентами. Аутентификация нет для них.

Мы смотрели на модель идентичности Thinktecture (http://nuget.org/packages/Thinktecture.IdentityModel https://github.com/thinktecture/Thinktecture.IdentityModel.40). Мы добавили обработчики BasicAuth и AcessKey в конфигурацию, и он работает (см. Код ниже).

При попытке доступа к webapi без проверки подлинности браузер отображает базовое диалоговое окно проверки подлинности и работает как ожидалось.

"Проблема" заключается в том, что, когда вы уже вошли в систему через Authentication Forms и пытаетесь вызвать метод Web Api, вы все равно получаете диалоговое окно Basic Authentication. Другими словами, Thinktecture IdentityModel, похоже, вообще игнорирует аутентификацию форм.

Мои вопросы:

  • Верны ли мои ожидания? что после того, как я выполнил проверку подлинности форм, я не должен делать ничего другого, чтобы позволить сценариям JQuery и т.д. обращаться к веб-API из того же сеанса пользователя браузера.
  • Как это исправить?
  • Если мои ожидания неверны; как это должно работать? т.е.: как я могу выполнить аутентификацию JQuery?

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

Я ценю помощь. Благодарю.

public static AuthenticationConfiguration CreateConfiguration()
{
var config = new AuthenticationConfiguration
        {
            DefaultAuthenticationScheme = "Basic",
            EnableSessionToken = true,
            SetNoRedirectMarker = true
        };            

config.AddBasicAuthentication((userName, password) => userName == password, retainPassword: false);
config.AddAccessKey(token =>
        {
            if (ObfuscatingComparer.IsEqual(token, "accesskey123"))
            {
                return Principal.Create("Custom",
                    new Claim("customerid", "123"),
                    new Claim("email", "[email protected]"));
            }

            return null;
        }, AuthenticationOptions.ForQueryString("key"));
4b9b3361

Ответ 1

Вот решение этой проблемы, с которой я столкнулся раньше.

Примечание. Это решение не включает модель идентификации Thinktecture.

У меня есть абстрактный класс BasicAuthenticationHandler, который является обработчиком делегирования. Вы можете получить этот обработчик, установив последний стабильный пакет WebAPIDoodle NuGet.

Вы можете дать подсказку этому базовому базовому обработчику проверки подлинности, чтобы подавить процесс аутентификации, если запрос уже прошел проверку подлинности (например: по формам auth). Ваш пользовательский обработчик, который вам нужно зарегистрировать, будет выглядеть следующим образом:

public class MyApplicationAuthHandler : BasicAuthenticationHandler {

    public MyApplicationAuthHandler() 
        : base(suppressIfAlreadyAuthenticated: true) { }

    protected override IPrincipal AuthenticateUser(
        HttpRequestMessage request, 
        string username, 
        string password, 
        CancellationToken cancellationToken) { 

        //this method will be called only if the request
        //is not authanticated.

        //If you are using forms auth, this won't be called
        //as you will be authed by the forms auth bofore you hit here
        //and Thread.CurrentPrincipal would be populated.

        //If you aren't authed:
        //Do you auth here and send back an IPrincipal 
        //instance as I do below.

        var membershipService = (IMembershipService)request
            .GetDependencyScope()
            .GetService(typeof(IMembershipService));

        var validUserCtx = membershipService
            .ValidateUser(username, password);

        return validUserCtx.Principal;
    }

    protected override void HandleUnauthenticatedRequest(UnauthenticatedRequestContext context) {

        // Do nothing here. The Autharization 
        // will be handled by the AuthorizeAttribute.
    }
}

В качестве последнего шага вам нужно будет применить System.Web.Http.AuthorizeAttribute (not System.Web.Mvc.AuthorizeAttribute) к вашим контроллерам и методам действий, чтобы предоставить авторизацию для определенных ролей и пользователей.

Надеюсь, это поможет решить вашу проблему.