使用 JAAS 进行开发以使用程序来进行登录

使用 JAAS 进行开发以使用程序来进行登录
“Java 认证和授权服务”(JAAS)是 WebSphere Application Server V5 中的一项新功能。此功能也是“J2EE 1.3 规范”所要求的。“Java 认证和授权服务”代表的是用于进行认证的策略性 API,它替换了 CORBA 程序登录 API。另外,WebSphere Application Server 提供了一些 JAAS 扩展。

如果应用程序使用定制 JAAS 登录配置,则请确保正确地定义定制 JAAS 登录配置。有关详细信息,参见配置 JAAS 登录配置。

一 些 JAAS API 受“Java 2 安全性”许可权保护,如果应用程序代码使用这些 API,则请确保将这些许可权添加至应用程序的 was.policy 文件。有关更多信息,参见was.policy 文件。有关哪些 API 受“Java 2 安全性”许可权保护的更多详细信息,请查阅 J2SDK、JAAS 和 WebSphere Application Server API javadoc 以了解更多详细信息。下面列示了本文档中的样本代码中使用的一些 API 以及这些 API 所需的“Java 2 安全性”许可权:

javax.security.auth.login.LoginContext 构造函数受 javax.security.auth.AuthPermission createLoginContext 保护。 
javax.security.auth.Subject.doAs() 和 com.ibm.websphere.security.auth.WSSubject.doAs() 受 javax.security.auth.AuthPermission doAs 保护。 
javax.security.auth.Subject.doAsPrivileged() 和 com.ibm.websphere.security.auth.WSSubject.doAsPrivileged() 受 javax.security.auth.AuthPermission doAsPrivileged 保护。 
WebSphere Application Server 提供了下列 JAAS 扩展:

com.ibm.websphere.security.auth.WSSubject 
由 于 JAAS 1.0 的设计失误,javax.security.auth.Subject.getSubject() 不返回与 java.security.AccessController.doPrivileged() 代码块中的执行线程相关联的主体。这可能会引起不一致的问题行为并导致不良后果。 com.ibm.websphere.security.auth.WSSubject 提供了一种变通方法来将主体与执行线程相关联。 

com.ibm.websphere.security.auth.WSSubject 将 JAAS 模型扩展到 J2EE 资源,以便进行授权检查。如果主体与 com.ibm.websphere.security.auth.WSSubject.doAs() 中的执行线程相关联,或者如果 com.ibm.websphere.security.auth.WSSubject.doAsPrivileged() 代码块包含产品凭证,则将把该主体用于 J2EE 资源授权检查。有关更多信息,参见 com.ibm.websphere.security.auth.WSSubject。

用于定义新的 JAAS 登录配置的 UI 支持 
可 以在管理控制台中配置 JAAS 登录配置并将其存储在 WebSphere 公共配置模型中。应用程序可以在管理控制台中定义新的 JAAS 登录配置并将数据持久存储在配置资源库中(资源库存储在 WebSphere 公共配置模型中)。然而,WebSphere 仍支持 JAAS 缺省实现提供的缺省 JAAS 登录配置格式(纯文本文件)。但如果 WebSphere 公共配置和纯文本格式文件中定义了重复的登录配置,则 WebSphere 公共配置中的登录配置具有优先权。在 WebSphere 公共配置中定义登录配置具有如下优点:

用于定义 JAAS 登录配置的 UI 支持。 
可以集中管理 JAAS 配置登录配置。 
在 Network Deployment 安装中,JAAS 配置登录配置是分布式的。 

WebSphere JAAS 登录配置 
WebSphere 为应用程序提供了 JAAS 登录配置来对 WebSphere 安全性运行时执行程序认证。这些 WebSphere JAAS 登录配置根据所提供的认证数据来对 WebSphere 配置的认证机制(SWAM 或 LTPA)和用户注册表(LocalOS、LDAP 或 Custom)执行认证。来自这些 JAAS 登录配置的经过认证的主体包含必需的“主体”和“凭证”,WebSphere 安全性运行时使用这个必需的“主体”和“凭证”来对基于 J2EE 角色的受保护资源执行授权检查。WebSphere 提供的 JAAS 登录配置如下:

WSLogin JAAS 登录配置 
这是类属 JAAS 登录配置,例如,Java 客户机、客户机容器应用程序、servlet、JSP 和企业 Bean 组件可以使用此登录配置来根据用户标识和密码或记号对 WebSphere 安全性运行时执行认证。然而,此登录配置不考虑“客户机容器”部署描述符中指定的 CallbackHandler。

ClientContainer JAAS 登录配置 
这 个 JAAS 登录配置接受“客户机容器”部署描述符中指定的 CallbackHandler。此登录配置的“登录模块”将使用“客户机容器”部署描述符中的 CallbackHandler(如果指定了的话),即使应用程序代码在 LoginContext 中指定了一个 CallbackHandler 亦如此。此登录配置用于“客户机容器”应用程序。

注意:使用上述 JAAS 登录配置进行认证的主体包含 com.ibm.websphere.security.auth.WSPrincipal 和 com.ibm.websphere.security.auth.WSCredential。如果在 com.ibm.websphere.security.auth.WSSubject.doAs()(或其它 doAs() 方法)中传送经过认证的主体,则 WebSphere 安全性运行时可以根据主体的 com.ibm.websphere.security.auth.WSCredential 来对 J2EE 资源执行授权检查。

客户定义的 JAAS 登录配置 
客 户可以定义其它 JAAS 登录配置。有关详细信息,参见配置 Java 认证和授权服务登录。使用这些登录配置来对客户的认证机制执行程序认证。然而,WebSphere 安全性运行时可能无法使用来自这些客户定义 JAAS 登录配置的主体来执行授权检查(如果它没有包含必需的主体和凭证的话)。

在使用 JAAS 进行程序登录时,您可以选择下列选项:

通过非提示实现来使用程序进行登录。 
产 品提供了 javax.security.auth.callback.CallbackHandler 接口的非提示实现,这个非提示实现名为 com.ibm.websphere.security.auth.callback.WSCallbackHandlerImpl。 这个 com.ibm.websphere.security.auth.callback.WSCallbackHandlerImpl 允许应用程序将认证数据“推送”到 WebSphere LoginModule 以执行认证。对于服务器端应用程序代码认证标识并想要使用该标识来调用下游 J2EE 资源而言,这可能非常有用。例如: 

javax.security.auth.login.LoginContext lc = null;

try {
  lc = new javax.security.auth.login.LoginContext("WSLogin",
      new
  com.ibm.websphere.security.auth.callback.WSCallbackHandlerImpl
  ("user","securedpassword"));

  // create a LoginContext and specify a CallbackHandler implementation
  // CallbackHandler implementation determin how authentication data is collected
  // in this case, the authentication data is "push" to the authentication mechanism
  // implemented by the LoginModule.
  }
  catch (javax.security.auth.login.LoginException e) {
    System.err.println("ERROR: failed to instantiate a LoginContext and the exception: " +
                e.getMessage());
    e.printStackTrace();

    // may be javax.security.auth.AuthPermission "createLoginContext" is not granted
    // to the application, or the JAAS login configuration is not defined.
  }

  if (lc != null) {
    try {
    lc.login(); // perform login

    // get the authenticated subject
    javax.security.auth.Subject s = lc.getSubject();

    // Invoke a J2EE resources using the authenticated subject
    com.ibm.websphere.security.auth.WSSubject.doAs(s,
          new java.security.PrivilegedAction() {
      public Object run() {
        try {
        bankAccount.deposit(100.00); // where bankAccount is an protected enterprise bean
        }
        catch (Exception e) {
        System.out.println("ERROR: error while accessing enterprise bean resource, exception: "
                      + e.getMessage());
        e.printStackTrace();
        }
        return null;
      }
    }
    )
  }
}
catch (javax.security.auth.login.LoginException e) {
  System.err.println("ERROR: login failed with exception: " + e.getMessage());
  e.printStackTrace();

  // login failed, might want to provide relogin logic
}
有关更多信息,参见示例:JAAS 程序登录。

