转载

使用 Single Sign On 服务对 Bluemix Object Storage 服务执行细粒度访问控制

在开发应用程序时,您可能发现需要让用户将文件存储在服务器上。为了解决这个问题,您可能只是简单地将文件存储在数据库中,甚至可能将它们直接存储在文件系统上。不幸的是,这些传统方法存在一些缺陷。如果直接将文件存储在文件系统上,则需要额外的工作来确保稳定性和安全性,并创建备份。将大型文件存储在数据库中会让性能变得糟糕,备份变得耗时,还原变得缓慢。

一些 Object Storage 服务已开发了出来,它们通过提供高度可用、基于云的存储来减轻这些问题,并为您扩展、保护和维护这些存储。

Bluemix 现在支持通过所谓的 Object Storage 服务来免费访问 Softlayer 的 Object Storage 。Object Storage 服务可通过 Bluemix 服务目录获取,由 OpenStack 的 Swift Object Store 提供支持。您可以在 OpenStack 网站上 阅读该 API 的概述。

Bluemix Object Storage 概述

概念

可通过 Swift 管理 3 种类型的资源:

  • 对象 :文件数据和任何关联的元数据。
  • 容器 :对象的逻辑分组,让所有对象都具有不同的名称。
  • 帐户: 容器分组,使用帐户凭据来保护。帐户由服务提供商在配备时创建。

安全性

在通过 Bluemix 创建 Object Storage 服务的实例时,会为您分配一个帐户,您的所有容器和对象都存储在该帐户下。您帐户的凭据可通过 VCAP_SERVICES 提供。

{   "objectstorage": [{    "name": "instance_basic",    "label": "objectstorage",    "plan": "plan_name",    "credentials": {     "auth_uri": "https://host:port/auth/instance_id/binding_id",     "username": "user_name",     "password": "password"    }    }]   } 

在创建任何对象或从服务读取任何对象之前,您必须从服务器获取一个授权令牌。该令牌使用包含上述凭据的基本身份验证机制从 auth_uri 端点获取。然后,获取的令牌可用在处理容器和对象的所有后续请求上。

您还能够在容器上创建访问控制列表 (ACL) 来增加对其他对象存储帐户访问限制和其他访问条件。尽管可使用 ACL 在帐户之间共享数据,但应该认识到这些帐户是特定于项目,而不是特定于最终用户。

此身份验证模式具有两大挑战:

  1. 您如何允许用户访问存储在您服务器上的文件,同时不会向客户端公开您的帐户凭据?
  2. 如果所有文件都存储在同一个帐户下,您如何预防用户 A 访问用户 B 的文件?

每种挑战都可通过以下方式克服:

  1. 使用一个服务器端代理来防止将帐户凭据暴露给客户端
  2. 保护代理并使用 Bluemix Single Sign On (SSO) 来验证用户

本文通过一个应用程序展示如何解决这些限制。

应用程序

该应用程序是一个基于 Web 的简单的镜像管理应用程序。用户通过 LinkedIn 执行身份验证,能够上传新镜像,还能够查看、更新和删除已存储的镜像。

运行应用程序

获取代码

第 1 步. 在 Bluemix 上创建一个节点应用程序

  1. 登录到 Bluemix 。
  2. 单击仪表板中的 Create an Application
  3. 在要求指定创建的应用程序类型时,单击 Web
  4. 选择 SDK for Node.js 选项并单击 Continue 使用 Single Sign On 服务对 Bluemix Object Storage 服务执行细粒度访问控制
  5. 命名您的应用程序。 使用 Single Sign On 服务对 Bluemix Object Storage 服务执行细粒度访问控制

第 2 步. 配备 Object Storage 服务

  1. 单击顶部菜单栏中的 Catalog
  2. 从左侧选择 Data Management 类别。
  3. 选择 Object Storage
  4. 选择第 1 步中创建的 App ,如果您愿意的话,还可以更新 Service name 。单击 Create使用 Single Sign On 服务对 Bluemix Object Storage 服务执行细粒度访问控制

    点击查看大图

    关闭 [x]

    使用 Single Sign On 服务对 Bluemix Object Storage 服务执行细粒度访问控制

  5. 在创建实例后,系统会提示您重新启动您的应用程序。单击 Restage

第 3 步. 测试 Object Storage 服务身份验证

