转载:http://www.ibm.com/developerworks/cn/webservices/1106_webservicessecurity/

 

简介

正如"HTTP Basic Authentication"这个名字,它是 Authentication( 认证 ) 中最简单的方法。长期以来,这种认证方法被广泛的使用。当你通过 HTTP 协议去访问一个使用 Basic Authentication 保护的资源时,服务器通常会在 HTTP 请求的 Response 中加入一个"401 需要身份验证"的 Header,来通知客户提供用户凭证,以使用资源。如果你正在使用 Internet Explorer 或者 Mozilla Firefox 这样的可视化浏览器来访问需要认证的资源,浏览器会弹出一个窗口,让你输入用户名和密码,如果所输入的用户名在资源使用者的验证列表,并且密码完全正确,此时,用户才可以访问受限的资源。那么什么是 HTTP Basic Authentication 呢?如何在不同的服务器上配置 Basic Authentication 呢?下面本文将展开介绍。

 

HTTP Basic Authentication 介绍

HTTP BASIC 认证的基本流程如图 1 所示,

图 1. BASIC HTTP认证基本流程

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

HTTP Basic Authentication 是指客户端在使用 HTTP 协议访问受限资源时,必须使用用户名和密码在一个指定的域 (Realm) 中获取认证。在正式开始之前,我们需要明白以下名词的含义:

  1. Authentication,即认证,验证。它是一种确认的过程,通过这样的认证过程,你可以确定某物体是不是它所声称的那种物体。这通常会涉及到用户名和密码,也可能是身份证明,或生物特征,如视网膜等。
  2. Realm,即域。一个 Realm 就是一系列用户名和密码的“数据库”,它通常用来保存、识别某个或某些 Web 应用中有效的用户和密码。它还定义了每个有效用户所对应的角色。

本文将介绍如何使用 HTTP BASIC Authentication 来保护 Web services endpoint 服务资源,当 Web services 的 Endpoints 被设置为 BASIC HTTP 认证才能访问的受限资源时,用户必须提供用户名密码才能使用它们,基本的流程如图 2 所示。

图 2. Web services 客户端访问受限 Web services 服务流程

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

下面,本文将以 Tomcat 何 WebSphere Application Server 为例,分别讲述如何配置 Web services 的 endpoint 为受限资源,并使用 Web services 静态和动态客户端分别加以测试。

 

为 Tomcat 配置 Basic Authentication

本节将详细讲述如何在 Tomcat 下使用 Basic Authentication 来增强 Axis 实现的 Web services 访问的安全性。本文使用 Eclipse 来开发相关的例子,在这里假设您已经安装了相关的环境。

创建 Web services Provider 应用

在 Eclipse 中新建一个 Dynamic Web Project,并将其命名为“TomcatAxis”如图 3 所示:

图 3. 创建动态 WEB 工程

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

该工程的目录结构如图 4 所示:

图 4. 工程结构

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

为 Web services 添加实现

创建一个基于 Axis 实现的 Web Service,本文采取“Bottom up Java bean Web Service”方式创建,其具体操作过程为:

  1. 创建该 Web services 的实现类,代码如下
    清单 1. Web services Provider 实现代码
     package sample.test; 
     public class ServiceImpl { 
      /** 
       * return the summation of the two integer arguments 
       * @param addend 
       * @param augend 
       * @return 
       */ 
      public int sum(int addend, int augend) { 
        return addend + augend; 
      } 
     }
  2. 基于该实现类,创建 Web Service,如图 5 所示
    图 5. 创建 Web Service
    Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

    完成上述步骤后,会在 /TomcatAxis/WebContent/wsdl/ 目录下创建一个名称为“ServiceImpl.wsdl”的 WSDL 文件。

  3. 将 Web Application 部署到 Tomcat 上,使用 Eclipse 自带的 Web services 测试工具“Web services Explorer”来测试所创建的 Web services 是否能被使用,如图 6 所示
图 6. 测试所创建的 Web services

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

在确认所创建的 Web services 能够正常使用后,需要为 Web Application 配置 Basic Authentication。

