Аутентификация для лазурных функций

Последние 24 часа я прочел все о том, как создавать Azure-функции и успешно преобразовал MVC WebApi в новое приложение с несколькими функциями. Моя проблема в том, что я не нашел четкой документации или учебников о том, как сделать с ними основную аутентификацию.

Мой сценарий довольно прямолинейный. Предоставляйте пользователям в AAD, а затем предоставляйте этим пользователям доступ к определенным функциям. Пользователи на веб-сайте будут нажимать на элементы пользовательского интерфейса, которые в свою очередь запускают Javascript, который вызывает мои функции Azure. В функции мне нужно как-то проверить свою личность, поскольку я буду передавать это вместе с другими функциями, которые взаимодействуют с экземпляром SQL.

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

Для записи я нашел на портале конфигурацию "Аутентификация" для моего приложения-функции и выбрал AAD в качестве моего провайдера аутентификации. Я добавил к нему свое приложение-приложение и предоставил несколько пользователей. Затем я написал следующую тестовую функцию:

[FunctionName("GetThings")]
public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.User, "GET", Route = null)]HttpRequestMessage req, TraceWriter log)
{
    log.Info("Getting all the things");
    var identity = ClaimsPrincipal.Current.Identity;

    return identity.IsAuthenticated ?
        req.CreateResponse(HttpStatusCode.Unauthorized, "Not authenticated!") :
        req.CreateResponse(HttpStatusCode.OK, $"Hi {identity.Name}!");
}

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

Помогите?

Ответ 1

После проверки подлинности пользователя в Azure AD вам будет предоставлен AppServiceAuthSessoin cookie AppServiceAuthSessoin. Это непрозрачное печенье, но вы можете обменять его на претензии, позвонив

https://yourFunctionApp.azurewebsites.net/.auth/me

и передавая непрозрачный cookie в качестве заголовка Cookie. Более того, id_token вами id_token хорош для использования в качестве токена Bearer.

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

Get claims

Механизм называется Easy Auth, он проще для Google по этому названию.

Подробнее о магазине токенов здесь -
https://cgillum.tech/2016/03/07/app-service-token-store/

... в котором говорится, что вы можете получить заявки, просто прочитав заголовки HTTP, поступающие из браузера пользователя:

Доступ к токенам

Из вашего внутреннего кода получить доступ к этим токенам так же просто, как прочитать заголовок HTTP-запроса. Заголовки названы как X-MS-TOKEN-{provider}-{type}. Возможные имена заголовков токенов перечислены ниже:

Заголовки запроса токена Azure Active Directory:

X-MS-TOKEN-AAD-ID-TOKEN
X-MS-TOKEN-AAD-ACCESS-TOKEN
X-MS-TOKEN-AAD-EXPIRES-ON
X-MS-TOKEN-AAD-REFRESH-TOKEN

Я только что узнал об этом прямо сейчас, так что спасибо за вопрос!

ОБНОВИТЬ:

Моя догадка была верной, id_token также хорош как Bearer:

$ curl -isk https://{funcApp}.azurewebsites.net/api/{someFunc} \
       -H "Authorization: Bearer eyJ0eXAiOi....oEU-Q"

HTTP/1.1 200 OK
Cache-Control: no-cache
Server: Microsoft-IIS/8.0
...

Основное различие между двумя способами чтения утверждений (чтение заголовков и вызов /.auth/me из бэкэнда с пользователем Cookie) заключается в количестве деталей, которые вы получаете. Там больше в последнем.

Вот набор заголовков, которые вы получаете от Easy Auth для аутентифицированного пользователя Twitter:

{
   "cookie": "AppServiceAuthSession=Lx43...xHDTA==",
   ...
   "x-ms-client-principal-name": "evilSnobu",
   "x-ms-client-principal-id": "35....",
   "x-ms-client-principal-idp": "twitter",
   "x-ms-token-twitter-access-token": "35...Dj",
   "x-ms-token-twitter-access-token-secret": "OK3...Jx",
}

и претензии вы получите, позвонив /.auth/me:

{
   "access_token": "35...FDj",
   "access_token_secret": "OK3...sJx",
   "provider_name": "twitter",
   "user_claims": [
      {
         "typ": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
         "val": "352660979"
      },
      {
         "typ": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn",
         "val": "evilSnobu"
      },
      {
         "typ": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
         "val": "Safarihat Hacker"
      },
      {
         "typ": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/webpage",
         "val": "..."
      },
      {
         "typ": "urn:twitter:description",
         "val": "GENIUS. HAVE BRAIN. WILL TRAVEL."
      },
      {
         "typ": "urn:twitter:location",
         "val": ""
      },
      {
         "typ": "urn:twitter:time_zone",
         "val": "London"
      },
      {
         "typ": "urn:twitter:lang",
         "val": "en"
      },
      {
         "typ": "urn:twitter:verified",
         "val": "False"
      },
      {
         "typ": "urn:twitter:profile_image_url_https",
         "val": "https://pbs.twimg.com/profile_images/867473646876545024/1elebfK1_normal.jpg"
      }
   ],
   "user_id": "evilSnobu"
}

Ответ 2

Я создал небольшое расширение для Azure Functions v2, которое может помочь вам при использовании с токенами на предъявителя.

Например, для работы с Azure B2C, когда вы хотите разрешить анонимные запросы к приложению.

Таким образом, вы можете получить право ClaimsPrincipal в функции Azure без использования какого-либо шаблона.

[FunctionName("Example")]
public async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
    [FunctionToken] FunctionTokenResult token,
    ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");
    return (ActionResult) new OkObjectResult($"Hello, {token}");
}

Код опубликован на Github

Ответ 3

AuthorizationLevel.User в настоящее время не поддерживается функциями azure, см. Здесь

По состоянию на декабрь 2017 года это не полностью реализовано.