服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

安全技术 java与安全性,第2部分二


  privilegedaction
  
  任何实现privilegedaction接口的类都封装了一些代码,java客户端可以在由已填充的subject定义的安全上下文中运行这些代码。在这种安全上下文下调用已授权动作之前,weblogic.security.security.runas( )方法允许客户端把一个subject与当前线程相关联。
  
  示例jaas客户端
  
  让我们考察一下如何构建一个能够为weblogic对自身进行身份验证的jaas客户端。我们将使用从上至下的方法讲述这个例子,从jaas客户端需要实现的内容开始,然后再细分为其实现的单个组件。让我们从主类simplejaasclient开始,采取以下步骤:
  
  它从命令行读取用户名、密码和url作为输入参数。
  
  它尝试连接到特定的url,然后使用所提供的用户名和密码对客户端进行身份验证。
  
  它在新获得的已验证对象下执行一个已授权的动作。例17-1列出了我们的jaas客户端的源代码。
  
  例17-1列出了我们的jaas客户端的源代码。
  
  例17-1.示例jaas客户端
  
  package com.oreilly.wlguide.security.jaas;
  import javax.security.auth.subject;
  import javax.security.auth.login.logincontext;
  public class simplejaasclient {
  public static void main(string[] args) {
  string username = args[0];
  string password = args[1];
  string url = args[2];
  logincontext logincontext = null;
  // create a logincontext using our own callbackhander
  try {
  logincontext = new logincontext("simple",
  new simplecallbackhandler(username, password, url));
  } catch (exception e) {
  // can get a securityexception or a loginexception
  e.printstacktrace( );
  system.exit(-1);
  }
  // now authenticate. if we don't get an exception, we succeeded
  try {
  logincontext.login( );
  } catch (exception e) {
  // can get failedloginexception, accountexpiredexception,
  // or credentialexpiredexception
  e.printstacktrace( );
  system.exit(-1);
  }
  // retrieve authenticated subject and perform action using it
  subject subject = logincontext.getsubject( );
  simpleaction simpleaction = new simpleaction(url);
  weblogic.security.security.runas(subject, simpleaction);
  }
  }
  
  注意我们是如何突出jaas客户端的重点部分的。我们的第一个关键步骤是建立logincontext对象:
  
  logincontext = new logincontext("simple",new simplecallbackhandler(username, password, url));
  
  logincontext对象使用将在jaas身份验证期间使用的callbackhandler和loginmodule实例初始化了客户端。构造器带的第二个参数是我们自己的callbackhandler实例,loginmodule将使用它来获得用户证书,以及将对我们的客户端进行身份验证的weblogic实例的url。
  
  构造器带的第一个参数是simple,用于为客户端查找适当的loginmodule。jaas客户端依赖于一个配置文件,该配置文件把jaas登录模块的名称映射为它们的实现,而且还指定了另外的参数。例17-2列出了我们使用的jaas配置文件。
  
  例17-2. 登录配置文件jaas.config
  
  simple {
  weblogic.security.auth.login.usernamepasswordloginmodule
  required
  };
  
  我们的配置文件包含一个simple入口,在给定用户名和密码的基础上为身份验证指定了weblogic的loginmodule: weblogic.security.auth.login.usernamepasswordloginmodule.当运行jaas客户端时,必须使用一个系统属性指定该配置文件的位置。下面说明了如何运行我们的示例jaas客户端:
  
  java -djava.security.auth.login.config=jaas.config com.oreilly.wlguide.security.jaas.simplejaasclient system pssst t3://10.0.10.10:
  8001/
  
  这样,我们就可以配置logincontext以使用weblogic的 loginmodule,它支持使用用户名-密码组合的身份验证。稍后,我们将看一看如何使用jaas配置文件透明地使用loginmodule实现来代替这种方法。
  
  建立登录上下文之后,我们调用了logincontext.login( )方法来执行实际的登录。我们的logincontext将利用已配置的登录模块和回调处理对象,并尝试借助服务器对客户端进行身份验证。如果客户端成功通过身份验证,可以从logincontext获得已验证的主题:
  
  subject subject = logincontext.getsubject( );
  
  这个已验证subject上的getprincipals( )方法将获得与用户相关的所有主体。例如,如果我们的jaas客户端使用系统管理员的证书进行身份验证,已验证的subject将具有两个主体:代表用户的system,和代表用户的组的administrators。现在,我们可以使用这个主题来执行一个或多个“已授权”的操作。换句话说,这些操作是在这个已验证主题的上下文中执行的:
  
  weblogic.security.security.runas(subject, simpleaction);
  
  这里给出一个忠告――客户端必须调用weblogic的security类上的runas( )方法。runas( )方法带有两个参数:已验证的subject和一个privilegedaction对象,后者包装了应用程序与服务器的特定交互。例17-3说明了我们的jaas客户端希望执行的操作。
  
  例17-3. 一个非常简单的操作
  
  package com.oreilly.wlguide.security.jaas;
  import java.security.privilegedaction;
  import java.sql.connection;
  import java.util.hashtable;
  import javax.naming.context;
  import javax.naming.initialcontext;
  import javax.sql.datasource;
  public class simpleaction implements privilegedaction {
  private static final string jndi_name = "jdbc.xpetstore";
  private string url;
  public simpleaction(string url) {
  this.url = url;
  }
  public object run( ) {
  object obj = null;
  try {
  context ctx = null;
  hashtable ht = new hashtable( );
  ht.put(context.initial_context_factory,
  "weblogic.jndi.wlinitialcontextfactory");
  ht.put(context.provider_url, url);
  // get a context for the jndi lookup
  ctx = new initialcontext(ht);
  // do any work here
  datasource ds =(javax.sql.datasource) ctx.lookup(jndi_name);
  // ...
  } catch (exception e) {
  e.printstacktrace( );
  }
  return obj;
  }
  }
  
  在这里,需要考虑以下重点:
  
  类实现 java.security.privilegedaction接口。然后,任何jaas 客户端都可以在已验证subject的上下文中调用这个类的一个实例。
  
  run( )方法封装了客户端与服务器的交互。通常,客户端将建立一个jndi上下文,使用它来获取绑定到jndi树的资源,然后调用/访问这些资源。在前面的例子中,我们使用了jndi上下文来获得jdbc数据源。
  
  当我们在privilegedaction.run( )方法中建立jndi上下文时,我们没有为jndi身份验证提供任何用户证书。jaas客户端提供已验证的subject给runas( )方法,确保privilegedaction对象是在这个主题的上下文中调用的。也就是说,runas( )方法负责把已验证的主题与当前线程关联起来。
  
  例17-4列出了我们的callbackhandler类的源代码。通常,回调处理程序将与客户端交互,提示用户输入用于身份验证的用户名和密码。在我们的简单jaas客户端的例子中,我们提供了必需的证书和url给我们的回调处理程序的构造器,这样回调便可容易地返回这些信息。
  
  例17-4. 一个简单的回调处理器
  
  package com.oreilly.wlguide.security.jaas;
  
  import javax.security.auth.callback.callback;
  import javax.security.auth.callback.callbackhandler;
  import javax.security.auth.callback.namecallback;
  import javax.security.auth.callback.passwordcallback;
  import javax.security.auth.callback.unsupportedcallbackexception;
  import weblogic.security.auth.callback.urlcallback;
  
  public class simplecallbackhandler implements callbackhandler {
  private string username = null;
  private string password = null;
  private string url = null;
  
  public simplecallbackhandler(string pusername, string ppassword, string purl) {
  username = pusername; password = ppassword; url = purl;
  }
  
  public void handle(callback[] callbacks)
  throws java.io.ioexception, unsupportedcallbackexception {
  for (int i = 0; i < callbacks.length; i++) {
  if (callbacks[i] instanceof namecallback) {
  namecallback nc = (namecallback) callbacks[i];
  nc.setname(username);
  } else if (callbacks[i] instanceof urlcallback) {
  urlcallback uc = (urlcallback) callbacks[i];
  uc.seturl(url);
  } else if (callbacks[i] instanceof passwordcallback) {
  passwordcallback pc = (pa

扫描关注微信公众号