为 Web Application 配置 Basic Authentication:

  1. 打开 Tomcat 安装目录下的“conf”文件夹,修改文件“tomcat-users.xml”,该文件是用来存储 Tomcat 预加载的用户和角色定义的,此文件即是上文提到的 Realm。在“<tomcat-users>”中加入如下用户和角色:
    清单 2. 定义用户及其角色
      <!-- Web services invoker role --> 
      <role rolename="WsInvokerRole"/> 
      
      <!-- Web services invokers/users --> 
      <user username="wsaxis" password="wsaxis" roles="WsInvokerRole"/>
  2. 打开 Web 应用“TomcatAxis”的部署描述符:web.xml 文件,并在“<web-app>”中加入如下片段:
    清单 3. 配置安全资源
      <!-- configurations for BASIC Authentication --> 
      <security-constraint> 
        <web-resource-collection> 
          <web-resource-name>All Web services Endpoints</web-resource-name> 
          <url-pattern>/services/*</url-pattern> 
        </web-resource-collection> 
        
        <auth-constraint> 
          <description>Web services invokers are allowed doing invocation</description> 
          <role-name>WsInvokerRole</role-name> 
        </auth-constraint> 
      </security-constraint> 
      
      <!-- authentication method --> 
      <login-config> 
        <auth-method>BASIC</auth-method> 
        <realm-name>Realm of Web services Invokers</realm-name> 
      </login-config>

    在“<security-constraint>”片段内,定义了改 Web Application 需要保护的资源,可以通过“<url-pattern>”来定义符合一定 URL 样式的资源,上述片段的定义,保护了所有 Web services 的 endpoints。

    “<login-config>”片段定义了采取 BASIC 认证方式,其中“<realm-name>”只在 BASIC 认证方式下有效,它分配安全领域名,此名称供浏览器用于对话框标题,且为 Authorization 头部的一部分。

  3. 重启 Tomcat,骤重新测试该 Web Service,将有如图 7 提示框,提示输入用户名和密码:输入之前所定义的 wsaxis 用户名及其密码后,点击 OK,Web services 将会被调用。否则将无法正常调用到 Web Service。
    图 7. 信息输入对话框
    Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制
 

测试 Tomcat 下 Basic Authentication

通常 Web services 可以有两种调用方式,即静态调用方式和动态调用方式。下面将分别介绍如何使用这两种方式验证 Basic Authentication 是否正常工作。

静态调用方式测试

首先,新建一个 Java Project,命名为“TomcatAxisClient”, 如图 8

图 8. 创建 Web services 测试客户端工程

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

其次,将前文所声称的 Web services 的 WSDL 的 URL 作为参数,生成 Web services 客户端,如图 9

图 9. 生成 Web services Client

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

完成上述操作后,将有如下结构的 Web services 客户端类生成,如图 10 所示:

图 10. 生成结果

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

使用上述客户端类,就可以实现 Web services 的调用。现在,需要创建一个测试类,实例化客户端类,调用 Web Service。类名为“sample.test.client.runable.StaticClientTest”,详细代码见清单 4.

清单 4. 静态调用类
 package sample.test.client.runable; 

 import java.net.URL; 
 import sample.test.ServiceImplServiceLocator; 
 import sample.test.ServiceImplSoapBindingStub; 

 public class StaticClientTest { 
  public static void main(String[] args) { 
    try { 
    // String userName = "wsaxis", password = "wsaxis"; 
      int addend = 64, augend = 128; 
      ServiceImplSoapBindingStub sisbs = new ServiceImplSoapBindingStub( 
          new URL(  "http://localhost:8080/TomcatAxis/services/ServiceImpl"), 
          new ServiceImplServiceLocator()); 
    // sisbs.setUsername(userName);   // sisbs.setPassword(password); 
      System.out 
          .println("Static Client Invocation:\n\tThe summation is: "
              + sisbs.sum(addend, augend)); 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
  } 
 }

运行上述代码,你将发现 Web services 不能够被顺利调用,此处将会抛出 Web services 调用异常,如图 11 所示:

图 11. 未认证时执行结果

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

这个错误表明,你所调用的资源是受保护的,你必须提供相关的认证信息来访问它们。如果把如下代码的注释符去掉,

// String userName = "wsaxis", password = "wsaxis";
… … 
// sisbs.setUsername(userName);
 // sisbs.setPassword(password);

再重新编译,运行,你就能得到正确的结果,如图 12

图 12. 认证后执行结果

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

由于 Web services 的 endpoint 被列为受限资源,需要使用这些资源,必须提供相应的认证信息。清单 4 中被注释掉的内容,正是用来向服务器认证时使用的,由于服务器无法获得认证信息,就返回了 401 Unauthorized 错误。去掉注释后的请求得到了服务器的认证,因而能够得到正确的结果。

动态调用方式测试

动态调用方式不需要生成 Web services 客户端,通过查找 Web services 提供的服务,就能调用 Web Service,此处不对动态调用方式详加解释, 清单 5 是使用动态调用的方式测试 Basic Authentication 的。

清单 5. 动态调用测试代码
 package sample.test.client.runable; 
 import javax.xml.namespace.QName; 
 import javax.xml.rpc.Call; 
 import javax.xml.rpc.ParameterMode; 
 import javax.xml.rpc.Service; 
 import javax.xml.rpc.ServiceFactory; 
 public class DynamicClientTest { 
  public static void main(String[] args) { 
    try { 
      String address = "http://localhost:8080/TomcatAxis/services/ServiceImpl"; 
      String namespaceURI = "http://test.sample"; 
      String serviceName = "ServiceImplService"; 
      String portName = "ServiceImpl"; 
      String operationName = "sum"; 
      String userName = "wsaxis", password = "wsaxis"; 
      int addend = 64, augend = 128; 
      ServiceFactory factory = ServiceFactory.newInstance(); 
      Service service = factory.createService(new QName(serviceName)); 
      Call call = service.createCall(new QName(portName)); 
      call.setTargetEndpointAddress(address); 
      QName intQName = new QName("http://www.w3.org/2001/XMLSchema","int"); 
      call.setOperationName(new QName(namespaceURI, operationName)); 
      call.addParameter("addend", intQName, ParameterMode.IN); 
      call.addParameter("augend", intQName, ParameterMode.IN); 
      call.setReturnType(intQName); 
      call.setProperty(Call.USERNAME_PROPERTY, userName); 
      call.setProperty(Call.PASSWORD_PROPERTY, password); 
      Object[] inParams = new Object[2]; 
      inParams[0] = new Integer(addend); 
      inParams[1] = new Integer(augend); 
      int value = ((Integer) call.invoke(inParams)).intValue(); 
      System.out.println("Dynamic Client Invocation:\n\tThe summation is: " + value); 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
  } 
 }

需要指出的是,与静态调用方式不同,动态调用方式设置认证的用户名和密码是通过 Property(属性)来设置的(代码中加粗的部分)。上述代码的运行结果如图 13 所示:

图 13. 动态调用测试结果

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

如果去掉清单 4 中加粗的部分,同样服务器将返回 401 Unauthorized 错误。

下面,本文将结合 Rational Application Developer Standard Edition Version 8.0 和 WebSphere Application Server Version 7.0 来介绍如何在 WAS 上配置 HTTP Basic Authentication,并使用 JAX-WS 实现的 Web services 加以测试。

 

WAS 下配置 HTTP Basic Authentication

使用 RAD 开发 Web services Provider 应用

首先,如同第 3 节中所述,在 Rational Application Developer(以下简称 RAD)中创建一个 Dynamic Project,此处需要注意,由于 RAD 中所使用的 WAS 只能部署 Enterprise Application Archive(EAR),因此,需要创建相应的 EAR 工程,并把所创建的 Dynamic Web Project 座位该 EAR 的模块。如图 14 所示:

图 14. 创建动态 WEB 工程

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

等待工程创建完毕之后,将有如图 15 所示的目录结构:图中高亮的两个工程是上述步骤所创建的。

图 15. 工程结构

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

接下来,我们仍然采用“Bottom up Java bean Web Service”方式创建用于测试的 Web Service:

  1. 创建 Web services 的实现类,并将如下代码复制并覆盖所创建的文件,如清单 6。
    清单 6. Web services Provider 实现代码
     package sample.test.jaxws; 
    
     public class JaxWsServiceImpl { 
      /** 
       * return the summation of the two integer arguments 
       * 
       * @param addend 
       * @param augend 
       * @return 
       */ 
      public int sum(int addend, int augend) { 
        return addend + augend; 
      } 
     }
  2. 使用该文件,创建 Web Service,在创建过程中,需要指定所采用的 Web services 运行时为“IBM WebSphere JAX-WS”,如图 16 所示
    图 16. 创建 Web services Provider
    Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制
  3. Web services 创建完毕后,将会被自动发布到 WAS 上,使用 Web services Explorer 加以简单测试,以便检查 Web services 是否能够被访问调用等。

