Пользовательская / проходная аутентификация с использованием RESTful WCF и Windows Forms - PullRequest
36 голосов
/ 28 декабря 2008

Каков наилучший подход к реализации авторизации / аутентификации для приложения Windows Forms, использующего службу RESTful WCF, размещенную на IIS?

Причина, по которой я спрашиваю, состоит в том, что я очень запутался, после того как просеял различные статьи и посты, в которых излагался другой метод, и, в конце концов, попал в документ на ~ 650 страниц по рекомендациям по безопасности WCF "(http://www.codeplex.com/WCFSecurityGuide) Я просто не уверен ЛУЧШИЙ подход и как начать реализацию, учитывая мой сценарий.

Я начал с этой статьи «Руководство по проектированию и созданию веб-сервисов RESTful с WCF 3.5» (http://msdn.microsoft.com/en-us/library/dd203052.aspx)) и видео с PDC о сервисах RESTful WCF, что было здорово и помогло мне реализовать мой первый REST-friendly WCF сервис,

После того, как служба работала, я вернулся для обеспечения безопасности, понимаете. «Соображения безопасности» (четверть страницы) и попытался реализовать HTTP-заголовок авторизации в соответствии с инструкциями, однако я обнаружил, что код неполон (посмотрите, как никогда не объявлялась переменная UserKeys). Именно в этот момент я попытался узнать больше о том, как это сделать (используя HMAC-хеш с заголовком HTTP «Авторизация», но не смог найти много в Google?), Он привел меня к другим статьям, касающимся безопасности на уровне сообщений, формы auth и пользовательские валидаторы, и, честно говоря, я не уверен, какой из них является наилучшим и наиболее подходящим подходом.

Итак, учитывая все сказанное (и спасибо, что выслушали до сих пор!), Я думаю, мои основные вопросы:

- Какую реализацию безопасности мне следует использовать?

- Есть ли способ избежать отправки имени пользователя / пароля при каждом вызове WCF? Я предпочел бы не посылать эти дополнительные байты, если соединение было установлено в начале, что будет до того, как последующие вызовы будут разрешены после входа в систему.

- Должен ли я вообще беспокоиться о чём-либо, кроме простого текста, если я использую SSL?

Как уже говорилось, .NET 3.5 приложение для создания форм, служба WCF, размещенная на IIS, однако важно, чтобы я желал, чтобы все службы WCF требовали эту процедуру авторизации (как бы это ни было, сеанс, заголовок http или другое) как Я не хочу, чтобы кто-нибудь мог использовать эти сервисы из Интернета.

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

PS: мне также известно об этом посте Как настроить безопасные службы RESTful с WCF, используя имя пользователя / пароль + SSL , и если сообщество предложит мне отойти от REST для служб WCF, я могу сделать это Однако я начал с этого, чтобы сохранить согласованность для любых публичных API.

Я думаю, что важно указать, как я получаю доступ к своей службе WCF (контакт со службой работает, но каков наилучший способ проверки учетных данных - и затем возврата объекта Member?):

WebChannelFactory<IMemberService> cf = new WebChannelFactory<IMemberService>(
                new Uri(Properties.Settings.Default.MemberServiceEndpoint));
            IMemberService channel = cf.CreateChannel();
            Member m = channel.GetMember("user", "pass");

Код, который был наполовину реализован из статьи MS (и мой собственный для тестирования):

 public Member GetMember(string username, string password)
    {
        if (string.IsNullOrEmpty(username))
            throw new WebProtocolException(HttpStatusCode.BadRequest, "Username must be provided.", null);
        if (string.IsNullOrEmpty(password))
            throw new WebProtocolException(HttpStatusCode.BadRequest, "Password must be provided.", null);

        if (!AuthenticateMember(username))
        {
            WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Unauthorized;
            return null;
        }

        return new Member() { Username = "goneale" };
    }

Ответы [ 4 ]

17 голосов
/ 29 декабря 2008

Ну, у меня нет опыта работы с возможностями REST WCF, но я много боролся с пониманием последствий выбора безопасности в моем вопросе безопасности WCF . Как вы заметили, в WCF практически отсутствует документация по ним в Интернете, и мой опыт работы с REST ограничен, поэтому возьмите мои ответы с недоверием:

Какую реализацию безопасности я должен использовать?

и

Стоит ли мне вообще беспокоиться о чём-либо, кроме простого текста, если я использую SSL?

Базовая аутентификация по SSL - это хорошо - в конце концов, именно так многие существующие веб-сайты аутентифицируют пользователей. (Когда вы входите в свою учетную запись Amazon для покупок, они просто передают ваше имя пользователя и пароль, когда вы вводите его через соединение SSL.) Я понимаю, что в статье говорится о атаках на безопасность и словарь, но бла-бла-бла, сделайте это просто и сначала что-нибудь получится. Простой XML API UPS запрашивает имя пользователя и пароль при каждом вызове, так же как API POX FedEx, так же как SOAP API PayPal и SOAP API CyberSource - это, кажется, достаточно для реального использования.

Есть ли способ избежать отправки имени пользователя / пароля при каждом вызове WCF? Я предпочел бы не посылать эти дополнительные байты, если соединение было установлено в начале, что будет до того, как последующие вызовы будут разрешены после входа в систему.

На этот вопрос я могу ответить чуть более уверенно. Обычно мы пытаемся сделать так, чтобы наши общедоступные службы WCF не имели состояния. Таким образом, наши сервисы WCF легко масштабируются; просто добавьте больше оборудования и больше серверов и балансировщиков нагрузки для решения этой проблемы, и нам не нужно беспокоиться о зависании сеансов или сохранении состояния сеанса где-либо. Так что это означает, что если мы хотим «держать пользователя в системе», то это не то, что должно произойти на сервере.

То, что я в итоге сделал, трактует мой веб-сайт как доверенную подсистему. Он проходил проверку подлинности в службе WCF с использованием предварительно общего сертификата X509, и если клиент был зарегистрирован на веб-сайте с помощью проверки подлинности с помощью форм, он отправлял бы заголовок имени пользователя клиента в службу; пользовательское поведение конечной точки в службе WCF будет искать этот заголовок, видеть, что он установлен доверенной подсистемой, и продолжать олицетворять этого пользователя без необходимости ввода или проверки пароля пользователя в базе данных.

Поскольку вы используете REST, вы, вероятно, могли бы использовать cookie на стороне клиента для поддержания состояния. Если вы используете режим совместимости ASP.NET, я думаю, что вы даже можете напрямую использовать проверку подлинности с помощью форм, но я не очень разбираюсь в этом подходе, поскольку моя служба WCF не была размещена в IIS.

Короче говоря, вам придется отправлять что-то с каждым запросом, чтобы идентифицировать пользователя, будь то имя пользователя и пароль, просто имя пользователя или какое-то хешированное значение, хранящееся в печенье. Если последний вариант, я думаю, у вас должен быть какой-то метод Login() или что-то в сервисе, что-то, что отправит «хорошо, вы вошли, если вы передадите это хеш-значение с будущими запросами». Но не все клиенты REST будут ожидать получения файлов cookie, просто простые запросы GET / PUT / POST / DELETE без какого-либо состояния.

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

Надеюсь, это немного поможет.

7 голосов
/ 31 марта 2010

Использование обычной аутентификации:

WebHttpBinding binding = new WebHttpBinding();
binding.SendTimeout = TimeSpan.FromSeconds(25);
binding.Security.Mode = WebHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;

Uri address = new Uri("http://localhost:3525/WcfRestWeb/Quotes.svc");

WebChannelFactory<IQuoteService> factory =
             new WebChannelFactory<IQuoteService>(binding, address);

factory.Credentials.UserName.UserName = "tan";
factory.Credentials.UserName.Password = "wani";

IQuoteService proxy = factory.CreateChannel();

var response = proxy.GenerateQuote(GetQuoteRequest());
Console.WriteLine("Quote Amount: " + response.QuoteAmount);
3 голосов
/ 29 декабря 2008

Спасибо за ответы. Отступив назад и взглянув четко и беспристрастно на проблему в целом (другими словами, не обращая внимания на 4+ часа, которые я потратил на поиск услуг RESTful), я сейчас пытаюсь заставить эту работу работать без REST и ссылок, на которые я пытаюсь следовать момент они: -

Это похоже на то, что я хочу.

lextm: Я слышал вас об этом, после того как я написал пост, я внимательно просмотрел руководство по безопасности WCF и сделал заметки обо всех моих требованиях, основываясь на опциях, которые они хотят, чтобы вы подумали над каждым Тенета.

Я выбрал:
- Режим безопасности передачи: безопасность транспорта
- Авт. Опция: базовая безопасность
- Связывание: wsHttpBinding
- Пользовательская аутентификация с валидатором имени

В свете примеров, предоставленных для каждого, и с учетом варианта использования оконных форм с сервисом WCF, кажется, что это лучший путь.

Николас: Согласен, разработка услуг для лиц без гражданства, вероятно, является лучшим подходом.

Итак, основываясь на статье, которой я буду следовать, когда у меня будет время, он использует сертификат X509. что я очень новичок (понимаю, вы используете этот Николас) это будет хорошо, учитывая, что это клиентское приложение можно загрузить из Интернета и установить на чей-либо компьютер, который имеет учетную запись на моем сайте?

Приветствую за вашу помощь, Graham

PS: Я думаю, что это наиболее близкий вариант использования к моему сценарию (за исключением того, что я хочу использовать безопасность на транспорте), должен ли я рассмотреть возможность реализации этого, так как это не беспокоит сертификат? Из цитаты, которую я прочитал, мне может понадобиться сертификат. как «WCF требует шифрования сертификата X509, потому что учетные данные клиента (имя пользователя / пароль) передаются в виде текста в сообщении SOAP». - однако из того, что я узнал и что мы сказали, если я использую SSL, этот вопрос, вероятно, спорный?

1 голос
/ 28 декабря 2008

Ну, вы действительно не должны обращать так много внимания на сторону WinForms, потому что сторона WCF - это ключ.

Кстати, вы внимательно читали эти страницы?

Концепция http://www.codeplex.com/WCFSecurityGuide/Wiki/View.aspx?title=Ch%2005%20-%20Authentication,%20Authorization%20and%20Identities%20in%20WCF&referringTitle=Home

и как http://www.codeplex.com/WCFSecurity/Wiki/View.aspx?title=How%20Tos&referringTitle=Home

...