如果已理解 Object Storage 服务如何验证用户,可跳过这一步。 Object Storage 文档页面 上也介绍了这一步。

  1. 要测试验证,需要一个 REST 客户端,比如 cURL 或 Chrome 插件 Postman 。
  2. 从您应用程序的 VCAP_Services 复制 auth_uri、username 和 password。 使用 Single Sign On 服务对 Bluemix Object Storage 服务执行细粒度访问控制

    点击查看大图

    关闭 [x]

    使用 Single Sign On 服务对 Bluemix Object Storage 服务执行细粒度访问控制

  3. 要获取令牌,必须通过基本身份验证向 https://auth_uri/username 执行一次 GET 请求。包含上述凭据的 cURL 命令类似于:

    点击查看代码清单

    关闭 [x]

    curl -i --user da938ab5c18601a38c45b3ad6c97cb8d1e7441da:29b6eb028cfdd3e1fec0cc8fa2066fea4a169cb352819e3dfa11e3f0efde https://swift.ng.bluemix.net/auth/45947227-d694-4e3b-beb4-66bfe895752d/bf587adc-10b8-40d8-aeb5-805f73f13844/da938ab5c18601a38c45b3ad6c97cb8d1e7441da
  4. 服务器响应包含 X-Storage-URLX-Auth-Token 标头(表示您的对象存储所在的 URL)和您必须包含在所有请求上的授权令牌。

    点击查看代码清单

    关闭 [x]

    HTTP/1.1 200 OK   X-Backside-Transport: OK OK   Connection: Keep-Alive   Transfer-Encoding: chunked   Content-Type: application/json:charset=utf-8   Date: Fri, 30 Jan 2015 18:33:12 GMT   Set-Cookie: connect.sid=s%3AnPo52qjvdynxlvCGEAmJfs7d.HuYPqYVmtQqeImm73iUnubk2r9T0S5WIQVOL5edX08U; Path=/; HttpOnly   --> X-Auth-Token: AUTH_tk924cd97c2af7475c8e6cb25d2adaccf8   X-Cf-Requestid: 969d6f00-8b85-471e-5ab5-80c36031f9fb   X-Powered-By: Express   --> X-Storage-Url: https://dal05.objectstorage.softlayer.net/v1/AUTH_0c6bf5d5-b5e4-43aa-93f1-ea7065837fb8   X-Client-IP: 129.42.208.182   X-Global-Transaction-ID: 770597619
  5. 所有后续请求都将在 X-Storage-Url 标头中提供的 URL 上,而且必须包含 X-Auth-Token 标头。例如,要为您的存储创建一个新容器,可以发出以下请求:

    点击查看代码清单

    关闭 [x]

    curl -i -H "X-Auth-Token: AUTH_tk924cd97c2af7475c8e6cb25d2adaccf8" -X PUT https://dal05.objectstorage.softlayer.net/v1/AUTH_0c6bf5d5-b5e4-43aa-93f1-ea7065837fb8/myNewContiner

如果一切运行正常,您会从服务器收到 201 响应代码。您可以在同一个 URL 上使用已设置的 X-Auth-Token 标头执行一次 GET 命令,获取与您的帐户有关联的所有容器:

点击查看代码清单

关闭 [x]

curl -i -H "X-Auth-Token: AUTH_tk924cd97c2af7475c8e6cb25d2adaccf8" https://dal05.objectstorage.softlayer.net/v1/AUTH_0c6bf5d5-b5e4-43aa-93f1-ea7065837fb8/

服务器响应应类似于以下内容,其中包含您创建的一个容器列表:

HTTP/1.1 200 OK  Content-Length: 44  Content-Type: text/plain; charset=utf-8  X-Account-Object-Count: 0  X-Timestamp: 1422642699.36706  X-Account-Meta-Cdn-Id: 21904  X-Account-Bytes-Used: 0  X-Account-Container-Count: 3  X-Account-Meta-Nas-Id: 4359794  Accept-Ranges: bytes  X-Trans-Id: tx0284889f9e2b47dca6c39-0054cbea86  Date: Fri, 30 Jan 2015 20:33:10 GMT    myNewContiner  myNewContiner2  myNewContiner3

第 4 步. 配备 Single Sign On 服务

  1. 单击顶部菜单栏中的 Catalog
  2. 从左侧选择 Security
  3. 选择 Single Sign On
  4. App 更改为 Leave Unbound ,如果需要的话,还可以更改 Service name
  5. 单击 Create使用 Single Sign On 服务对 Bluemix Object Storage 服务执行细粒度访问控制

    点击查看大图

    关闭 [x]

    使用 Single Sign On 服务对 Bluemix Object Storage 服务执行细粒度访问控制

    备注:您将在第 6 步绑定该服务。

