了解Node.js应用程序和Oracle Identity Cloud Service之间的验证

您已准备好了解Node.js Web 应用程序与Oracle Identity Cloud Service之间的验证。其中包括了解以下内容:

  • Oracle Identity Cloud Service为Node.js SDK 支持的三路验证流

  • 将 SDK 与Node.js应用程序一起使用的用例可向Oracle Identity Cloud Service进行验证

  • Node.js SDK 的方法和功能

了解有关三路验证流的信息

Oracle Identity Cloud Service支持Node.js SDK 的三路验证流。在此流中,用户直接与Oracle Identity Cloud Service交互。用户登录后,Oracle Identity Cloud Service将发出一个用户访问标记的 SDK 交换的授权代码。Node.js Web 应用程序使用该访问标记向用户授予对应用程序中受保护资源的访问权限。三路流使用授权代码授权类型。

为了提高安全性,Oracle建议您使用三路流将Node.js Web 应用程序与Oracle Identity Cloud Service集成以进行验证。通过使用授权代码授权类型,您还可以访问由Oracle Identity Cloud Service保护的其他应用程序,而无需重新验证。

了解将 SDK 与Node.js应用程序配合使用的主要用例

Node.js Web 应用程序实施了两种用例:一个用于验证用户,另一个用于访问登录用户的详细信息。

以下数据流图表说明了 Web 浏览器、Web 应用程序和Oracle Identity Cloud Service之间每种用例的事件、调用和响应流。

用例# 1:验证用户

数据流将以下方式进行:

  1. 用户请求受保护的资源。

  2. 验证模块使用 SDK 生成Oracle Identity Cloud Service的请求授权代码 URL,并将此 URL 作为重定向响应发送到 Web 浏览器。

  3. Web 浏览器将调用 URL。

  4. 此时将显示Oracle Identity Cloud Service登录 页。

  5. 用户提交其Oracle Identity Cloud Service登录身份证明。

  6. 用户登录后,Oracle Identity Cloud Service为该用户创建一个会话并发出授权代码。

  7. Web 应用程序使后端(或服务器到服务器)调用可交换用户访问标记的授权代码。

  8. Oracle Identity Cloud Service发出访问标记。

  9. 会话已建立,用户将重定向到 页。

  10. 此时将显示 Web 应用程序的 页。

用例# 2:获取有关用户的详细信息

数据流将以下方式进行:

  1. 用户请求/myProfile资源。

  2. Web 应用程序使用 SDK 调用Oracle Identity Cloud Service,而 SDK 使用存储在用户会话中的访问标记作为参数。

  3. 用户的详细信息将作为 JSON 对象发送到 Web 应用程序。

  4. The My Profile page renders the JSON object as HTML content.

了解方法和函数

Node.js SDK 是您添加到Node.js modules文件夹中的Node.js护照策略。此 SDK 还基于Node.js承诺。Node.js SDK 需要的所有第三方相关性都在 SDK 的 package.json文件中定义。在Node.js Web 应用程序中至少需要使用此模块集。

"dependencies": {
    "async": "^2.1.2",
    "bunyan": "^1.8.5",
    "cache-manager": "^2.2.0",
    "json-web-token": "^2.1.3",
    "jsonwebtoken": "^7.1.9",
    "jwk-to-pem": "^1.2.6",
    "jws": "^3.1.4",
    "lru": "^3.1.0",
    "passport": "^0.3.2",
    "promise": "^7.1.1",
    "querystring": "^0.2.0",
    "request": "^2.79.0",
    "rsa-pem-to-jwk": "^1.1.3",
    "util": "^0.10.3"
  },

Node.js Web 应用程序是使用Node.js expressexpress-handlebars模块开发的,它以app.get()函数的形式对于每个 URL 实施 URL 路由。

Node.js SDK 需要一个与Oracle Identity Cloud Service连接信息一起加载的 JSON 变量。Node.js Web 应用程序使用ids变量来存储以下信息:

var ids = {
    oracle: {
         "ClientId": '123456789abcdefghij',
         "ClientSecret": 'abcde-12345-zyxvu-98765-qwerty',
         "ClientTenant": 'idcs-abcd1234',
         "IDCSHost": 'https://%tenant%.identity.oraclecloud.com',
         "AudienceServiceUrl" : 'https://idcs-abcd1234.identity.oraclecloud.com',
         "TokenIssuer": 'https://identity.oraclecloud.com/',
         "scope": 'urn:opc:idm:t.user.me openid',
         "logoutSufix": '/oauth2/v1/userlogout',
         "redirectURL": 'http://localhost:3000/callback'
    }
};
 
module.exports = ids;

下面是此 SDK 的每个必需属性的简要说明:

名称 说明
ClientId 在Identity Cloud Service控制台中注册Node.js Web 应用程序后生成的客户机 ID 的值。
ClientSecret 在Identity Cloud Service控制台中注册Node.js Web 应用程序后生成的客户端密钥的值。
ClientTenant Oracle Identity Cloud Service实例的域前缀。此前缀通常与idcs-abcd1234类似。
IDCSHost Oracle Identity Cloud Service实例的域后缀。在运行时,% tenant % 占位符由ClientTenant属性的值替换。
AudienceServiceUrl Oracle Identity Cloud Service实例的全限定域名 URL。
TokenIssuer 对于此属性,Oracle建议保留值https://identity.oraclecloud.com/
scope

范围控制应用程序可代表Oracle Identity Cloud Service用户访问或处理的数据。

如果应用程序使用 SDK 对用户进行验证,则范围是openid。如果应用程序使用 SDK 获取有关用户的详细信息,则范围为urn:opc:idm:t.user.me openid

