使用 MSAL 对 Azure 静态 Web 应用中的函数进行授权
Authorisation using MSAL for a function in Azure Static Web App
我正在尝试使用 Azure AD 和 MSAL 对使用 Azure 静态 Web 应用程序创建和公开的 Azure 函数的用户进行身份验证和授权。如果我将应用配置为使用较旧的 AAD v1 流而不是 MSAL,则用户可以成功访问 API。 setup/use-case:
- 使用基本 HTML 和 JS 作为 Azure 静态 Web 应用程序部署和托管的单页应用程序 (SPA)(这是一个演示 '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>"
}
```
用户通过身份验证并返回身份令牌。
静态 Web 应用公开了一个示例函数 GetMessage,其中 returns 一些虚拟文本
如果函数的路由不受保护,SPA 可以成功调用该函数并将文本返回到 browser/SPA
如果函数的路由通过 routes.json 对函数的请求(正确)受到保护 returns 401,除非用户已通过身份验证和授权。
{
"routes": [
{
"route": "/api/*",
"allowedRoles": ["Authenticated"]
}
]
}
为了通过 MSAL 对用户进行身份验证,我正在尝试检索一个访问令牌,我将其放入函数调用的 Bearer header 中:
```
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 中检索并验证,但函数始终 returns 403 - 禁止。如果更改范围或用户角色似乎没有什么区别,尽管我可能缺少一个神奇的组合。
如果我调用的函数是 Micrsoft Graph - 即 https://graph.microsoft.com/v1.0/me - 它只会在我们自己的静态 Web 应用程序函数上失败,那么此过程将完美运行。我看不到一种访问 Azure 服务器端日志的方法来理解它可能失败的原因。
使用 AAD v1 流程,即调用 http://APP_URL/.auth/login/aad 效果很好 - 但它不使用访问令牌。它使用一个名为 StaticWebAppsAuthCookie 的 Cookie(对 APP_URL/.auth/login/aad 的一次调用就足以对用户进行身份验证和授权)。可以找到一个例子 here
我知道 MSAL 是 Azure AD 正在转向的流程,那么有没有办法通过 MSAL 流程授权用户?特别是使用 Azure AD、静态 Web 应用程序和在静态 Web 应用程序中公开的函数(不是作为独立的 Azure Functions 应用程序)。
我相信在调用静态 Web 应用程序中包含的 Azure 函数 API 时,该服务会将自己的身份验证令牌插入到 header 中。如果您依赖授权持有者 header 将您的令牌从应用程序传递到 api,它可能会被覆盖。
就我而言,我正在发送令牌:
{
"typ": "JWT",
"alg": "RS256",
"kid": "{key value}"
}
{
"iss": "https://{domain}.b2clogin.com/{tenant ID}/v2.0/",
"aud": "{client ID}",
...
}
但是我的 Azure Functions API 正在接收令牌:
{
"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
我正在尝试使用 Azure AD 和 MSAL 对使用 Azure 静态 Web 应用程序创建和公开的 Azure 函数的用户进行身份验证和授权。如果我将应用配置为使用较旧的 AAD v1 流而不是 MSAL,则用户可以成功访问 API。 setup/use-case:
- 使用基本 HTML 和 JS 作为 Azure 静态 Web 应用程序部署和托管的单页应用程序 (SPA)(这是一个演示 '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>"
}
```
用户通过身份验证并返回身份令牌。
静态 Web 应用公开了一个示例函数 GetMessage,其中 returns 一些虚拟文本
如果函数的路由不受保护,SPA 可以成功调用该函数并将文本返回到 browser/SPA
如果函数的路由通过 routes.json 对函数的请求(正确)受到保护 returns 401,除非用户已通过身份验证和授权。
{ "routes": [ { "route": "/api/*", "allowedRoles": ["Authenticated"] } ] }
为了通过 MSAL 对用户进行身份验证,我正在尝试检索一个访问令牌,我将其放入函数调用的 Bearer header 中:
```
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 中检索并验证,但函数始终 returns 403 - 禁止。如果更改范围或用户角色似乎没有什么区别,尽管我可能缺少一个神奇的组合。
如果我调用的函数是 Micrsoft Graph - 即 https://graph.microsoft.com/v1.0/me - 它只会在我们自己的静态 Web 应用程序函数上失败,那么此过程将完美运行。我看不到一种访问 Azure 服务器端日志的方法来理解它可能失败的原因。
使用 AAD v1 流程,即调用 http://APP_URL/.auth/login/aad 效果很好 - 但它不使用访问令牌。它使用一个名为 StaticWebAppsAuthCookie 的 Cookie(对 APP_URL/.auth/login/aad 的一次调用就足以对用户进行身份验证和授权)。可以找到一个例子 here
我知道 MSAL 是 Azure AD 正在转向的流程,那么有没有办法通过 MSAL 流程授权用户?特别是使用 Azure AD、静态 Web 应用程序和在静态 Web 应用程序中公开的函数(不是作为独立的 Azure Functions 应用程序)。
我相信在调用静态 Web 应用程序中包含的 Azure 函数 API 时,该服务会将自己的身份验证令牌插入到 header 中。如果您依赖授权持有者 header 将您的令牌从应用程序传递到 api,它可能会被覆盖。
就我而言,我正在发送令牌:
{
"typ": "JWT",
"alg": "RS256",
"kid": "{key value}"
}
{
"iss": "https://{domain}.b2clogin.com/{tenant ID}/v2.0/",
"aud": "{client ID}",
...
}
但是我的 Azure Functions API 正在接收令牌:
{
"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