第 5 步. 为 LinkedIn 配置 Single Sign On 服务

配备 Single Sign On 服务后,您的信息将发送到服务控制台。也可以从仪表板中的服务部分中打开此控制台。

  1. 第一次打开 SSO 控制台时,您会看到一个欢迎窗口,它要求您为服务提供一个名称。提供一个名称,然后单击 Continue使用 Single Sign On 服务对 Bluemix Object Storage 服务执行细粒度访问控制

    备注:单击 Continue 后,可能需要花一分钟来配备服务,在此期间控制台将会无响应。

  2. 我们希望让用户使用 LinkedIn 执行验证,所以在左侧选择 LinkedIn
  3. Configure your Identity Source 面板中,按照说明在 LinkedIn 上注册您的应用程序。在 LinkedIn 上注册您的应用程序后,确保使用了 Configure your Identity Source 所提供的 OAuth 2.0 Redirect URL使用 Single Sign On 服务对 Bluemix Object Storage 服务执行细粒度访问控制 使用 Single Sign On 服务对 Bluemix Object Storage 服务执行细粒度访问控制
  4. 单击 Agree (阅读 API 使用条款后)和 Add Application
  5. LinkedIn 将为您提供 OAuth 密钥。将 API KeyAPI Secret 复制到 SSO Console 中的 Step 2 下的相应字段,然后单击 Save使用 Single Sign On 服务对 Bluemix Object Storage 服务执行细粒度访问控制

第 6 步. 集成 SSO 服务与您的应用程序

  1. 选择第 1 步中创建的 NodeJS 应用程序,然后单击 Bind a Service使用 Single Sign On 服务对 Bluemix Object Storage 服务执行细粒度访问控制
  2. 从打开的窗口中选择您刚创建的 SSO 服务,单击 Add使用 Single Sign On 服务对 Bluemix Object Storage 服务执行细粒度访问控制
  3. 出现 Restage Application 应用程序时单击 Restage
  4. 从应用程序上下文中打开 SSO 服务控制台。这很重要,因为 Integrate 部分仅在从应用程序的页面打开控制台时可用。 使用 Single Sign On 服务对 Bluemix Object Storage 服务执行细粒度访问控制 使用 Single Sign On 服务对 Bluemix Object Storage 服务执行细粒度访问控制
  5. 单击右上侧的 Integrate 选项卡。
  6. Return-to URL

    是 SSO 服务器在完成身份验证后将响应的 URL。在本地测试应用程序时,可以使用:http://localhost:3000/sso/redirect。托管在 Bluemix 上时,该 URL 必须更新为:https://<your-app-domain>.mybluemix.net/sso/redirect。

    请注意协议上的区别。对于本地托管的应用程序,使用的协议为 http,但对于 Bluemix 托管的应用程序,则应使用安全 HTTP,也就是 https。

    至于现在,使用 http://localhost:3000/sso/redirect URL 并单击 Save

第 7 步. 下载并运行应用程序

  1. 从 JazzHub 下载或克隆应用程序源代码。
  2. 要在本地运行,必须从应用程序复制完整的 VCAP_SERVICES 内容,并将这些内容粘贴到 config.json 文件中。
  3. 打开一个终端并导航到应用程序的目录。
  4. 运行 npm install
  5. 要运行应用程序,可从终端运行 node app.js
  6. 在浏览器中打开 http://localhost:3000。您会被重定向到 LinkedIn 登录页面。使用您的凭据登录。
  7. 单击右上角的 ‘+’ 符号来测试您能否上传镜像。

第 8 步. 将应用程序部署到 Bluemix

测试所有功能都能在本地运行后,您可以将应用程序部署到 Bluemix 上:

  1. Return-to URL 更新为 https://<your-app-domain>.mybluemix.net/sso/redirect。
  2. 从终端运行 cf push <Your App Name> -p . ,以便将应用程序部署到 Bluemix
  3. 转到 https://<your-app-domain>.mybluemix.net 来测试应用程序

应用程序概述

文件

在解压项目时,您会看到以下文件:

  • app.js:Node 服务器的源代码。
  • config.json:必须使用 SSO 和 Object Storage 服务提供的凭据来更新的配置文件。
  • ./node_modules/:解压之后的 node_modules 目录仅包含 passport-idaas-openidconnet 模块,因为 npm 注册表中还没有这个模块。其他所有模块包都在运行 npm install 时获取。
  • package.json:包含对所有 Node 依赖项的引用。
  • README:项目自述文件。
  • ./web/:包含应用程序的静态内容:index.html 和 modal_dialog.css。

