Добавление базового HTTP-аутентификации в службу WCF REST

У меня есть служба HTTP REST WCF, и я связываюсь с ней с клиентом HTTP на другом языке программирования, который пишет свой собственный HTTP-протокол. Я хотел бы добавить поддержку базовой аутентификации WWW-Authenticate для моей службы WCF.

Мои методы выглядят так:

[WebInvoke(UriTemplate = "widgets", Method = "POST")] public XElement CreateWidget(XElement e) { ... } 

Возможно ли, чтобы я каким-то образом отфильтровывал входящие HTTP-запросы, поэтому я могу проверить допустимую строку Basic auth, прежде чем он ударит по каждому из методов REST, например CreateWidget выше? Примечание. Моя учетная запись является stord в моей базе данных.

В основном я хочу проверить это в заголовках запроса: Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== а затем я могу сам проанализировать эту строку и проверить u / p в базе данных.

Файл web.config выглядит следующим образом:

                        

Я также интересовался пользовательской аутентификацией в службе REST HTTP WCF и, наконец, получил ее работу.

Это говорит о том, что мой код даст вам способ заставить его работать, но я рекомендую прочитать это руководство, которое объясняет все более подробно: http://wcfsecurityguide.codeplex.com/

Во-первых, измените часть system.web вашего Web.Config следующим образом:

         

Затем добавьте еще один файл в свой проект: UserNameAuthenticator.cs

 using System; using System.Collections.Generic; using System.Text; using System.Web; using System.Web.Security; using System.Security.Principal; using System.ServiceModel.Activation; namespace YourNamespace { public class UserNameAuthenticator : IHttpModule { public void Dispose() { } public void Init(HttpApplication application) { application.AuthenticateRequest += new EventHandler(this.OnAuthenticateRequest); application.AuthorizeRequest += new EventHandler(this.OnAuthorizationRequest); application.EndRequest += new EventHandler(this.OnEndRequest); } public bool CustomAuth(string username, string password) { //TODO: Implement your custom auth logic here return true; } public string[] GetCustomRoles(string username) { return new string[] { "read", "write" }; } public void OnAuthorizationRequest(object source, EventArgs eventArgs) { HttpApplication app = (HttpApplication)source; //If you want to handle authorization differently from authentication } public void OnAuthenticateRequest(object source, EventArgs eventArgs) { HttpApplication app = (HttpApplication)source; //the Authorization header is checked if present string authHeader = app.Request.Headers["Authorization"]; if (!string.IsNullOrEmpty(authHeader)) { string authStr = app.Request.Headers["Authorization"]; if (authStr == null || authStr.Length == 0) { // No credentials; anonymous request return; } authStr = authStr.Trim(); if (authStr.IndexOf("Basic", 0) != 0) { //header not correct we do not authenticate return; } authStr = authStr.Trim(); string encodedCredentials = authStr.Substring(6); byte[] decodedBytes = Convert.FromBase64String(encodedCredentials); string s = new ASCIIEncoding().GetString(decodedBytes); string[] userPass = s.Split(new char[] { ':' }); string username = userPass[0]; string password = userPass[1]; //the user is validated against the SqlMemberShipProvider //If it is validated then the roles are retrieved from the //role provider and a generic principal is created //the generic principal is assigned to the user context // of the application if (CustomAuth(username, password)) { string[] roles = GetCustomRoles(username); app.Context.User = new GenericPrincipal(new GenericIdentity(username, "Membership Provider"), roles); } else { DenyAccess(app); return; } } else { //the authorization header is not present //the status of response is set to 401 and it ended //the end request will check if it is 401 and add //the authentication header so the client knows //it needs to send credentials to authenticate app.Response.StatusCode = 401; app.Response.End(); } } public void OnEndRequest(object source, EventArgs eventArgs) { if (HttpContext.Current.Response.StatusCode == 401) { //if the status is 401 the WWW-Authenticated is added to //the response so client knows it needs to send credentials HttpContext context = HttpContext.Current; context.Response.StatusCode = 401; context.Response.AddHeader("WWW-Authenticate", "Basic Realm"); } } private void DenyAccess(HttpApplication app) { app.Response.StatusCode = 401; app.Response.StatusDescription = "Access Denied"; // error not authenticated app.Response.Write("401 Access Denied"); app.CompleteRequest(); } } // End Class } //End Namespace 

У меня были подобные проблемы, и я нашел множество разных подходов, особенно перекрестные вызовы, а также базовая аутентификация, кажется, немного сложной задачей. Например, JQuery сначала выдает вызов OPTIONS, чтобы проверить, разрешен ли POST. Обычно Wcf отклоняет этот запрос, и вы получаете странную ошибку.

Я, наконец, получил его работу, и вы можете загрузить образец кода из моего блога: http://sameproblemmorecode.blogspot.com/2011/10/creating-secure-restfull-wcf-service.html

Чтобы добавить к этому, Chrome не загрузит диалоговое окно входа, если вы не измените «BasicRealm» на «BasicRealm = сайт» в методе OnEndRequest:

  public void OnEndRequest(object source, EventArgs eventArgs) { if (HttpContext.Current.Response.StatusCode == 401) { //if the status is 401 the WWW-Authenticated is added to //the response so client knows it needs to send credentials HttpContext context = HttpContext.Current; context.Response.StatusCode = 401; context.Response.AddHeader("WWW-Authenticate", "Basic Realm=site"); } } 

И спасибо, это такое простое решение.

  • Как установить флажок в форме ASP.NET?
  • Целочисленная проверка для ввода
  • Проверка подлинности WinForm UI
  • Проверьте, нет ли входов пустых с помощью jQuery
  • Использовать проверку ASP.NET MVC с помощью jquery ajax?
  • Как проверить два поля пароля с помощью ajax?
  • Установить проверку classа для динамического текстового поля в таблице
  • Как я могу изменить или удалить сообщения об ошибках в форме HTML5 по умолчанию?
  • Аутентификация со старым паролем больше не поддерживается, используйте пароли типа 4.1
  • Как проверить правильность данной строки JSON в Java
  • Принудительное JSF обрабатывать, проверять и обновлять компоненты для чтения / отключения ввода в любом случае
  • Interesting Posts

    Как добавить gradleиент к тексту UILabel, но не к фону?

    Как изменить часовой пояс mysql в java-соединении

    Невозможно загрузить флешку на материнскую плату GIGABYTE

    Многострочное регулярное выражение для соответствия конфигурационному блоку

    Очистка диска, кроме DBAN

    Не удается смонтировать USB после небезопасного извлечения

    Как установить текст кнопки «Назад» на UINavigationBar?

    WinRT и региональные настройки. Правильный способ форматирования дат и чисел на основе региональных настроек пользователя?

    Как сделать JAR-файл, содержащий файлы DLL?

    Почему SMART проходит, пока он указывает на ошибку для частоты ошибок чтения RAW?

    Ubuntu 10.10: второй экземпляр Firefox не подчиняется настройкам GTK2

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

    Начать настройку VPN из командной строки (OSX)

    Исключить папку с помощью команды «Найти»

    Как программно открыть экран разрешения для определенного приложения на Android Marshmallow?

    Давайте будем гением компьютера.