RESTful Web Service 的安全(token 认证方式)以及性能

可扩展性(scalability)和可用性(availability)

 custom token authentication

使用一个独一无二的标志,来标示每一次的数据请求。

这个标志有两种用法:1.它可以作为URI的 2.它可以加入到HTTP的请求头中。

@Path("/users/token={token}")
public class UsersResource {
@GET
@Produces("application/xml")
public String getXML(@PathParam("token") String token) {
    if (AuthenticationService.authenticate(token)) {
        return UserBO.getAllXML();
    } else {
        throw new WebApplicationException(401);
    }
  }
}

先检验URI中的标志——Token,如果token变量未通过验证,返回401错误,即未授权。

 

HTTP basic authentication

RESTful Web Service 的安全(token 认证方式)以及性能_第1张图片
即在HTTP请求头中加入一个Authorization: Basic QWxhZGRpbjpvcGVulHNIc2FtZQ==域,就相当于一个证书。对于浏览器而言,会把证书放入缓存中,这样就不必每次都要输入用户名和密码。但这样会导致越权访问,此时由于存在缓存,所以Web Service很难区分请求是否授权。

 

而且用户名和密码是用Base64 encoding编码的,这个很容易破解,解决这个问题,我们可以用HTTPS(SSL)协议代替HTTP协议。

如果用浏览器访问但没有加入对应的证书,浏览器会出现一个对话框,要求你输入用户名和密码,当用户输入完后,浏览器会再次发送求情。浏览器对401错误会自动处理。

如果使用其他的客户端,则会收到一个401错误。

 

也可以在刚开始的时候就设置好HTTP请求头,这样就不用每次都输入证书了。

