Аутентификация пользователя/пароля с использованием RESTful WCF и форм Windows

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

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

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

После того, как я работал с сервисом, я вернулся для обеспечения безопасности. "Вопросы безопасности" (в квартал вниз по странице) и попытался реализовать заголовок HTTP-авторизации в соответствии с инструкциями, однако я обнаружил, что код является неполным (см., Как никогда не объявлялась переменная UserKeys). Это тот момент, когда я пытался больше исследовать, как это сделать (используя хеш-память HMAC с HTTP-заголовком "Authorization", но не смог найти многого в google?), Это привело меня к другим статьям, касающимся безопасности на уровне сообщений, формы auth и пользовательские валидаторы, и, честно говоря, я не уверен, какой из них лучше всего подходит.

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

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

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

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

Как сказано, приложение .NET 3.5 win forms, служба 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" };
    }

Ответ 1

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

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

и

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

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

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

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

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

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

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

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

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

Ответ 2

Использование обычной проверки подлинности:

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

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

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

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

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

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

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

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

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

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

Ответ 4

Ну, вы действительно не должны уделять столько внимания стороне 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