Вызов функции Azure из клиентского приложения в браузере от имени авторизованного пользователя

Моя цель - иметь Angular 8 SPA с бессерверным бэкэндом, представленным несколькими приложениями с функциями Azure, использующими OAuth из Facebook, Google ...

У меня проблема с вызовом функций Azure от имени авторизованных пользователей. Функция видит эти вызовы как анонимных пользователей.

В браузере функция возвращает имя авторизованного пользователя, а при вызове приложения в браузере возвращает «без имени», что означает, что пользователь не авторизован.

Я предполагаю, что сеанс с myapp.azurewebsites.net не отображается в моем приложении, которое находится на localhost (это может быть любой другой домен). Кроме того, я не могу указать сеанс в запросе на функционирование конечной точки.

Итак, как можно авторизовать пользователей и вызывать функции Azure из клиентского приложения в другом домене? Или это возможно только с ручной реализацией токенов JWT с распределенной логикой по всем функциям? Кроме того, я не хочу платить сторонним сервисам, таким как Auth0 или даже AAD.

Джим Сюй предложил способ, который работает, но не в моем случае. Недостатки вижу:

  • При таком подходе я не могу видеть имя пользователя и адрес электронной почты в субъекте претензий. Также не уверен, что я могу использовать в качестве идентификатора пользователя.
  • Логика входа будет распространена на все приложения, использующие API.
  • Потребуется хранить токен FB для аутентификации всех функциональных приложений.

Ищу ответы на такие вопросы:

  1. Есть ли в моем случае аутентификация, управляемая сервером?
  2. Есть ли возможность настроить post_login_redirect_url для получения токена для обслуживания?
  3. Может быть, это можно настроить через https://resources.azure.com/?
  4. Можно ли поделиться токеном доступа для приложений с несколькими функциями? (Таким образом, логика пользовательского интерфейса будет упрощена, чтобы получить доступ к app / .auth / login / provider, а затем сохранить токен службы.)

Мой пример кода и конфигурации:

Вот основные части клиентского приложения, которые я использую для вызова:

<button (click)="call('https://myapp.azurewebsites.net/Function1')">CallWithoutAuth</button>
<button (click)="call('https://myapp.azurewebsites.net/Function2')">CallWithAuth</button>

<a href="https://myapp.azurewebsites.net/.auth/login/facebook?post_login_redirect_url=http%3A%2F%2Flocalhost%3A5000" target="_blank">Log in with Facebook</a>

Тело функции вызова:

var url = 'my azure func url with auth via facebook';
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
    console.log(this.responseText);
  }
};
xhttp.onerror = function(e){console.log(e, this)};
xhttp.open("GET", url, true);
xhttp.send();

Код функции:

public static async Task<IActionResult> Run(
 [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "Func2")] HttpRequest req, 
 ClaimsPrincipal claimsPrincipal)
{
    var name = claimsPrincipal?.Identity?.Name;
    return (ActionResult)new OkObjectResult($"Hello, {name ?? "no name"}");
}

Вот конфигурации приложений функций:

введите здесь описание изображения

Конфигурация CORS:

введите здесь описание изображения

Конфигурация Fasebook:

введите здесь описание изображения


person Vitaliy Goncharuk    schedule 06.02.2020    source источник


Ответы (1)


Согласно моему тесту, мы можем использовать следующие шаги для вызова функции Azure, спроектированной facebook.

  1. Интегрируйте Facebook в свое угловое приложение. после этого мы можем войти в facebook и получить accessToken. Дополнительные сведения о том, как его реализовать, см. В статье.

    Например

    а. добавьте URL-адрес приложения в Valid OAuth Redirect URIs

    б. добавьте следующий код в app.component.ts

    
    export class AppComponent {
      title = 'web';
      fbLibrary() {
    
        (window as any).fbAsyncInit = function() {
          window['FB'].init({
            appId      : '<app id you use to project azure function>',
            cookie     : true,
            xfbml      : true,
            version    : 'v3.1'
          });
          window['FB'].AppEvents.logPageView();
        };
    
        (function(d, s, id){
           var js, fjs = d.getElementsByTagName(s)[0];
           if (d.getElementById(id)) {return;}
           js = d.createElement(s); js.id = id;
           js.src = "https://connect.facebook.net/en_US/sdk.js";
           fjs.parentNode.insertBefore(js, fjs);
         }(document, 'script', 'facebook-jssdk'));
    
    }
    ngOnInit() {
      this.fbLibrary();
    }
      login() {
    
        window['FB'].login((response) => {
    
    
            if (response.authResponse) {
             //get access token
              var accessToken=response.authResponse.accessToken;
              console.log('login response',accessToken);
              window['FB'].api('/me', {
                fields: 'last_name, first_name, email'
              }, (userInfo) => {
    
                console.log("user information");
                console.log(userInfo);
              });
    
            } else {
              console.log('User login failed');
            }
        }, {scope: 'email'});
    }
    }
    
    
    

    c. добавить кнопку входа в html

  2. Вызовите следующий запрос, чтобы обменять этот accessToken на «токен службы приложений».

Запрос

   POST https://<appname>.azurewebsites.net/.auth/login/aad HTTP/1.1
  Content-Type: application/json

  {"access_token":"<token>"}

Ответ

{
    "authenticationToken": "...",
    "user": {
        "userId": "sid:..."
    }
}

введите здесь описание изображения

  1. вызвать лазурную функцию
Get https://myapp.azurewebsites.net/Function1
X-ZUMO-AUTH: <authenticationToken_value>

введите здесь описание изображения Для получения дополнительной информации см. https://docs.microsoft.com/en-us/azure/app-service/app-service-authentication-how-to.

person Jim Xu    schedule 10.02.2020
comment
Спасибо, это работает, но не так, как я ожидал. Проблемы: 1) При таком подходе я не вижу имя пользователя и адрес электронной почты в субъекте претензий. Также не уверен, что я могу использовать в качестве идентификатора пользователя. 2) Логика входа будет распределена между всеми пользователями API. Альтернатива ?: Есть ли для моего случая аутентификация, управляемая сервером? Есть ли возможность настроить post_login_redirect_url для получения токена для обслуживания? Может быть, это можно настроить через resources.azure.com? (Таким образом, логика пользовательского интерфейса будет упрощена, чтобы получить доступ к app / .auth / login / provider, а затем сохранить токен службы.) - person Vitaliy Goncharuk; 11.02.2020
comment
@VitaliyGoncharuk Насколько я знаю, у нас нет возможности сделать это. Дополнительные сведения см. В документации. .microsoft.com / en-us / azure / app-service /. Кроме того, что касается информации о пользователе, вы можете отправить запрос на /.auth/me., чтобы получить - person Jim Xu; 11.02.2020
comment
@VitaliyGoncharuk Есть ли у вас другие проблемы? - person Jim Xu; 14.02.2020
comment
@VitaliyGoncharuk Поскольку других проблем у вас нет, не могли бы вы принять ответ? Это может помочь большему количеству людей. - person Jim Xu; 04.03.2020