Вызов Azure Function App от stati c -файл SPA - PullRequest
1 голос
/ 08 января 2020

ОТВЕТ: Для всех, кто ищет этот ответ, я смог получить нужный токен, указав веб-API в областях вызова MSAL acquToken, например:

let token = msal.acquireToken({ 
  scopes: [ 'myFunctionApp.azurewebsites.net/user_impersonation' ] 
})

После выполнения этого Я использовал токен в качестве токена Bearer в заголовке Authentication. Я могу использовать это в дополнение к вызову конечных точек MS Graph. Я нашел эту информацию в тихом отдаленном месте:

https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-acquire-cache-tokens#request -specifi c -scopes-for-web-api

Большое спасибо @StanleyGong за его помощь, которая в конечном итоге привела к ответу.

/////

Последние несколько дней я искал, как эффективно обезопасить Vue SPA подается из веб-приложения Azure, вызывающего функциональное приложение Azure. У меня включена функция Easy Auth как для веб-приложения, так и для приложения-функции, и я вызываю конечную точку /.auth/me, чтобы получить токен идентификатора, который, как я прочитал, может использоваться в качестве токена-носителя. Поэтому я вызываю /.auth/me и использую возвращенный id_token для создания заголовка авторизации, но я все равно получаю 401 Unauthorized при вызове приложения функции.

Код, получающий id_token из / .auth / me и добавление его в качестве заголовка по умолчанию для всех вызовов Ax ios (я понимаю, что это нужно будет обновить ... Я собираюсь создать все эти логи c после того, как получу один вызов работает):

let authUrl = '/.auth/me';
let response = await axios.get(authUrl);
let token = response.data[0].id_token;
axios.defaults.headers.common['Authorization'] = "Bearer " + token;

Я вижу, что токен используется в заголовке авторизации в запросе, который следует сразу за разделом выше:

Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Authorization: Bearer eyJ0eXAiO...

Я видел этот пост и пытался используйте часть этой информации, в том числе сообщение в блоге Криса Гиллума (что было полезно, но все равно не помогло мне): Аутентификация для Azure Функции

Любые предложения о том, как чтобы это заработало? Я чувствую, что я рядом, но я не совсем там. Если это не правильный путь к go по этому поводу, любой совет также будет полезен.

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

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

РЕДАКТИРОВАТЬ: я только что понял, что все посты, которые я прочитал, предполагают, что токен доступа возвращается с /.auth/me, но я его не получаю. Возвращенный JSON выглядит следующим образом, и это все:

id_token: "eyJ0eXA...7_A"
provider_name: "aad"
user_claims: [{typ: "aud", val: "2...fa"},…]
user_id: "<<my email address>>"

ДРУГОЕ РЕДАКТИРОВАНИЕ: я обнаружил, что могу получить токен с помощью MSAL, но информация, содержащаяся в нем, немного отличается от информации из /.auth/me. Использование любого токена в качестве маркера носителя по-прежнему приводит к 401. Я заметил, что в настройках аутентификации AAD для приложений URL-адрес издателя был другим. Один был sts. windows. net, а другой - логин. windows. net. У обоих был идентификатор арендатора после них. Не уверен, что это изменило ситуацию, но я попытался установить для них одно и то же значение, и это не помогло.

/.auth/me токен (очищенный, конечно):

{
  "aud": "2fe...fa", (AAD app id)
  "iss": "https://sts.windows.net/<< AD tenant id >>/",
  "iat": 15785xxx,
  "nbf": 15785xxx,
  "exp": 15785xxx,
  "aio": "AVQAq/...UQ=",
  "amr": [
    "pwd",
    "mfa"
  ],
  "family_name": "<< my last name >>",
  "given_name": "<< my first name >>",
  "ipaddr": "<< my ip >>",
  "name": "<< my full name >>",
  "nonce": "e32a...48",
  "oid": "a0...0e",
  "sub": "LNu...8l8",
  "tid": "f14...2ca",
  "unique_name": "<< my email >>",
  "upn": "<< my email >>",
  "uti": "i9O...TAQ",
  "ver": "1.0"
}

Маркер доступа MSAL:

{
  "aud": "000...000", (mostly 0s...not sure what this id is)
  "iss": "https://sts.windows.net/<< AD tenant id >>",
  "iat": 15785xxx,
  "nbf": 15785xxx,
  "exp": 15785xxx,
  "acct": 0,
  "acr": "1",
  "aio": "AVQAq/8O...ZZ12s=", (different than above)
  "amr": [
    "pwd",
    "mfa"
  ],
  "app_displayname": "<< app name in AAD app registration >>",
  "appid": "<< app GUID from AAD >>",
  "appidacr": "0",
  "family_name": "<< my last name >>",
  "given_name": "<< my first name >>",
  "ipaddr": "<< my ip >>",
  "name": "<< my full name >>",
  "oid": "a0...0e", (same as above)
  "platf": "3",
  "puid": "10...1B",
  "scp": "User.Read profile openid email",
  "signin_state": [
    "kmsi"
  ],
  "sub": "WuX...L3A",
  "tid": "f14...2ca", (tenant id, same as above)
  "unique_name": "<< my email >>",
  "upn": "<< my email >>",
  "uti": "UD...AA",
  "ver": "1.0",
  "xms_st": {
    "sub": "LNu...8l8"
  },
  "xms_tcdt": 14...37
}

