科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网网络频道连载:选择正确Web服务安全解决方案(三)

连载:选择正确Web服务安全解决方案(三)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

通过允许配置一个用于口令验证的LDAP,应用程序服务器支持UsernameToken身份验证。由于其简易性和在应用程序服务器中的广泛支持,UsernameToken身份验证是非常吸引人的。

作者: 赛迪网 来源:赛迪网 2007年10月4日

关键字: UsernameToken Web服务 args SOAP

  • 评论
  • 分享微博
  • 分享邮件

UsernameToken 身份验证

UsernameToken 身份验证与HTTP身份验证很相似,此时用户保密信息在消息的头部被传送。UsernameToken被添加到SOAP的头部,可能还会夹杂着一个散列的口令。这是一种加密的简单形式,可以避免无限制地传递口令。应该使用传输级别或者消息级别的加密来保证用户口令的保密性。

通过允许配置一个用于口令验证的LDAP,应用程序服务器支持UsernameToken身份验证。在应用程序服务器收到一个SOAP消息时,在将消息转发给应用程序之前,它会通过LDAP验证用户证书的正确性。

由于其简易性和在应用程序服务器中的广泛支持,UsernameToken身份验证是非常吸引人的。然而,在考虑将它部署到你的应用框架时,你必须清楚其限制条件:

会话状态: UsernameToken需要用户名和口令在每一个Web服务的调用上都被传递。这暗示着如果客户端经常与该服务会话,客户端必须要对口令进行缓存,而这会导致一种安全风险。

性能:应用程序服务器必须重新验证每一个Web服务调用。而且,因为口令是消息的一部分,那么即使消息并没有包含敏感信息也必须加密。

为了演示UsernameToken身份验证,下面的例子重新使用了计算器服务的例子。你必须配置应用程序服务器以支持UsernameToken的安全,并且指定一个LDAP来验证用户的证书。配置步骤是与特定服务器相关的,因此请参考你的服务器的相关文档。笔者用WebSphere 6.1和活动目录测试了这个例子。

你必须增加一个WSS4J SOAP处理程序,以支持客户端支持在报头中发送UsernameToken。下面的客户端代码在调用Web服务之前,先调用configureClientHandlers方法:

public static void main(String[] args) throws MalformedURLException {
      CalculatorServiceClient sc = new CalculatorServiceClient();
      Calculator calc = sc.getCalculator(UT_ENDPOINT);
      configureClientHandlers(calc);
      float a = 5f;
      float b = 7f;
      System.out.println(a + " * " + b + " = " + calc.multiply(a,b));
   }

configureClientHandlers方法创建一个新的拥有UsernameToken 属性的WSS4JoutHandler处理程序。下面的configureUsernameToken方法指定了属性:

private static void configureClientHandlers(Object svc) {
      Client client=Client.getInstance(svc);
      client.addOutHandler(new DOMOutHandler());
      Properties properties = new Properties();
      // Configure the UsernameToken properties
      configureUsernameToken(properties);
      client.addOutHandler(new WSS4JOutHandler(properties));	
		
   }

   protected static void configureUsernameToken(Properties config)
	    {
          // UsernameToken Action
           config.setProperty(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
	        
           // Clear Text Password
           config.setProperty(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
           // User name to send
           config.setProperty(WSHandlerConstants.USER, "johndoe");
           // Callback used to retrieve password for given user.
           config.setProperty(WSHandlerConstants.PW_CALLBACK_CLASS, 
PasswordHandler.class.getName());
	         
   }

口令从PasswordHandler中重新检索。它将口令存储在一个由用户名索引的地图中。下面是示例样本的用户证书代码:

public class PasswordHandler implements CallbackHandler {
   private Map passwords = new HashMap();
   public PasswordHandler() {
      passwords.put("johndoe", "abc123");
   }
   ...
The following SOAP message is observed by the TCP/IP monitor after running the client: 
<soap:Envelope ...>
   <soap:Header>
      <wsse:Security ...>
         <wsse:UsernameToken ...>
            <wsse:Username ...>
               johndoe
            </wsse:Username>
            <wsse:Password ...>
               abc123
            </wsse:Password>
         </wsse:UsernameToken>
      </wsse:Security>
   </soap:Header>
   <soap:Body>
      <multiply xmlns="http://ejb.security.ws.dev.com">
         <a>5.0</a>
         <b>7.0</b>
      </multiply>
   </soap:Body>
</soap:Envelope>

现在这个SOAP消息的头部部分包含了用户名和口令。服务器对用户证书进行验证,或者许可或者拒绝了对目标Web服务的访问。为了防止对口令的窃听,你必须使用消息级的加密或者以前描述的SSL方法。

一个.net2.0客户端也将一个UsernameToken添加到SOAP/HTTP的头部。为了支持这项功能,你必须在你的Visual Studio环境中安装WSE 3.0库及其扩展。(你可从这里下载。)你必须像在Java客户端的例子中所做的那样,从WSDL中生成一个客户端的stub。生成的stub看起来会是如下这样子:

...    
public partial class CalculatorServiceWse : Microsoft.Web.Services3.WebServicesClientProtocol {
        
        private System.Threading.SendOrPostCallback multiplyOperationCompleted;
        
        private bool useDefaultCredentialsSetExplicitly;
	  ...

一旦stub被创建,客户端代码就会展现这个stub,并且指定UsernameToken被发送到服务器。下面的c#示例代码演示了如何做到:

static void Main(string[] args)
        {
            CalculatorServiceWse calc = new CalculatorServiceWse();
            calc.Url = "http://localhost:9080/WSUTSigEncRouterWeb/services/Calculator";
//
            UsernameToken token = new UsernameToken("johndoe", "abc123", 
PasswordOption.SendPlainText);
            calc.SetClientCredential(token);
            calc.SetPolicy("usernameTokenSecurity");
            float result = calc.multiply(7, 5);
            Console.WriteLine("Result = " + result);
            Console.ReadLine();
        }

运行客户端代码就会生成所期望的输出结果:Result = 35.0

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章