Copy code
示例:JAAS 程序登录
以下示例说明应用程序可以如何使用 JAAS 认证来执行程序登录:

LoginContext lc = null;
        
try {
  lc = new LoginContext("WSLogin",
      new WSCallbackHandlerImpl("userName", "realm", "password"));
}
catch (LoginException le) {
  System.out.println("Cannot create LoginContext. " + le.getMessage());
  // insert error processing code
}
catch(SecurityException se) {
  System.out.printlin("Cannot create LoginContext." + se.getMessage();
  // Insert error processing
}

try {
  lc.login();
}
catch(LoginExcpetion le) {
  System.out.printlin("Fails to create Subject. " + le.getMessage());
  // Insert error processing code
}
如 示例所示,新的 LoginContext 是使用 WSLogin 登录配置和 WSCallbackHandlerImpl CallbackHandler 进行初始化的。WSCallbackHandlerImpl 适合于在不需要提示的服务器端应用程序中使用。WSCallbackHandlerImpl 实例由指定的用户标识、密码和域信息初始化。WSLogin 指定的当前 WSLoginModuleImpl 类实现只能从指定的 CallbackHandler 检索认证信息。可使用 Subject 对象来构造 LoginContext,但当前 WSLoginModuleImpl 实现不考虑该 Subject。对于 WebSphere 客户机容器应用程序,将 WSLogin 替换为指定了针对客户机容器需求进行定制的 WSClientLoginModuleImpl 实现的 ClientContainer 登录配置。

对 于纯粹 Java 应用程序客户机,WebSphere 提供了另外两个 CallbackHandler 实现:WSStdinCallbackHandlerImpl 和 WSGUICallbackHandlerImpl,它们分别在命令行和弹出面板上提示用户名、密码和域信息。用户可根据特定的应用程序环境来选择其中一 个 WebSphere CallbackHandler。如果那些实现都不能满足您的特定应用程序需求,则您可以开发新的 CallbackHandler。

另外,如果缺省的 WSLoginModuleImpl 实现无法满足您的所有需求,则您还可以开发自己的 LoginModule。WebSphere 提供了可以由定制 LoginModule 使用的实用程序函数,下一节描述这些函数。


注 意:com.ibm.websphere.security.auth.callback.WSCallbackHandlerImpl 回调处理程序可以由纯粹 Java 客户机、客户机应用程序容器、企业 Bean 组件、JSP、servlet 或任何其它 J2EE 资源使用。

使用程序来从图形用户界面实现登录。

WebSphere 还提供了 javax.security.auth.callback.CallbackHandler 接口的图形用户界面(GUI)实现,此图形用户界面实现通过 GUI 登录提示来从用户那里收集认证数据。GUI 实现名为 com.ibm.websphere.security.auth.callback.WSGUICallbackHandlerImpl。 此回调处理程序显示 GUI 登录面板来提示用户输入认证数据。

例如:

javax.security.auth.login.LoginContext lc = null;

try {
  lc = new javax.security.auth.login.LoginContext("WSLogin",
      new com.ibm.websphere.security.auth.callback.WSGUICallbackHandlerImpl());

  // create a LoginContext and specify a CallbackHandler implementation
  // CallbackHandler implementation determin how authentication data is collected
  // in this case, the authentication date is collected by GUI login prompt
  // and pass to the authentication mechanism implemented by the LoginModule.
}
catch (javax.security.auth.login.LoginException e) {
  System.err.println("ERROR: failed to instantiate a LoginContext and the exception: " +
    e.getMessage());
e.printStackTrace();

// may be javax.security.auth.AuthPermission "createLoginContext" is not granted
// to the application, or the JAAS login configuration is not defined.
}

if (lc != null) {
  try {
    lc.login(); // perform login
    javax.security.auth.Subject s = lc.getSubject(); // get the authenticated subject

    // Invoke a J2EE resources using the authenticated subject
    com.ibm.websphere.security.auth.WSSubject.doAs(s,
        new java.security.PrivilegedAction() {
      public Object run() {
        try {
        bankAccount.deposit(100.00); // where bankAccount is an protected enterprise bean
        }
        catch (Exception e) {
        System.out.println("ERROR: error while accessing enterprise bean resource, exception: " +
          e.getMessage());
        e.printStackTrace();
        }
      return null;
    }
    }
  )
}
catch (javax.security.auth.login.LoginException e) {
  System.err.println("ERROR: login failed with exception: " + e.getMessage());
  e.printStackTrace();

  // login failed, might want to provide relogin logic
}
注 意:不应该将 com.ibm.websphere.security.auth.callback.WSGUICallbackHandlerImpl 回调处理程序用于服务器端资源(如企业 Bean 组件、servlet 和 JSP 文件)。GUI 登录提示在用户输入时将阻塞服务器。对于服务器进程而言这不是所期望的行为。另外,也不应该将其用于 iSeries 5250 客户机。

使用程序来从标准输入实现登录。 
WebSphere 还提供了 javax.security.auth.callback.CallbackHandler 接口的标准输入实现来通过标准输入从用户那里收集认证数据,此标准输入实现名为 com.ibm.websphere.security.auth.callback.WSStdinCallbackHandlerImpl。 此回调处理程序在标准输入中提示用户输入认证数据。

javax.security.auth.login.LoginContext lc = null;

try {
  lc = new javax.security.auth.login.LoginContext("WSLogin",
      new com.ibm.websphere.security.auth.callback.WSStdinCallbackHandlerImpl());

  // create a LoginContext and specify a CallbackHandler implementation
  // CallbackHandler implementation determin how authentication data is collected
  // in this case, the authentication date is collected by stdin prompt
  // and pass to the authentication mechanism implemented by the LoginModule.
}
catch (javax.security.auth.login.LoginException e) {
  System.err.println("ERROR: failed to instantiate a LoginContext and the exception: " +
                e.getMessage());
  e.printStackTrace();

  // may be javax.security.auth.AuthPermission "createLoginContext" is not granted
  // to the application, or the JAAS login configuration is not defined.
}

if (lc != null) {
  try {
    lc.login(); // perform login
    javax.security.auth.Subject s = lc.getSubject();
    // get the authenticated subject

    // Invoke a J2EE resources using the authenticated subject
    com.ibm.websphere.security.auth.WSSubject.doAs(s, new java.security.PrivilegedAction() {
    public Object run() {
      try {
        bankAccount.deposit(100.00); // where bankAccount is an protected enterprise bean
      }
      catch (Exception e) {
        System.out.println("ERROR: error while accessing enterprise bean resource, exception: " +
                    e.getMessage());
        e.printStackTrace();
      }
      return null;
    }
    }
  )
}
catch (javax.security.auth.login.LoginException e) {
  System.err.println("ERROR: login failed with exception: " + e.getMessage());
  e.printStackTrace();

  // login failed, might want to provide relogin logic
}
注 意:完全不应该将 com.ibm.websphere.security.auth.callback.WSStdinCallbackHandlerImpl 回调处理程序用于服务器端资源(如企业 Bean 组件、servlet、JSP 或任何其它服务器端资源)。标准输入提示在服务器环境中没有发送行为,通常大多数在后台运行的服务器都没有控制台。然而,如果服务器没有控制台,则标准输 入提示在用户输入时将阻塞服务器。对于服务器进程而言这不是所期望的行为。

你可能感兴趣的:(使用 JAAS 进行开发以使用程序来进行登录)