交互

客户端部分是一个使用 AngularJS(一种基于 JavaScript 的框架)编写的单页 Web 应用程序。服务器是使用 NodeJS 编写的,它提供了 REST API,使用 SSO 服务处理授权流,代表客户端向 Object Storage 服务发出请求,还提供了 Web 应用程序的静态内容(HTML、CSS 和 JavaScript)。来自客户端的通信通过 Ajax 请求传输到服务器。

服务器

服务器有两个主要的用途:

  1. 验证和代理发送给 Object Storage 服务的请求
  2. 集成 Single Sign On 服务,以便基于用户身份验证来提供安全保护

服务器是使用 NodeJS 编写的。以下库是我们用来完成此任务的主要的库:

  • ExpressJS:提供 REST API 的标准节点库
  • http-proxy:处理发送给 Object Storage 服务的代理请求
  • passport:处理 OAuth 流
  • passport-idaas-openid:一种将验证请求定向到 Bluemix 的 SSO 服务的护照身份验证战略

服务器有 3 个主要的根端点:

  • /web:提供托管在 /web 下的静态内容
  • /swift:代理对 Object Storage 服务的请求
  • /sso:处理对 Single Sign On 的授权请求

下一节将分析代码。

代理代码

首先,我们在 /swift 路由上创建一个 express 路由器:

如果不熟悉 express 路由器,可以在 Express 文档页面 上查阅有关的更多信息。

var proxyRouter = express.Router();  app.use('/swift', proxyRouter);  proxyRouter.use('/:container', validateProxyRequest);