...
HttpClient client = new HttpClient();
client.getState().setCredentials(new AuthScope("www.restfuljava.com",
443, "realm"), new UsernamePasswordCredentials("username",
"password"));
GetMethod get = new GetMethod("http://www.restfuljava.com/webservice
/users");
get.setDoAuthentication(true);
client.executeMethod(get);
...

不过,这样一来,该客户端就只能用于访问证书对应的网站。

 

OAuth认证方式。

允许第三方访问用户数据,只通过授权验证方式,即每次访问不需要提供用户名及密码。需要为该认证方式提供另外一个独立的Web Service。

如果不用这种方式,如果一个服务提供者想要别人来使用自己的服务,那就必须向使用者提供相应的证书。

 

 OAuth和OpenID是不同的两种协议。OpenID是指,使用同一个证书,访问不同的网络应用。

 

性能

简单来说,RESTful web service的性能是由web框架决定的。

High availability意味着0或者最低的运行故障时间。对于一个复杂的web结构,达到0运行故障时间是不可能的。有时候我们不得不关掉整个系统,这是不可避免的。

 

对于如何减少系统故障运行时间最常用的方法就是,硬件冗余,即当一个机器出了问题,停止工作,另外一个机器会接替他的工作。

 

 



本节将通过一个示例来介绍如何访问RESTful服务,该示例中,我们通过访问Flickr的REST API返回图片信息,有关Flickr的API大家可以访问http://flickr.com/services/api/查看。开始使用之前需要在http://flickr.com/services/api/keys/申请一个API Key,如图12-13所示。

RESTful Web Service 的安全(token 认证方式)以及性能_第2张图片 
(点击查看大图)图12-13
编写一个简单的用户界面,供用户输入搜索主题,如下面的示例代码所示:
XAML


Margin="10"/>
在"搜索"Button控件单击事件中调用Flickr的REST API,访问RESTful服务并无特别方式,只要发起一个基于HTTP的请求即可,可以使用WebClient或者后面将要介绍的HttpWebRequest,然后对请求的数据做处理,如下面的示例代码所示:
C#
void btnSearch_Click(object sender, RoutedEventArgs e)
{
String apiKey = "3b6ed657779c5c27bb05e73b551d0e7e";
String url = String.Format("
http://api.flickr.com/services/rest/?method=
flickr.photos.search&api_key={1}&text={0}",
txtTopic.Text, apiKey);
    WebClient client = new WebClient();
client.DownloadStringCompleted +=
new DownloadStringCompletedEventHandler
(OnFlickrDownloadStringCompleted);
client.DownloadStringAsync(new Uri(url));
}
void OnFlickrDownloadStringCompleted(object sender, 
DownloadStringCompletedEventArgs e)
{
if (e.Error != null)
{
return;
}
    string result = e.Result;
}
运行程序后,在Visual Studio中使用XML Visualizer查看返回的结果,如图12-14所示。
RESTful Web Service 的安全(token 认证方式)以及性能_第3张图片 
(点击查看大图)图12-14
可以看到返回的结果是一个标准的、且不复杂的XML文档。对于该XML的处理有很多种方法,可以使用Silverlight 2中操作XML的API或者使用LINQ to XML。现在定义一个业务类来对应XML返回的结果,因为我们最终需要的是图片的URL值,如下面的示例代码所示:
C#
public class FlickrPhoto
{
public String Id { get; set; }
public String Owner { get; set; }
public String Secret { get; set; }
public String Server { get; set; }
public String Farm { get; set; }
public String Title { get; set; }
    public String ImageUrl
{
get
{
return String.Format
("http://farm{0}.static.flickr.com/{1}/{2}_{3}.jpg",
Farm, Server, Id, Secret);
}
}
}
该FlickrPhoto 类的ImageUrl属性通过其他几个属性组合而成,大家可以参考Flickr API的有关文档。现在重新修改OnFlickrDownloadStringCompleted事件,并添加两个全局变量Photos和ImageNumber,使用LINQ to XML实现XML结果与定义的业务类之间的映射,如下面的示例代码所示:
C#
IEnumerable Photos;
int ImageNumber = 0;
    void OnFlickrDownloadStringCompleted(object sender, 
DownloadStringCompletedEventArgs e)
{
XDocument xmlPhotos = XDocument.Parse(e.Result);
if (e.Error != null ||
xmlPhotos.Element("rsp").Attribute("stat").Value == "fail")
{
return;
}
        Photos = from photo in xmlPhotos.Element("rsp").
Element("photos").Descendants().ToList()
select new FlickrPhoto
{
Id = (String)photo.Attribute("id"),
Owner = (String)photo.Attribute("owner"),
Secret = (String)photo.Attribute("secret"),
Server = (String)photo.Attribute("server"),
Farm = (String)photo.Attribute("farm"),
Title = (String)photo.Attribute("title"),
};
        FlickrPhoto p = Photos.Skip(ImageNumber).First();
BitmapImage bitmap = new BitmapImage();
bitmap.UriSource = new Uri(p.ImageUrl);
this.imgTarget.SetValue(Image.SourceProperty, bitmap);
}
}
运行程序后,输入查询条件,可以看到效果如图12-15所示。
RESTful Web Service 的安全(token 认证方式)以及性能_第4张图片 
(点击查看大图)图12-15
根据搜索的结果,应该是一个图片的集合,但现在仅仅显示一张图片,接下来实现单击图片时,显示下一张图片,在Image控件的MouseLeftButtonDown事件中实现,如下面的示例代码所示:
C#
void imgTarget_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (Photos == null) return;
if (ImageNumber >= Photos.Count()) ImageNumber = 0;

FlickrPhoto p = Photos.Skip(ImageNumber).First();
BitmapImage bitmap = new BitmapImage();
bitmap.UriSource = new Uri(p.ImageUrl);
this.imgTarget.SetValue(Image.SourceProperty, bitmap);

ImageNumber++;

}

现在再单击图片时,将会继续显示下一张。通过上面的示例可以看到,调用RESTful服务与调用其他服务并没有什么特别的地方,仅仅是使用WebClient或HttpWebRequest发起请求,并针对请求结果进行处理。

你可能感兴趣的:(JAVA开发)