应用程序使用logoutSufixredirectURL属性。SDK 不需要它们。

Node.js应用程序实施/oauth/oracle URL 路由。当用户决定使用Oracle Identity Cloud Service进行验证时,Web 浏览器会向此 URL 发出请求。此路由使用 SDK 生成Oracle Identity Cloud Service的授权 URL。

//Loading the configurations
var auth = require('./auth.js');
 
//Route for /oauth/oracle
app.get("/auth/oracle", function(req, res){
    //Authentication Manager loaded with the configurations.
    am = new IdcsAuthenticationManager(auth.oracle);
    //Using Authentication Manager to generate the Authorization Code URL, passing the
    //application's callback URL as parameter, along with code value and code parameter.
    am.getAuthorizationCodeUrl(auth.oracle.redirectURL, auth.oracle.scope, "1234", "code")
        .then(function(authZurl){
            //Redirecting the browser to the Oracle Identity Cloud Service Authorization URL.
            res.redirect(authZurl);
        }).catch(function(err){
            res.end(err);
        })
});

此函数将 JSON 参数加载到变量,初始化验证管理器,并使用Node.js SDK 的IdcsAuthenticationManager.getAuthorizationCodeUrl()函数生成授权代码 URL。在生成授权代码 URL 或在浏览器中呈现错误时,此函数使用承诺重定向用户 Web 浏览器。

以下参数用于生成授权代码 URL:

名称 说明
auth.oracle.redirectURL 用户登录后,Oracle Identity Cloud Service会将用户的 Web 浏览器重定向到此 URL。此 URL 必须与您将为Identity Cloud Service控制台中的可信应用程序配置的 URL 匹配。有关为Node.js Web 应用程序指定重定向 URL 的详细信息,请参阅注册Node.js应用程序。
auth.oracle.scope 验证的OAuth或OpenID连接范围。此应用程序仅需要openid验证。
state OAuth协议定义此参数。Node.js Web 应用程序示例使用此代码来检查是否可以与Oracle Identity Cloud Service建立通信。对于此示例,此参数的值为1234
response_type 授权代码授权类型所需的参数。对于此示例,此参数的值为code

用户登录后,Oracle Identity Cloud Service会将用户的 Web 浏览器重定向到开发人员必须实施的回调 URL。Node.js Web 应用程序使用/callback路由来处理此请求。

//Route for /callback
app.get("/callback", function(req,res){
    //Authentication Manager loaded with the configurations.
    var am = new IdcsAuthenticationManager(auth.oracle);
    //Getting the authorization code from the "code" parameter
    var authZcode = req.query.code;
    //Using the Authentication Manager to exchange the Authorization Code to an Access Token.
    am.authorizationCode(authZcode)
        .then(function(result){
            //Getting the Access Token Value.
            res.cookie(config.IDCS_COOKIE_NAME, result.access_token);
            res.redirect('/auth.html');
        }).catch(function(err){
            res.end(err);
        })
});

Node.js应用程序使用授权代码请求访问标记。访问标记以 Cookie 的形式存储,然后发送到 Web 浏览器以供将来使用。

Node.js SDK 的IdcsAuthenticationManager.authorizationCode()函数还使用 Commit (then-catch 语句)将访问标记设置为 cookie,并将浏览器重定向至/auth.html页。

Node.js SDK 基于Node.js护照框架。因此,您必须将访问标记作为标头变量转发到/auth URL 处理程序,并将passport.authenticate()方法与Oracle Identity Cloud Service策略名称一起使用作为参数:

//Uses passport to create a User Session in Node.js.
//Passport sets a user attribute in the request as a json object.
app.get('/auth', passport.authenticate(config.IDCS_STRATEGY_NAME, {}), function(req, res) {
   res.redirect('/home');
});

passport.authenticate()方法创建应用程序会话后,该函数会将用户的 Web 浏览器重定向到/home应用程序中的受保护 URL。除了/home之外,Node.js Web 应用程序还具有三个其他受保护的URLs:/appDetails/userInfo/myProfile

每个受保护的 URL 都需要检查用户的会话是否是以前创建的。以下函数由这些URLs的每个app.get()函数使用。

function ensureAuthenticated(req, res, next) {
   if (req.isAuthenticated()) {
      return next();
   }
   res.redirect('/login')
}

Node.js应用程序处理/myProfile路由,并获取由passport.authenticate()方法在会话中设置的信息,如下所示:

app.get("/myProfile", ensureAuthenticated, function(req,res){
   //User Manager loaded with the configurations
   var um = new IdcsUserManager(auth.oracle);
   //Using the user id in the request attribute to render the user json in the screen.
   um.getUser(req.user.id)
      .then(function(user){
         res.render('myProfile', {
         layout: 'privateLayout',
         title: 'My Profile',
         user: req.user,
         userInfo: JSON.stringify(user, null, 2)
         });
      }).catch(function(err1){
         res.end(err1);
      })
});

初始化UserManager对象后,/myProfile路由处理程序使用 SDK 的IdcsUserManager.getUser()函数获取表示用户概要文件的 JSON 对象。应用程序会将 JSON 对象发送到myProfile.handlebars文件以在 Web 浏览器中呈现。

要从应用程序与Oracle Identity Cloud Service之间的一次登入注销用户,Node.js Web 应用程序实施/logout路由,如下所示:

app.get('/logout', function(req, res){
   req.logout();
   res.clearCookie();
   res.redirect(auth.oracle.IDCSHost + auth.oracle.logoutSufix);
});

此路由使应用程序的会话失效,删除以前设置的任何 Cookie,然后将用户的 Web 浏览器重定向到Oracle Identity Cloud Service的OAuth注销 URL。此 URL 在 JSON 配置对象中设置。