配置 Web services Provider 应用的受限访问资源

此处,我们需要仿照上文为 Web services Provider 应用配置安全性,将 Web services 的 endpoint 作为受限资源,定义在应用的部署描述符(web.xml)中。

  1. 打开 web.xml 文件,切换到 Design 页面,如图 17 所示
    图 17. web.xml 编辑页面
    Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制
  2. 点击“Add …”按钮,在弹出的窗口中选择“Security Role”,确认后,对“Role Name”和“Description”赋值,其中“Role Name”是必填项,如图 18 所示
    图 18. 添加安全角色
    Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制
  3. 仿照步骤 2,添加“Security Constraint”项,展开“Authorization Constant”,点击“Add”按钮,添加一个 Role,名称为之前所创建的 Role:“wsRole”,继续配置 Security Constraint,将 Web services 的 endpoint 加入到受限资源中。配置完成后,如图 19 和图 20 所示:
    图 19. 添加受限资源
    Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制
    图 20. 添加受限资源 2
    Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制
  4. 仿照步骤 2,添加“Login Configuration”,在“Authentication Method”中输入“BASIC”,如图 21 所示
    图 21. 配置认证方式
    Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

至此,Web services Provider 的受限资源以及应用的 Basic Authentication 都配置完毕。如果需要 Basic Authentication 起作用,还必须启用 WAS 的安全设置,下面我们将简要讲述如何启动 WAS 安全。

