Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js API won';t使用MSAL通过SPA传递的令牌对AAD进行身份验证_Node.js_Azure_Authentication_Msal - Fatal编程技术网

Node.js API won';t使用MSAL通过SPA传递的令牌对AAD进行身份验证

Node.js API won';t使用MSAL通过SPA传递的令牌对AAD进行身份验证,node.js,azure,authentication,msal,Node.js,Azure,Authentication,Msal,我正在尝试修改引用的B2C代码示例,并与我们的组织AAD对抗 我有一个SPA应用程序,它通过MSAL与AAD成功进行身份验证并接收令牌。SPA应用程序可以使用令牌从MS Graph API提取数据——因此我确信令牌是有效的 SPA当前正在本地运行@localhost:9000 我还有第二个应用程序,它是运行@localhost:3000的nodejsapi。SPA应用程序调用API,传递与GraphAPI相同的令牌。API应用程序应该使用该令牌对用户进行身份验证并提供对API的访问;然而,我只得

我正在尝试修改引用的B2C代码示例,并与我们的组织AAD对抗

我有一个SPA应用程序,它通过MSAL与AAD成功进行身份验证并接收令牌。SPA应用程序可以使用令牌从MS Graph API提取数据——因此我确信令牌是有效的

SPA当前正在本地运行@localhost:9000

我还有第二个应用程序,它是运行@localhost:3000的nodejsapi。SPA应用程序调用API,传递与GraphAPI相同的令牌。API应用程序应该使用该令牌对用户进行身份验证并提供对API的访问;然而,我只得到过未经授权的401退休金

(我使用Aurelia作为客户端代码。HTTP请求是使用Aurelia的HTTP客户端发出的)

以下是用于调用API的SPA代码:

//Not entirely sure what to use as the scope here!!  API is registered to allow user.read Graph API scope.
this.config.msClient.acquireTokenSilent(["user.read"]).then(token => {
   console.log("Token acquired silently.");
   this.makeAPICall(token);
}, error => { ... }
);

makeAPICall(token) {
   this.http.configure(config => {
     config
       .withBaseUrl('http://localhost:3000/')
       .withDefaults({
           headers: {
               'Authorization': 'Bearer ' + token
           }
      }

      this.http.fetch("user/0")
       .then(response => {
          debugger;  //response is 401 Unauthenticated at this point
       }, error => { ... });

}
我已在apps.dev.microsoft.com为我的API注册了一个应用程序。下面是我的服务器端(API)节点代码:

const express = require("express")
const port = 3000
const passport = require("passport")
var BearerStrategy = require("passport-azure-ad").BearerStrategy;

var userList = [
    {id: 1, first: "Mickey", last: "Mouse", age: 95},
    {id: 2, first: "Donald", last: "Duck", age: 85},
    {id: 3, first: "Pluto", last: "leDog", age: 70}
]

var options = {
    identityMetadata: "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration",
    clientID: "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx",  //My registered App Id
    passReqToCallback: false,
    validateIssuer: true,
    issuer: "xxxxxxx"  //Our tenant name
};

var strategy = new BearerStrategy(options, (token, done) => {
    console.log(token);
    done(null,{}, {scope: '*'});
})


const app = express()
app.use(passport.initialize())
passport.use(strategy);

//Allow CORS
app.use((req, res, next) => {
    res.header("Access-Control-Allow-Origin","*");
    res.header("Access-Control-Allow-Headers","Authorization, Origin, X-Requested-With, Content-Type,Accept");
    next();
})

app.get("/",(request, response) => {  //Unauthenticated -- always works
    response.send("Hello World!")
})

app.get("/user/:id",passport.authenticate('oauth-bearer',{session: false }),
  (request, response) => {
    //Never seem to get here (when debugging) as authenticate always fails
    let id = request.params["id"];
    let user = userList[id];
    if(user) response.json(user);
    else response.send("No user found")
})

app.listen(port, () => {
    console.log("Listening on port " + port)
})

我肯定我只是误解了这一切是如何运作的,但我希望能得到一些指导,告诉我需要做些什么才能让这一切正常运作。

代币就像银行支票:它们只能由为其编写代币的人缓存。为MS Graph颁发的令牌将作为Microsoft Graph的访问对象,并且只能被Microsoft Graph接受。任何其他接收到该令牌的API X都应该拒绝它。打算调用X的客户端应该为X请求一个令牌,不管它是否已经为另一个服务(如Microsoft graph)拥有令牌。这里有一个使用ADAL JS实现的流程示例:
目前Azure AD v2(由MSAL使用)无法为自定义API颁发访问令牌:该功能正在开发中,但我们没有预计何时可用于生产。在此之前,v2不支持此拓扑(因此MSAL JS)。对不起

一年后,现在可以使用MSAL保护您的自定义API。在应用程序门户()中,您可以创建应用程序,然后两次“添加平台”——一次用于web应用程序SPA,另一次用于web api。在web api中,创建一个“范围”,例如api://e892d79e-03e7-4e5e-.../access_as_user,然后将此作用域传递到acquireTokenSilent调用中(而不是上面示例中的“user.read”)

因此,如果我理解正确,MSAL只为Graph API提供访问令牌?从今天起,就是这样。v2端点为Microsoft Graph颁发访问令牌,为应用程序登录颁发id_令牌。非常感谢您的解释。这帮了大忙。还有一个问题,你能帮我理解发生了什么吗。此链接似乎表明他们正在使用AD v2保护自定义节点API。(就算他们没有使用MSAL)我理解你说这是不可能的。我遗漏了什么?如果没有这里讨论的访问令牌功能,该示例实际上无法工作-谢谢您的帮助!我联系了该示例的作者,我们将相应地调整语言(或拉,直到我们拥有服务端功能)。