Аутентификация сайта/приложения для доступа к службе веб-API

Краткий вопрос: У меня есть служба веб-API в .NET, а сайт создан только с HTML и AngularJS.

Как разрешить мой сервис ТОЛЬКО моей сети?


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

Предположим, что у меня есть веб-сервис Api (последний) от MS. Поэтому я должен использовать приложение, которое его потребляет. Позвольте определить два сценария.

Сценарий 1:

В том же IIS у меня есть ASP.NET MVC 3/4 с особенностью, что все работы MVC находятся на стороне клиента, сделанные AngularJS, поэтому приложение указывает прямо из JavaScript в Web Api Service.

Сценарий 2:

У меня есть стороннее приложение, которое указывает прямо на веб-службу Api и находится в другой сети/сайте/ничего, кроме связанных.

Итак, мой вопрос:

Как можно аутентифицировать обе системы, чтобы Web Api Service предоставлял доступ к обеим системам (мне все равно, является ли это так или нет) и не дает доступа, например, к парню с клиентом REST, и зашел на сайт с авторизацией пользователя/пароля? Я надеюсь, что эти оба примера дали представление о том, что мне интересно.

Прошу прокомментировать ниже все, что вам нужно, чтобы улучшить этот вопрос лучшим образом!

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

Ответ 1

Как настроить аутентификацию с помощью Сценария 1:

Я заставляю статические файлы проходить через сервер, чтобы обеспечить аутентификацию

Web.config

<compilation>
    <buildProviders>
        <add extension=".html" type="System.Web.Compilation.PageBuildProvider" />
        <add extension=".htm" type="System.Web.Compilation.PageBuildProvider" />
    </buildProviders>
</compilation>

<system.webServer>
     <handlers>
         <add name="HTML" path="*.html" verb="GET, HEAD, POST, DEBUG"   type="System.Web.UI.PageHandlerFactory" resourceType="Unspecified" requireAccess="Script" />
         <add name="HTM" path="*.htm" verb="GET, HEAD, POST, DEBUG" type="System.Web.UI.PageHandlerFactory" resourceType="Unspecified" requireAccess="Script" />
     </handlers>
</system.webServer>

Это позволит мне настроить <authentication> и <authorization> в моем web.config как:

<authorization>
  <allow roles="demo" />
</authorization>

или

 <authorization>
   <deny users="?" />
 </authorization>

Кроме того, я настрою свою страницу входа в систему:

<authentication mode="Forms">
      <forms  path="/" loginUrl="~/login"..

Для Сценарий 2:

Вероятно, вам нужно включить CORS, если это так, вам нужно:

Задайте опцию конфигурации config.EnableCors(); в вашем методе Register; вам также необходимо включить CORS в ApiController, используя атрибут [EnableCors] вместе с объявлением контроллера, вот пример того, как я это делаю:

 [EnableCors(origins: "http://localhost:49595", headers: "*", methods: "*")]
 public class ValuesController : ApiController
 {
 ...

Наконец, чтобы защитить WebApi, нам нужно будет использовать атрибут [Authorize] в контроллерах и, скорее всего, вам нужно будет определить свой собственный метод проверки подлинности для авторизации ваших вторых абонентов. Вы можете выполнить следующие действия:

Ответ 2

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

Существуют различные способы защиты службы RESTful, но если вы хотите ограничить доступ к ней, у вас есть в основном два подхода:

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

В зависимости от того, что вы делаете, ни одно из вышеперечисленных действий не может работать.

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

Итак, это вопрос выдачи одного сертификата для каждого клиента. Это работает для стороннего приложения, но его невозможно реализовать из-за того, что браузеры напрямую обращаются к вашему API. Это будет означать, что вам необходимо установить сертификат для каждого браузера, который обращается к вашему приложению MVC, или переместить доступ к API на стороне сервера MVC и больше не вызывать его напрямую из AngularJS. Если вы можете сделать то, что это хорошо, в противном случае он вернется к чертежной доске...

Надеюсь, это поможет! И если вы найдете подходящее решение, отправьте его как ответ на SO.