ASP.NET MVC – проверка подлинности HTTP

Возможно ли заставить мое приложение запрашивать имя пользователя и пароль, запрашивая его перед визуализацией? Как и в twitter API для получения информации о вашей учетной записи:

http://twitter.com/account/verify_credentials.xml

Поэтому перед отображением вида || файл просит вас ввести вам имя пользователя и пароль, я думаю, что это делается непосредственно на сервере, поскольку запрос на curl основан на имени пользователя: password, а также:

curl -u user:password http://twitter.com/account/verify_credentials.xml 

Поскольку я пытаюсь создать API, следуя той же структуре, я хотел бы знать, как это сделать на ASP.NET MVC C #. Я уже использовал это на rubyовых рельсах, и это довольно просто:

 before_filter :authenticate def authenticate authenticate_or_request_with_http_basic do |username, password| username == "foo" && password == "bar" end 

Я не думаю, что фильтр [Авторизовать] тот же, поскольку я считаю, что это просто redirect, и перенаправляет вас к внутреннему controllerу учетных записей, который основан на базе данных учетных записей, в этом случае я буду использовать другую базу данных, в частности, из webservice и выполнить проверку после отправки информации. Но мне нужно действие, чтобы потребовать пользователя и передать учетные данные по его запросу.

заранее спасибо


ОБНОВИТЬ:

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

 request.Credentials = new NetworkCredential("username", "password"); 

И это отразится на подсказке имени пользователя и пароля.

Таким образом, это точно то же самое, но с другой стороны, если можно запросить информацию в приглашении на аутентификацию по запросу, как я могу потребовать эту аутентификацию по запросу?

Поэтому каждый раз кто-то пытается сделать запрос к моему приложению, например:

Http: // MyApplication / клиенты / verify_credentials

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

 curl -u user:password http://myapplication/clients/verify_credentials 

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

Я написал ActionFilterAttribte чтобы узнать, могу ли я получить нужное поведение, если в web.config не установлен модуль проверки подлинности.

 public class RequireBasicAuthentication : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { var req = filterContext.HttpContext.Request; if (String.IsNullOrEmpty(req.Headers["Authorization"])) { var res = filterContext.HttpContext.Response; res.StatusCode = 401; res.AddHeader("WWW-Authenticate", "Basic realm=\"Twitter\""); res.End(); } } } 

И действие controllerа:

 [RequireBasicAuthentication] public ActionResult Index() { var cred = System.Text.ASCIIEncoding.ASCII .GetString(Convert.FromBase64String( Request.Headers["Authorization"].Substring(6))) .Split(':'); var user = new { Name = cred[0], Pass = cred[1] }; return Content(String.Format("user:{0}, password:{1}", user.Name, user.Pass)); } 

Это действие успешно печатает имя пользователя и пароль, которые я вводил. Но я действительно сомневаюсь, что это лучший способ сделать это. У вас нет выбора, кроме как запросить имя пользователя и пароль таким образом?

Вы действительно хотите создать службу, а не веб-приложение, основанное на том, что я прочитал. Я угадываю здесь, но я думаю, что вы выбрали ASP.NET MVC, чтобы воспользоваться маршрутизацией и построить URL-адрес так, как вы хотите? Поправьте меня, если я ошибаюсь.

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

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

Я изменил ответ çağdaş, чтобы поместить всю логику в свой собственный атрибут ActionFilter.

 public class BasicAuthenticationAttribute : ActionFilterAttribute { public string BasicRealm { get; set; } protected string Username { get; set; } protected string Password { get; set; } public BasicAuthenticationAttribute(string username, string password) { this.Username = username; this.Password = password; } public override void OnActionExecuting(ActionExecutingContext filterContext) { var req = filterContext.HttpContext.Request; var auth = req.Headers["Authorization"]; if (!String.IsNullOrEmpty(auth)) { var cred = System.Text.ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(auth.Substring(6))).Split(':'); var user = new { Name = cred[0], Pass = cred[1] }; if (user.Name == Username && user.Pass == Password) return; } var res = filterContext.HttpContext.Response; res.StatusCode = 401; res.AddHeader("WWW-Authenticate", String.Format("Basic realm=\"{0}\"", BasicRealm ?? "Ryadel")); res.End(); } } 