配置 WAS 安全

  1. 打开到 WAS 的控制台,如图 22 所示
    图 22. WAS 控制台
    Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制
  2. 登录后,选择“Security – Global Security”菜单,并点击“Security Configuration Wizard”按钮,如图 23 所示
    图 23. 配置 WAS 安全 1
    Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制
  3. 在 Wizard 的步骤 2 中,选择“Federated repositories”作为资源库。点击“Next”,输入用户名密码,并确认密码,如图 24 所示。其中,用户名和密码将作为登录控制台的用户名和密码,此处,所输入的用户名和密码都是“jaxws”。完成向导后,保存所做的修改,并重新启动 WAS。
    图 24. 配置 WAS 安全 2
    Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制
  4. 重新登录控制台,此时,将提示你输入用户名和密码,如图 25 所示:
    图 25. 配置 WAS 安全 3
    Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

部署 Web services Provider 应用

在启用了安全的 WAS 上部署步骤创建的 Web services Provider 应用。

首先,在 RAD 中,将所创建的工程导出为 EAR 包;

其次,部署所导出的 EAR 到 WAS 中,具体步骤如下:

  1. 登录 WAS 控制台,并打开“Applications - Application Types - WebSphere enterprise applications”;
  2. 点击“Install”按钮,在“Preparing for the application installation”页面,点击“Browse”按钮,浏览到已经导出的 EAR 文件,并单击“Next”,如图 26 所示
    图 26. 部署 Web services Provider 到 WAS 1
    Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制
  3. 在新页面中选择“Detailed”选项,如图 27,单击“Next”
    图 27. 部署 Web services Provider 到 WAS 2
    Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制
  4. 单击链接“Step 8”,在 RAD 中所创建的 Role 和 WAS 中用户或组之间建立关联,如图 28 所示:
    图 28. 建立角色 ( 用户 ) 关联
    Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制
  5. 完成向导,并启动该 Web services Provider,如图 29 所示:
    图 29. 启动 Web services Provider 应用
    Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

至此,JAX-WS Web services Provider 的 Basic Authentication 已经配置完毕,下一节,将将输入和采用静态和动态调用方式测试它。

 

测试 WAS 下 Basic Authentication

静态调用方式测试

如同测试 Tomcat 上的 Basic Authentication 类似,需要在 RAD 中创建一个 Java Project,利用之前所创建的 Web services Provider 提供的 WSDL 文件,创建 Web services Client,需要指出的是,Web services 的运行时需要指定为“IBM WebSphere JAX-WS”。生成客户端之后的 Java Project 的目录结构如图 30 所示

图 30. 创建测试工程

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

创建一个测试 Class,命名为“sample.test.jaxws.client.runable.StaticClientTest”,其内容如清单 7 所示:

清单 7. 静态测试代码
 package sample.test.jaxws.client.runable; 
 import javax.xml.ws.BindingProvider; 
 import sample.test.jaxws.JaxWsServiceImplPortProxy; 

 public class StaticClientTest { 
  public static void main(String[] args) { 
    String userName = "jaxws", password = "jaxws"; 
    JaxWsServiceImplPortProxy proxy = new JaxWsServiceImplPortProxy(); 
    BindingProvider bp = (BindingProvider) proxy._getDescriptor() 
        .getProxy(); 
    bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, userName); 
    bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, 
        password); 
    System.out.println(proxy.sum(123, 312)); 
  } 
 }

运行该测试 Class,将得到如图 31 所示的结果:

图 31. 测试结果

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

如果将“userName”或“password”赋予了其他的值,运行测试 Class,将得到 401 Unauthorized 错误,如图 32 所示:

图 32. 未加认证的测试结果

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

动态调用方式测试

使用动态调用方式测试该 Web Service,需要基于 JAX-WS 的 API 开发客户端代码,本文给出测试需要 BASIC Authentication 认证的 Web services 的样例代码,如清单 8 所示:

清单 8. 动态测试代码

点击查看代码清单

以下是该样例代码的执行结果,如图 33 所示

图 33. 动态测试结果

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

通常,如果我们可以使用 Eclipse 或者 RAD 自带的 Web services Explorer 等测试工具来对 Web services 做简单的测试,或者,我们通过客户端来测试所开发的 Web services Provider。这样的测试通常只能发现简单而明显的问题,如何对 Web services Provider 做系统的测试呢? soapUI 这个工具能帮我们更加方便,更加系统地测试 Web services Provider。下面,我们将概述如何使用 soapUI 来测试 Web services 的 BASIC Authentication。

 

使用 SOAPUI 测试配置了 Basic Authentication 的 Web Service

soapUI 的是世界领先的 SOA 和 Web services 的测试工具。凭借其易于使用的图形界面和企业级功能,soapUI 能让你轻松,快速的创建和执行自动化测试,回归和负载测试。

首先,需要从 soapUI 的 官方网站 下载最新的 soapUI 安装文件,安装 soapUI。

其次,创建一个 soapUI 测试工程,提供被测试 Web services 的 WSDL 以便创建测试用例。如图 34 所示

图 34. soapUI 新建工程

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

如果选择了“Create Test Suite”,soapUI 将根据 Web services 的 operation 创建测试用例,同时,你还可以创建相关的性能测试用例,如图 35 所示

图 35. 生成测试集合

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

图 36 给出了所创建的测试工程,打开测试用例,可以看出,屏幕被分割成 3 个区域,在区域 A 中,显示了所创建的功能性测试用例和用于测试 Web services 性能的 Load Test 用例。区域 B 是 Web services 请求的配置区域,此处可以设置 Web services 使用的参数,认证等相关的信息。B 区中,红方格中的 Username 和 Password 正式设置 BASIC Authentication 使用的用户名和密码的。区域 C 是 Web services 请求返回(Response)显示区域。

图 36. soapUI 布局

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

然后,在区域 B 中,给 Web services 所使用参数赋值,并点击 B 区上方的“Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制 ”按钮,如图 37 所示。

图 37. 运行测试

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

此时,由于没有设置相关的认证信息,将会得到图 38 所示的相关错误信息。

图 38. 未认证时 soapUI 测试结果

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

在 B 区域红方格所示区域中输入认证信息,再重新执行测试用例,将得到如图 39 所示的结果。

图 39. soapUI 添加认证信息

Web services 安全实践: 基于 HTTP Basic Authentication 为 Web services 配置传输层安全机制

以上就是如何使用 soapUI 来测试 Web services BASIC Authentication 的步骤,从中我们可以发现,只需要简单的操作便可以实现 Web services 的测试,因此,soapUI 对于提供 Web services 的测试效率是有帮助的。

相关文章:

  • 2021-07-20
  • 2022-12-23
  • 2021-08-26
  • 2022-12-23
  • 2021-11-23
  • 2022-01-11
  • 2022-01-03
  • 2022-12-23
猜你喜欢
  • 2021-11-01
  • 2021-11-05
  • 2021-10-10
  • 2021-11-29
  • 2021-10-05
  • 2021-05-26
相关资源
相似解决方案