Авторизация с помощью MSAL для функции в статическом веб-приложении Azure

Я пытаюсь аутентифицировать и авторизовать пользователя для функции Azure, созданной и предоставленной с помощью статического веб-приложения Azure, с использованием Azure AD и MSAL. Пользователь сможет успешно получить доступ к API, если я настрою приложение для использования более старого потока AAD v1, но не с MSAL. Вариант установки / использования:

  • одностраничное приложение (SPA), развернутое и размещенное как статическое веб-приложение Azure с использованием базового HTML и JS (это демонстрационное приложение Hello World)
  • В приложение встроена аутентификация с использованием MSAL. В частности, msal-browser.js версии 2.6.1. Идентификационный токен извлекается с помощью:
msal.PublicClientApplication(msalConfig).loginPopup(loginRequest)

где msalConfig содержит:

```
auth: {
        clientId: "<CLIENTID>",
        authority: "https://login.microsoftonline.com/<TENANT_ID>"
    }
```
  • Пользователь аутентифицирован и возвращается токен идентификации.

  • Статическое веб-приложение предоставляет пример функции GetMessage, которая возвращает фиктивный текст.

  • Если путь к функции не защищен, SPA может успешно вызвать функцию, и текст будет возвращен в браузер /SPA.

  • Если путь к функции защищен через routes.json, запрос функции (правильно) возвращает 401, если пользователь не аутентифицирован и не авторизован.

    {
        "routes": [
          {
            "route": "/api/*",
            "allowedRoles": ["Authenticated"]
          }  
        ]
      }
    

Чтобы аутентифицировать пользователя через MSAL, я пытаюсь получить токен доступа, который я помещаю в заголовок Bearer вызова функции:

```
async function getAPI() {
    const currentAcc = myMSALObj.getAccountByHomeId(accountId);
    if (currentAcc) {
        const response = await getTokenPopup(silentRequest, currentAcc).catch(error => {
            console.log(error);
        });
        console.log("Got token " + response.accessToken)
        const accToke = response.accessToken
        const headers = new Headers();
        const bearer = `Bearer ${accToke}`;

         headers.append("Authorization", bearer);

          const options = {
                method: "GET",
                headers: headers
      };


    let { text } = await( await fetch('/api/GetMessage',options)).json();
    document.querySelector('#name').textContent = text;
    }    
}

```

Токен извлекается и проверяется в jwt.ms, но функция всегда возвращает 403 - запрещено. Кажется, нет никакой разницы, если меняются области действия или роли пользователей, хотя, возможно, есть волшебная комбинация, которую мне не хватает.

Этот процесс работает отлично, если функция, которую я вызываю, - это Micrsoft Graph, то есть https://graph.microsoft.com/v1.0/me - она ​​не работает только с нашей собственной функцией статических веб-приложений. Я не вижу способа получить доступ к журналам на стороне сервера Azure, чтобы понять, почему он может давать сбой.

Использование потока AAD v1, т.е. вызов http://APP_URL/.auth/login/aad, работает отлично, но не использует токен доступа. Он использует файл cookie под названием StaticWebAppsAuthCookie (для аутентификации и авторизации пользователя достаточно одного вызова APP_URL/.auth / login / aad). Пример этого можно найти здесь

Я понял, что MSAL - это поток, к которому движется Azure AD, поэтому есть ли способ авторизовать пользователя через поток MSAL? Официально с использованием Azure AD, статического веб-приложения и функции, представленной в статическом веб-приложении (а не как отдельное приложение-функция Azure).

1 ответ

Я полагаю, что при вызове API-интерфейса функций Azure, содержащегося в вашем статическом веб-приложении, служба вставляет в заголовок собственный токен аутентификации. Если вы полагаетесь на заголовок Authorization Bearer для передачи вашего токена из приложения в API, он может быть перезаписан.

В моем случае я отправлял токен:

      {
  "typ": "JWT", 
  "alg": "RS256", 
  "kid": "{key value}"
}
{
  "iss": "https://{domain}.b2clogin.com/{tenant ID}/v2.0/", 
  "aud": "{client ID}",
  ...
}

но мой API функций Azure получал токен:

      {
  "typ": "JWT", 
  "alg": "HS256", 
}
{
  "iss": "https://{ID}.scm.azurewebsites.net", 
  "aud": "https://{ID}.azurewebsites.net/azurefunctions",
  ...
}

Эта проблема отслеживается здесь: https://github.com/Azure/static-web-apps/issues/34.

Другие вопросы по тегам