Его можно использовать для установки под базовой аутентификацией всего controllerа:

 [BasicAuthenticationAttribute("your-username", "your-password", BasicRealm = "your-realm")] public class HomeController : BaseController { ... } 

или конкретный ActionResult:

 public class HomeController : BaseController { [BasicAuthenticationAttribute("your-username", "your-password", BasicRealm = "your-realm")] public ActionResult Index() { ... } } 

ПРИМЕЧАНИЕ . Вышеупомянутая реализация требует, чтобы разработчик вручную ввел имя пользователя и пароль в качестве необходимых параметров ActionFilter, но может быть легко расширен, чтобы обеспечить поддержку любого механизма авторизации (MembershipProvider, идентификатор ASP.NET, пользовательская firebase database на внешней СУБД или файл и т. Д. ), удалив пользовательский конструктор и соответствующим образом изменив IF-блок OnActionExecuting.

Вы также можете прочитать здесь для получения дополнительной информации .

Вот как это работает для меня. Это небольшая работа, но это сделает IIS и MVC3 более похожими на все другие системы аутентификации Basic Http, такие как Apache …

Шаг 1.

Убедитесь, что для IIS установлена ​​«Основная проверка подлинности».

(Пример: Панель управления -> Программы и функции -> Включить или отключить функции Windows)

* Я использую Windows 7 в данный момент и не уверен, что именно путь. [GOOGLE: установка базовой аутентификации в IIS] должна вас закрыть.

Шаг 2.

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

Шаг 3.

(Примечание: я использую MVC3 и считаю, что это должно работать в большинстве моделей, включая ASP.Net, без особых проблем).
В вашем проекте вам нужно будет добавить следующие classы:

 public class ServicePrincipal : IPrincipal { // This answers the "What am I allowed to do" question // In real life, this guy will contain all your user info // and you can put what ever you like and retrieve it // later via the HttpContext, on your application side. // Some fun with casting will be required. public static IPrincipal Default { get { return new ServicePrincipal { Identity = new ServiceIdentity { AuthenticationType = "Test", IsAuthenticated = true, Name = "Basic" } }; } } public IIdentity Identity { get; set; } public bool IsInRole(string role) { // If you want to use role based authorization // eg [Authorize(Roles = "CoolPeople")] // This is the place to do it and you can do // anything from load info from a db or flat file // or simple case statement...though that would // be silly. return true; } } public class ServiceIdentity : IIdentity { // This answers the "Who Am I" Question public string AuthenticationType { get; set; } public bool IsAuthenticated { get; set; } public string Name { get; set; } } public class ServiceModule : IHttpModule { // This is the module for IIS public void Init(HttpApplication context) { context.AuthenticateRequest += this.BasicAuthenticationRequest; } public void BasicAuthenticationRequest(object sender, EventArgs e) { HttpApplication app = sender as HttpApplication; if( !ServiceProvider.Authenticate(app.Context) ) { // Total FAIL! } } public void Dispose() { // Clean up the mess, if needed. } } public class ServiceProvider { public static bool Authenticate( HttpContext context ) { // For the example we are going to create a nothing user // say he is awesome, pass him along through and be done. // The heavy lifting of the auth process will go here // in the real world. HttpContext.Current.User = ServicePrincipal.Default; return true; } } 

Шаг 3a. [редактировать]

Вот разные библиотеки, которые вы будете «использовать»,

 using System.Security.Principal; using System.Web; 

Просто хотел бросить их. Я ненавижу, когда люди оставляют их. 🙂

Шаг 4.

Добавьте в свою веб-конфигурацию следующее. Обратите внимание, что я включаю в себя структуру окружения, например тег «Конфигурация» … Это просто дорожная карта, если у вас уже есть тег конфигурации, который не добавляет другой, или IIS расстраивается с вами.

        

Обратите внимание, что пространство имен в {Namespace} .ServiceModule – это пространство имен, которое вы кладете classы со стадии 3 в.

… и это в значительной степени.

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