1 Ответ

2 голосов
/ 09 января 2020

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

Если вы будете входить в систему пользователей, вам необходимо зарегистрировать приложение Azure AD и в своем арендаторе с дополнительными конфигами: enter image description here Добавить разрешение user_impersonation для этого приложения, чтобы пользователи могли войти в систему. ваше приложение и вызовите вашу Azure функцию (пожалуйста, запишите здесь ваш azure идентификатор приложения функции, и мы будем использовать его позже): enter image description here Добавьте это разрешение и предоставьте его: enter image description here enter image description here

После выполнения этих шагов ваше новое приложение сможет войти в систему пользователей для вызова вашей функции Azure.

Я не являюсь конечно, каков ваш код приложения VUE, но это VUE образец adal , и моя демонстрация будет основана на нем. 1. Загрузите код и go в src/main.js замените его содержимое кодом ниже:

import Vue from 'vue'
import axios from 'axios'
import { default as Adal, AxiosAuthHttp } from 'vue-adal'
import App from './App.vue'
import router from './router'

Vue.config.productionTip = false
const functionBase = `<your Azure function URL>`
const functionResource = '<your Azure function application ID>'

Vue.use(Adal, {
  config: {
    tenant: '<your tenant ID>',
    clientId: '<your new resistered app ID>',
    redirectUri: '<redirect url you mapped in your new resgistered app ID, in this case it should be : http://localhost:8080>',
    cacheLocation: 'localStorage'
  },
  requireAuthOnInitialize: true,
  router: router
})

Vue.use({
  install (vue, opts = {}) {
    // Configures an axios http client with a interceptor to auto-acquire tokens
    vue.prototype.$functionApi = AxiosAuthHttp.createNewClient({
      // Required Params
      axios: axios,
      resourceId: functionResource, // Resource id to get a token against

      // Optional Params
      router: router, // Enables a router hook to auto-acquire a token for the specific resource

      baseUrl: functionBase, // Base url to configure the client with

      onTokenSuccess (http, context, token) { // Token success hook
        // When an attempt to retrieve a token is successful, this will get called.
        // This enables modification of the client after a successful call.
        if (context.user) {
          // Setup the client to talk with the Microsoft Graph API
          http.defaults.baseURL = `${functionBase}`
          console.log(token)
        }
      },

      onTokenFailure (error) { // Token failure hook
        // When an attempt to retrieve a token is not successful, this will get called.
        console.log(error)
      }
    })
  }
})

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

2. Go до src/views/Home.vue, замените содержимое раздела <script> следующим кодом:

<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'

export default {
  name: 'home',
  components: {
    HelloWorld
  },
  data () {
    return {
      msg: "Signing in..."
    }
  },
  async created () {
    if (this.$adal.isAuthenticated()) {
      this.msg = "Hello, " + this.$adal.user.profile.name 

      let functionInfo = await this.getAzureFunctionInfo()
      this.msg += "  |  function result : " + functionInfo


    } else {
      this.msg = "Please sign in"
    }
  },

  methods: {
    async getAzureFunctionInfo () {
      let res = await this.$functionApi.get('',{
        params: {
          'name': 'test'
        }
      })
      console.log(res)
      return res.data
    }
  }
}
</script>

Давайте проверим результат: Поскольку этот проект будет выполняться локально, вам следует go в вашу Azure функцию => Функции платформы => Все настройки, чтобы включить все запросы cors, чтобы вы могли локально протестировать свою функцию из проекта stati c vue: enter image description here

Моя функция logi c была проста, если вы вызываете ее с параметром, она ответит на привет: enter image description here

Запустите проект и откройте его в приватном окне браузера по URL: http://localhost:8080 Вам будет предложено войти в систему, и вы увидите, что он может успешно вызвать функцию Azure: enter image description here

Я думаю, что это ответ, который вы ищете.

Обновление :

Исходя из вашего кода, вы используете Azure AD V2 для входа пользователей, Pls:

1) следуйте за вторым решение повторно зарегистрировать Azure рекламное приложение и завершить sh процесс предоставления разрешений, чтобы он мог войти в систему пользователей и получить доступ к вашей функции Azure.

2) В вашем Azure AD найдите Azure AD приложение, которое от имени вашего Azure приложения функции по имени (мое Azure имя функции: stanfuntest): скопируйте область действия здесь: enter image description here

2) В своем коде VUE используйте этот идентификатор приложения в качестве идентификатора клиента для входа в систему, измените код, чтобы получить токен доступа с только что найденной областью:

let token = msal.acquireToken( { scopes: [ 'https://stanfuntest.azurewebsites.net/user_impersonation' ] } )

Надеюсь, это поможет.

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