本文将简要介绍 IBM SmartCloud Entry 自带的两种 Web Service 安全机制,以及如何在各种客户端编程通过这些安全机制的认证。
环境准备
一个运行的 IBM SmartCloud Entry 系统 Eclipse 3.6 或者更高版本
开始之前
在正式开始之前,先对本文将用到的一些名词做基本的解释。
Restlet:诞生于 2005 年,是一个针对 Java 语言开发人员的开源项目。Restlet 旨在以一种简单的方式,向开发人员提供各个应用场景下实现 REST Web Service 的方法。目前 Restlet 的最新
稳定版本是 2.1.1,本文的所有内容都是基于 Restlet 2.1.1 来进行说明。 Dojo:Dojo 是一个强大的前端框架,它提供了方便的 Ajax 方法、
丰富的小部件、数据结构、辅助函数、效果和布局帮助。Dojo 是一个较为活跃的开源项目,截止到目前,Dojo 的最新版本是 1.8.1。本文中的所有实现将基于 Dojo 1.8.1。 jQuery:jQuery 是一个优秀的轻量级 JavaScript 框架。可以方便的提供 Ajax 交互,各种动画效果。jQuery 的应用文档很详细,同时还有许多成熟的插件可供使用。本文中所有实现将基于 jQuery1.9.1。 HttpClient:Apache Jakarta Common 下的子项目,可以用来提供高效的、最
新的、功能丰富的、支持 HTTP 协议的客户端编程工具包。 cURL:由瑞士 curl 组织开发,是一个综合的网络传输工具。更多内容,请参考 cURL 网站。
基于 Restlet 的 WebService 安全机制
Restlet 框架自带了一套完整的用户认证机制,IBM SmartCloud Entry 的用户认证机制正是基于 Restlet 实现。Restlet 框架的用户认证机制如图 1 所示。
图 1. Restlet 的认证机制
从图中可以看出,Client 若没有通过认证,是没有办法接触到 REST 资源。
IBM SmartCloud Entry 在版本 3.1 以前,只支持 HTTP Basic Authentication 的认证方式。从版本 3.1 开始,在原来的基础上,新增了 Token Authentication 的认证方式,用户可以根据自己的需要选用相应的认证方式。若客户端同时带有两种认证,IBM SmartCloud Entry 将只按照 HTTP Basic Authentication 进行认证。接下来,将简要介绍如何在各个客户端编程以通过这两种认证。
HTTP Basic Authentication
HTTP Basic Authentication 可以说是最简单的 HTTP 认证方式。它仅需要静态的、标准 HTTP header 就能完成认证。同时,它不需要登录页面,可以将用户名和密码直接通过 URL 传入,例如:http://username:password@www.example.com/path。但是,另一方面,Basic Authentication 几乎没有任何机密性,用户名和密码仅仅是经过 BASE64 编码就从客户端传递到服务器端。
客户端想要通过 HTTP Basic Authentication,首先需要确认用户名和密码是正确的,然后将用户名和密码通过一个“:”连接,进行 BASE64 编码,编码的结果与“Basic ”结合置于一个叫“Authorization”的 HTTP header 中,即可通过认证。
IBM SmartCloud Entry 提供一个 REST API,POST “//hostname:port/unsecured/cloud/api/auth”,可以用于验证所提供的用户名和密码是否合法。下面的例子将用到这个 REST API 以验证用户名和密码。
如何使得 Dojo 客户端通过认证
清单 1 展示了如何在 Dojo 客户端编程以 HTTP Basic Authentication 方式通过 IBM SmartCloud Entry 的认证。在确认了用户名和密码之后,获取已经部署的 workload 来检验已经通过认证。
清单 1. Dojo 客户端通过 HTTP Basic Authentication
dojo.require("dojox.encoding.digests._base");dojo.ready(function() { var base64Encode, username = "xhh", password = "password"; dojo.xhrPost({// 通过 post 方式验证用户名和密码是否有效 // 这里的绝对地址是 hostname:port/unsecured/cloud/api/auth url: "../../unsecured/cloud/api/auth", content: { username: encodeURIComponent(username), password: encodeURIComponent(password) }, sync: true, // 这里为了直观表现,将该 Ajax 请求设置成同步 // 实际中可以设置成异步方式 handle: function(response, ioArgs) { if (ioArgs.xhr.status == 200) { //进行 Base64 编码 base64Encode = dojox.encoding.digests.wordToBase64( dojox.encoding.digests.stringToWord( encodeURI(username)+":"+encodeURI(password))); } else { console.error("Wrong username or password!"); } } }); if (base64Encode) { // 验证是否能通过认证 dojo.xhrGet({ // 这里的绝对地址是 hostname:port/cloud/api/workloads url: "../api/workloads", handleAs: "json", headers: { "Accept": "application/json, text/plain, text/html", "Authorization": "Basic " + base64Encode, "Content-Type": "text/plain; charset=UTF-8" }, handle: function(response, ioArgs) { if (ioArgs.xhr.status == 200) { console.log(response); } else { console.error(response); } } }); }});
客户端只要记住 base64Encode 的值,在每个 HTTP 请求时传入 Authorization 即可完成通过认证。