发送给 https://<app-domain>.mybluemix.net/swift 的所有请求都被转发给对象缓存存储。这通过两个步骤来完成:

  1. 身份验证验证令牌的获取已在上面的 “第 3 步. 测试 Object Storage 服务身份验证” 中演示。下面这个中间件演示了这一过程:
    proxyRouter.use(function (req, res, next) {  var swiftStorageCredentials = cache.get('swiftStorageCredentials')  if(!swiftStorageCredentials === undefined){   var parsedUrl = url.parse(swiftConfig.credentials.auth_uri);   var options = {    hostname: parsedUrl.hostname,    path: parsedUrl.path + '/' + swiftConfig.credentials.username,    method: 'GET',    auth: swiftConfig.credentials.username + ':' + swiftConfig.credentials.password   };   var swiftRequest = https.request(options, function(swiftResponse) {    var storageURL = swiftResponse.headers["x-storage-url"];    var storageToken = swiftResponse.headers["x-auth-token"];    swiftStorageCredentials = new SwiftStorageCredentials(storageURL, storageToken)    cache.set('swiftStorageCredentials', swiftStorageCredentials ) ;    next();   });   swiftRequest.end();  } else{   next();  } }); 

    此中间件首先检查 URL 缓存,查看我们是否已在最近 15 分钟内获得了该令牌。如果没有,则会使用基本的 auth 令牌向授权端点发出一个安全请求。您可以在 swiftRequest 响应回调中看到,我们获得了存储 URL 和 auth 令牌,因此我们可以在后续代理请求中使用它们,并将它们存储在缓存中。

  2. 使用缓存中存储的凭据来发出代理请求。

    为此,我们定义了将请求重定向到代理的中间件:

    proxyRouter.use(function (clientRequest, clientResponse, next){  //Obtain Object Storage service endpoint from stored credentials.  //This will be the target of the proxy.  var swiftStorageCredentials = cache.get('swiftStorageCredentials');  var proxyURL = swiftStorageCredentials.storageURL ;  var options = {target : proxyURL};  if(!clientRequest.header('expect')){   proxy.web(clientRequest, clientResponse, options);  } else{   clientResponse.writeContinue();   clientResponse.setHeader("SkipProxyWeb", "true");   clientResponse.end();  } }); 

    这会获取我们存储在缓存中的存储 URL,并使用指定的同一个路径来调用该代理。换句话说,对 http://hostname/swift/mycontainer/myimage.jpg 的请求被转发到 https://storageURL/mycontainer/myimage.jpg。

    在代理自身上,我们必须定义一个函数,以便所有传出的请求都包含 auth 令牌,该令牌是在我们的第一个中间件所发出的身份验证请求中获取的。

    proxy.on('proxyReq', function(proxiedReq, req, res, options) {     var swiftStorageCredentials = cache.get('swiftStorageCredentials');     if(!req.header(‘expect')){         proxiedReq.setHeader(‘X-Auth-Token', swiftStorageCredentials.storageToken);     } else{         res.setHeader("ProxyRequestEventFoundExpect", "true");     } });

    有了此信息后,向 https://<app-domain>.mybluemix.net/swift 发出的所有请求都会被重定向到对象存储服务,使用帐户凭据来授权请求,而不会向客户端把暴露凭据。

使用 Passport.js 集成 SSO

Single Sign On 文档的 配置 Node.js 应用程序 一节详细介绍了如何使用 Passport.js 节点库和 Single Sign On(passport-idaas-openidconnect) 将第三方用户安全集成到应用程序中。在这一节中,我们将介绍应用程序中的相关更改。

要持久保存用户信息,必须向 express 应用程序注册 express-session 和 cookieParser 中间件。

app.use(cookieParser());  app.use(session({ secret: 'SOME SECRET HERE', resave: true, saveUninitialized: true }));  app.use(passport.initialize());  app.use(passport.session());   //Serializes the user into the session  passport.serializeUser(function(user, done) { done(null, user); });  //Deserializes the user into an object and makes it available on req.user  passport.deserializeUser(function(obj, done) { done(null, obj); });

上述代码初始化并注册了 session 和 passport 中间件。 serializeUserdeserializeUser 方法调用描述了如何序列化和去序列化会话中的用户信息。参见 Passport 配置文档 中的 “会话” 部分,了解有关的更多信息。

接下来,我们将设置 Single Sign On 文档中所介绍的 Passport(护照)战略。

//Retrieve SSO credentials from VCAP_SERVICES when running on Bluemix, //or config.json when running locally var services  = isBluemix() ? JSON.parse(process.env.VCAP_SERVICES) : config.VCAP_SERVICES,  ssoConfig = services.SingleSignOn[0]; //Create Passport Strategy with SSO credentials to handle authentication flows passport.use(new OpenIDConnectStrategy({  authorizationURL: ssoConfig.credentials.authorizationEndpointUrl,  tokenURL: ssoConfig.credentials.tokenEndpointUrl,  clientID: ssoConfig.credentials.clientId,  scope: 'openid',  response_type: 'code',  clientSecret: ssoConfig.credentials.secret,  callbackURL: "/sso/redirect",  skipUserProfile: true,  issuer: ssoConfig.credentials.issuerIdentifier }, function(accessToken, refreshToken, profile, done) {  process.nextTick(function() {   profile.accessToken = accessToken;   profile.refreshToken = refreshToken;   done(null, profile);  }) })); 

来自 VCAP_SERVICES 的 SSO 凭据用于实例化 OpenIDConnectStrategy 。此战略会告诉护照,我们希望发出何种授权请求和在何处发出这些请求(使用 SSO 服务)。 authorizationURLtokenURLclientIdclientSecretissuer 身份都由 SSO 服务提供。我们还在这里指定,我们希望在完成登录操作后调用我们的 /sso/redirect 端点。

为了简化登录请求,我们创建了一个 authRouter ,并将它与发送给 /sso/* 的所有请求相关联。

var authRouter = express.Router();  app.use('/sso', authRouter);

然后,为了处理登录请求,我们创建了一个 /sso/login 端点,并让护照来处理该请求。

authRouter.get('/login', passport.authenticate('openidconnect', {}));

护照和 SSO 服务将为我们处理实际的身份验证流。完成身份验证后,用户会被重定向到之前提到的 /sso/redirect。

authRouter.get('/redirect',function(req,res,next) {   passport.authenticate('openidconnect',{    successRedirect: "/web",    failureRedirect: '/sso/failure'   })(req,res,next);  });

您可以看到,这个端点表明成功的身份验证将重定向个到 /web/ 端点,用户将能够在其中查看实际的网站。失败的身份验证将被重定向到 '/sso/failure' ,这会通知用户登录失败:

authRouter.get('/failure', function(req, res) { res.send('login failed'); });

要保护端点,必须检查用户是否已在所有请求上进行了验证。为此,我们可以检查 req.isAuthenicated() 是否为 true,也可以检查 req.user 是否允许用户访问请求的容器。

为了保护根 (/) 端点,我们创建了 ensureAuthenticated 函数:

function ensureAuthenticated(req, res, next) {   //If user isn't authenticated, redirect to login   if (!req.isAuthenticated()) {    res.redirect('/sso/login');   } else {    //If authenticated, continue to next middleware     return next();   }  }

它的使用方式是:

app.get('/', ensureAuthenticated, function(req,res,next){   res.redirect('/web');  });

借助代理请求,我们执行一个额外的步骤,确保经过验证的用户仅对允许他们访问的容器发出代理请求。在我们的案例中,我们要求用户 ID(他们的电子邮件地址)与容器的名称匹配。为此,我们创建下面这个函数:

点击查看代码清单

关闭 [x]

function validateProxyRequest(req, res, next) {   if (!req.user) {    console.log("Invalid proxy request. User is not logged in.");    res.send(401).send("Not logged in.");   } else if (req.user.id != req.params.container) {    res.send(401).send("Container and user id don't match. Container: %s, User id: %s”, req.params.container, req.user.id);   } else {    return next();   }  }

在代理端点之前向 proxyRouter 注册,将它注册为中间件。

proxyRouter.use('/:container', validateProxyRequest);

对于 validateProxyRequest 函数,有两点需要注意:

  • 我们检查了 req.user ,而不是 req.isAuthenticated() 。因此我们可确保 req.user.id:container 端点参数 ( req.params.container ) 相匹配。这可以确保用户无法访问其他用户的文件。
  • 我们没有像 ensureAuthenticated 中那样执行重定向,我们发送了 401。这是因为代理请求将使用 Ajax 代理来处理,因此服务器端重定向无法正确处理。如果我们发送 401,我们可登录到存在错误的客户端,通知用户他们需要登录(为了简便起见,我们在应用程序中执行了客户端重定向)。

客户端代码

客户端部分通过流行的 Angular 库 来使用 HTML、CSS 和 JavaScript 编写。Angular 是一个基于 MVC 的框架,用于编写基于 JavaScript 的 Web 应用程序。可以从 Angular 的 在线文档 获取它的概念性概述。出于本文的目的,我们坚持只介绍用于与我们刚演示的服务器通信的控制器的内容。

/web/index.html 中的控制逻辑包含在 HTML 后的脚本标记中。首先,我们定义了一个名为 swiftResourceApp 的模块,它充当着所有 Web 应用程序的逻辑的容器模块。随后,我们定义了 swiftListController ,而且它位于应用程序的大部分逻辑所在的控制器中。

您会注意到,此控制器中定义了多个方法。以下方法用于与服务器通信:

  • getContainer :此方法调用我们在应用程序中定义的一个特殊端点(简言之,就是 /container),该端点将告诉我们此用户有权访问的容器名称。容器名称应与从 Passport 的已验证用户获取的用户 ID 或电子邮件地址相同。 备注: 这不是代理端点。所有其他 Ajax 调用都是对代理发出的。
  • listResources :在 /swift/<container name> 上执行一次 GET ,获取用户的容器中存储的所有文件。如果这是用户第一次登录,服务器会使用一个 404 页面作为响应。此问题的处理方式是,在 /swift/<container name> 上执行一次 PUT ,创建一个具有相同名称的新容器。
  • createResource :在 /swift/<container name>/<resource name> 上使用在请求中作为数据上传的文件的内容执行一次 PUT
  • onSaveUpdate :类似于 createResource ,但更新了现有资源。

您会注意到,在对我们的服务器的每次调用中,如果服务器使用 401 作为响应,我们会通过将 window.location.href 更改为登录端点来执行一次客户端重定向:

error(function(response, status){     if (status == 401) {         window.location.href = window.location.origin+"/sso/login";     } else {         console.error("Error updating resource. Error code: %s, Error message: %s", status, response);     } });

结束语

IBM Bluemix 是一个创建和部署以云为中心的应用程序的重要平台。在本文中,我们演示了开发人员如何使用与 Node.js 和 Angular.js 相关的前沿技术(都受 OAUTH 保护),安全地将资源存储在 IBM SoftLayer 的 Object Storage 服务中。通过设计一种多层架构,我们可确保开发人员能够使用 IBM Bluemix 平台开发一个高度可扩展、可靠、高性能的解决方案。Bluemix 上的服务目录非常庞大,而且提供了许多不同的功能,它们对开发人员很有吸引力,可以缩短新一代应用程序的上市准备时间。

BLUEMIX SERVICES USED IN THIS TUTORIAL:

  • Single Sign On 服务 可以帮助您保护为云开发的 Web 和移动应用程序,并轻松地构建和增强应用程序以包含基于策略的用户访问安全。
  • Object Storage 服务 拥有对配置独立对象存储的内置支持,而且它为每个对象存储创建了单独的子帐户。
正文到此结束
Loading...