- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
解答:对于寻找此答案的任何人,我可以通过在 MSAL acquireToken 调用范围内指定 Web API 来获取所需的 token ,如下所示:
let token = msal.acquireToken({
scopes: [ 'myFunctionApp.azurewebsites.net/user_impersonation' ]
})
完成此操作后,我将该 token 用作身份验证 header 中的承载 token 。除了调用 MS Graph 端点之外,我还可以使用它。我在一个安静的偏僻地方找到了此信息:
非常感谢@StanleyGong 的帮助,最终找到了答案。
/////
过去几天我一直在寻找如何有效地保护从调用 Azure Function App 的 Azure Web 应用程序提供的 Vue SPA。我为 Web 应用程序和函数应用程序打开了 Easy Auth,并且我正在调用 /.auth/me
端点来获取 id token ,我读过该 token 可以用作不记名 token 。所以我正在做的是调用 /.auth/me
并使用返回的 id_token
创建授权 header ,但我仍然得到 401 Unauthorized
调用函数 app 时。
从/.auth/me 获取 id_token 并将其作为默认 header 添加到所有 Axios 调用的代码(我确实认识到这需要刷新...我将在获得后创建所有逻辑一次调用即可工作):
let authUrl = '/.auth/me';
let response = await axios.get(authUrl);
let token = response.data[0].id_token;
axios.defaults.headers.common['Authorization'] = "Bearer " + token;
我可以看到请求中的授权 header 中使用了 token ,该 header 紧接在上面的部分之后:
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Authorization: Bearer eyJ0eXAiO...
我看到了这篇文章并尝试使用其中的一些信息,包括 Chris Gillum 的博客文章(这很有帮助,但仍然没有让我到达那里):Authentication for Azure Functions
关于如何让它发挥作用有什么建议吗?我觉得我已经很接近了,但我还没有完全做到这一点。如果这不是正确的方法,任何建议也会有所帮助。
总的来说,我在身份方面缺乏经验,所以我一直在使用术语,而文档中的不一致并没有帮助我。
此外,有没有什么方法可以测试这些东西,而无需在每次更改时部署代码?通过以某种方式从商店获取 token 而无需将代码放在网络应用程序服务器上来测试这一点会很棒......我猜这是一厢情愿的想法,但只是想知道。
编辑:我刚刚意识到我读过的所有帖子都表明访问 token 是从 /.auth/me
返回的,但我没有得到。返回的 JSON 看起来像这样,这就是全部:
id_token: "eyJ0eXA...7_A"
provider_name: "aad"
user_claims: [{typ: "aud", val: "2...fa"},…]
user_id: "<<my email address>>"
另一个编辑:我发现我可以使用 MSAL 获取 token ,但它包含的信息与 /.auth/me
中的信息略有不同。使用任一 token 作为不记名 token 仍然会导致 401。我确实注意到,在应用程序的 AAD 身份验证设置中,颁发者 URL 不同。一个是 sts.windows.net,另一个是 login.windows.net。两人身上都贴有租户 ID。不确定这是否会产生影响,但我尝试将它们设置为相同的值,但这没有帮助。
/.auth/me
token (当然已清理):
{
"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 访问 token :
{
"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
}
最佳答案
对于您的方案,您可以在租户中注册 Azure AD native 应用程序作为客户端,以获取 access_token 作为承载 token 来调用您的 Azure 函数。如果您使用服务到服务调用,只需引用my previous post here 。
如果您要登录用户,您还应该使用其他配置在您的租户中注册 Azure AD 应用程序: 向此应用程序添加 user_impersonation 权限,以便用户可以登录您的应用程序并调用您的 Azure 函数(请在此处记下您的 azure 函数应用程序 ID,我们稍后将使用它): 添加此权限并授予它:
完成这些步骤后,您的新应用程序将能够登录用户来调用您的 Azure 函数。
我不确定你的VUE应用程序代码是什么样的,但这是一个VUE adal sample我的演示将基于它。1.下载代码并前往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.前往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>
让我们测试一下结果:由于此项目将在本地运行,您应该转到 Azure 函数 => 平台功能 => 所有设置以启用所有 cors 请求,以便您可以从静态 vue 项目在本地测试您的函数:
我的函数逻辑很简单,如果你用参数调用它,它会回复一个 hello 响应:
运行项目,并通过 url 在私有(private)浏览器窗口中打开它: http://localhost:8080
您将被要求登录,您可以看到它可以成功调用Azure函数:
我认为这就是您正在寻找的答案。
更新:
根据您的代码,您正在使用 Azure AD V2 登录用户,请:
1)按照第二种解决方案重新注册Azure广告应用并完成权限授予过程,以便它可以登录用户并访问您的Azure功能。
2) 在您的 Azure AD 中,找到代表您的 Azure 函数应用程序名称的 Azure AD 应用程序(我的 Azure 函数名称是 :stanfuntest ):将范围复制到此处:
2)在您的VUE代码中,使用此应用程序ID作为客户端ID来登录用户,修改代码以获取您刚刚找到的范围的访问 token :
let token = msal.acquireToken( { scopes: [ 'https://stanfuntest.azurewebsites.net/user_impersonation' ] } )
希望有帮助。
关于azure - 从静态文件 SPA 调用 Azure Function App,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59637635/
今天我在一个 Java 应用程序中看到了几种不同的加载文件的方法。 文件:/ 文件:// 文件:/// 这三个 URL 开头有什么区别?使用它们的首选方式是什么? 非常感谢 斯特凡 最佳答案 file
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我有一个 javascript 文件,并且在该方法中有一个“测试”方法,我喜欢调用 C# 函数。 c# 函数与 javascript 文件不在同一文件中。 它位于 .cs 文件中。那么我该如何管理 j
需要检查我使用的文件/目录的权限 //filePath = path of file/directory access denied by user ( in windows ) File fil
我在一个目录中有很多 java 文件,我想在我的 Intellij 项目中使用它。但是我不想每次开始一个新项目时都将 java 文件复制到我的项目中。 我知道我可以在 Visual Studio 和
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a software
我有 3 个组件的 Twig 文件: 文件 1: {# content-here #} 文件 2: {{ title-here }} {# content-here #}
我得到了 mod_ldap.c 和 mod_authnz_ldap.c 文件。我需要使用 Linux 命令的 mod_ldap.so 和 mod_authnz_ldap.so 文件。 最佳答案 从 c
我想使用PIE在我的项目中使用 IE7。 但是我不明白的是,我只能在网络服务器上使用 .htc 文件吗? 我可以在没有网络服务器的情况下通过浏览器加载的本地页面中使用它吗? 我在 PIE 的文档中看到
我在 CI 管道中考虑这一点,我应该首先构建和测试我的应用程序,结果应该是一个 docker 镜像。 我想知道使用构建环境在构建服务器上构建然后运行测试是否更常见。也许为此使用构建脚本。最后只需将 j
using namespace std; struct WebSites { string siteName; int rank; string getSiteName() {
我是 Linux 新手,目前正在尝试使用 ginkgo USB-CAN 接口(interface) 的 API 编程功能。为了使用 C++ 对 API 进行编程,他们提供了库文件,其中包含三个带有 .
我刚学C语言,在实现一个程序时遇到了问题将 test.txt 文件作为程序的输入。 test.txt 文件的内容是: 1 30 30 40 50 60 2 40 30 50 60 60 3 30 20
如何连接两个tcpdump文件,使一个流量在文件中出现一个接一个?具体来说,我想“乘以”一个 tcpdump 文件,这样所有的 session 将一个接一个地按顺序重复几次。 最佳答案 mergeca
我有一个名为 input.MP4 的文件,它已损坏。它来自闭路电视摄像机。我什么都试过了,ffmpeg , VLC 转换,没有运气。但是,我使用了 mediainfo和 exiftool并提取以下信息
我想做什么? 我想提取 ISO 文件并编辑其中的文件,然后将其重新打包回 ISO 文件。 (正如你已经读过的) 我为什么要这样做? 我想开始修改 PSP ISO,为此我必须使用游戏资源、 Assets
给定一个 gzip 文件 Z,如果我将其解压缩为 Z',有什么办法可以重新压缩它以恢复完全相同的 gzip 文件 Z?在粗略阅读了 DEFLATE 格式后,我猜不会,因为任何给定的文件都可能在 DEF
我必须从数据库向我的邮件 ID 发送一封带有附件的邮件。 EXEC msdb.dbo.sp_send_dbmail @profile_name = 'Adventure Works Admin
我有一个大的 M4B 文件和一个 CUE 文件。我想将其拆分为多个 M4B 文件,或将其拆分为多个 MP3 文件(以前首选)。 我想在命令行中执行此操作(OS X,但如果需要可以使用 Linux),而
快速提问。我有一个没有实现文件的类的项目。 然后在 AppDelegate 我有: #import "AppDelegate.h" #import "SomeClass.h" @interface A
我是一名优秀的程序员,十分优秀!