使用 Java 认证和授权服务(JAAS)来定制应用程序登录

使用 Java 认证和授权服务(JAAS)来定制应用程序登录

使用 Java 认证和授权服务(JAAS)可以定制应用程序登录。

关于本任务

Java 认证和授权服务(JAAS)是一种 API,它使应用程序能够在不连接至认证和访问控制服务的情况下,对这些服务进行访问。本节中阐述了以下对使用 JAAS 来定制应用程序进行说明的主题:

过程

  • 使用 Java 认证和授权服务(JAAS)来开发程序化登录
  • 为 JAAS 配置程序化登录
  • 配置服务器端 Java 认证和授权服务认证和登录配置

子主题
开发带 Java 认证和授权服务的程序化登录 
为 Java 认证和授权服务配置程序化登录 
定制应用程序登录以执行身份声明 
定制服务器端 Java 认证和授权服务认证和登录配置 
启用带信任验证的标识声明 
相关任务
开发 WebSphere 安全性基础结构的扩展

开发带 Java 认证和授权服务的程序化登录

使用本主题开发带 Java 认证和授权服务的程序化登录

在您开始之前

Java 认证和授权服务(JAAS)为认证提供策略应用程序编程接口(API)。

JAAS 替换公共对象请求代理体系结构(CORBA)程序化登录应用程序编程接口(API)。

WebSphere Application Server 提供一些对 JAAS 的扩展:
  • 请参阅开发使用 CosNaming(CORBA 命名接口)的应用程序 一文,以了解有关如何设置瘦客户机应用程序的环境以访问服务器上的远程资源的详细信息。
  • 如果应用程序使用定制 JAAS 登录配置,那么验证是否正确定义了 JAAS 登录配置。请参阅为 Java 认证和授权服务配置程序化登录 ,以了解详细信息。
  • 某些 JAAS API 受 Java 2 安全许可权的保护。如果这些 API 由应用程序代码使用,验证这些许可权是否已添加到应用程序 was.policy 文件。
    有关详细信息,请参阅以下文章: 有关 Java 2 安全许可权保护哪些 API 的更多详细信息,请检查 安全性:学习资源 中的 IBM Developer Kit, Java Technology Edition; JAAS and WebSphere Application Server public APIs 文档。
    以下列表中是此文档中的样本代码使用的一些 API 以及这些 API 需要的 Java 2 安全许可权:
    • 受 javax.security.auth.AuthPermission "createLoginContext" 对象保护的 javax.security.auth.login.LoginContext 构造函数。
    • 受 javax.security.auth.AuthPermission "doAs" 对象保护的 javax.security.auth.Subject.doAs 和 com.ibm.websphere.security.auth.WSSubject.doAs 方法。
    • 受 javax.security.auth.AuthPermission "doAsPrivileged" 对象保护的 javax.security.auth.Subject.doAsPrivileged 和 com.ibm.websphere.security.auth.WSSubject.doAsPrivileged 方法。
  • Java 2 Platform, Enterprise Edition(J2EE)资源授权检查的增强模型

    由于 JAAS V1.0 中的设计疏忽,javax.security.auth.Subject.getSubject 方法在 java.security.AccessController.doPrivileged 代码块中不返回与正在运行的线程相关联的主体集。此疏忽可能呈现出不一致的行为,这可能会导致意外的结果。com.ibm.websphere.security.auth.WSSubject 类提供了使主体集与正在运行的线程相关联的变通方法。com.ibm.websphere.security.auth.WSSubject 类将 JAAS 模型扩展到 Java 2 Platform, Enterprise Edition(J2EE)资源授权检查。如果主体集与 com.ibm.websphere.security.auth.WSSubject.doAs 方法中正在运行的线程相关联,或者com.ibm.websphere.security.auth.WSSubject.doAsPrivileged 代码块包含代码产品凭证,那么主体集用于 J2EE 资源授权检查。

  • 用于定义新的 JAAS 登录配置的用户界面支持
    可以在管理控制台中配置 JAAS 登录配置并将 JAAS 登录配置存储在配置库中。应用程序可在管理控制台中定义新的 JAAS 登录配置,并且数据持久保存在配置库中。但是,WebSphere Application Server 仍支持由 JAAS 缺省实现提供的缺省 JAAS 登录配置格式(纯文本文件)。如果配置库和纯文本文件格式中定义了重复的登录配置,那么存储库中的定义优先。在配置库中定义登录配置的优点包括:
    • 支持使用管理控制台来定义 JAAS 登录配置
    • 对 JAAS 登录配置进行集中管理
  • 支持应用程序进行程序化认证

    WebSphere Application Server 为应用程序提供 JAAS 登录配置,以便对 WebSphere 安全性运行时执行程序化认证。这些配置根据提供的认证数据对 WebSphere Application Server 已配置的认证机制(简单 WebSphere 认证机制(SWAM)或轻量级第三方认证(LTPA))和用户注册表(本地操作系统、轻量级目录访问协议或定制)执行认证。来自这些 JAAS 登录配置的已认证主体集包含 WebSphere 安全性运行时可以用来对 J2EE 基于角色的受保护资源执行授权检查的必需主体和凭证。

    以下是 WebSphere Application Server 提供的一些 JAAS 登录配置:
    • WSLogin JAAS 登录配置。一般 JAAS 登录配置可以使用 Java 客户机、客户机容器应用程序、servlet、JavaServer Pages(JSP)文件和 Enterprise JavaBeans(EJB)组件,根据用户标识和密码或到 WebSphere Application Server 安全性运行时的令牌执行认证。但是,此配置不支持在客户机容器部署描述符中指定的 CallbackHandler 处理程序。
    • ClientContainer JAAS 登录配置。此 JAAS 登录配置支持客户机容器部署描述符中指定的 CallbackHandler 处理程序。此登录配置的登录模块将使用客户机容器部署描述符中的 CallbackHandler 处理程序(如果指定了一个的话),即使应用程序代码在登录上下文中指定了一个回调处理程序。这适用于客户机容器应用程序。

      用前面提到的 JAAS 登录配置认证的主体集包含 com.ibm.websphere.security.auth.WSPrincipal 主体和 com.ibm.websphere.security.cred.WSCredential 凭证。如果在 com.ibm.websphere.security.auth.WSSubject.doAs 或其他 doAs 方法中传递已认证的主体集,那么产品安全性运行时可以根据 com.ibm.websphere.security.cred.WSCredential 主体集对 J2EE 资源执行授权检查。

  • 客户定义的 JAAS 登录配置

    可以定义其他 JAAS 登录配置来执行程序化登录,这将在客户机或服务器进程中创建定制主体集。主体集中需要某些凭证和主体,以便产品安全性运行时使用此主体集从客户机通过协议发送认证信息,或者使用它在服务器上处理授权。根据提供的登录模块生成必需凭证。

    纯 Java 客户机登录所需的登录模块如下所示:
    • com.ibm.ws.security.common.auth.module.WSLoginModuleImpl required;
    除了使用此登录模块之外,所使用的回调处理程序必须能够处理下列回调类。
    • javax.security.auth.callback.NameCallback
    • javax.security.auth.callback.PasswordCallback
    必须在回调处理程序中指定用户名和密码。只要启用了安全性属性传播,在客户端对主体集添加的定制类应该自动传播到服务器。有关对纯 Java 客户机启用传播的信息,请参阅 在应用程序服务器之间传播安全性属性 中的相应步骤。
    注: 对主体集添加的类必须是 Java Serializable 和 De-serializable,才能使这种情况正确发生。
    服务器登录所需的登录模块如下所示:
    • com.ibm.ws.security.server.lm.ltpaLoginModule required;
    • com.ibm.ws.security.server.lm.wsMapDefaultInboundLoginModule required;
    有关对服务器端登录配置使用的回调的信息,请参阅 定制服务器端 Java 认证和授权服务认证和登录配置 
  • 纯 Java 客户机上程序化登录的命名要求

    当程序化登录发生在纯 Java 客户机并且属性 com.ibm.CORBA.validateBasicAuth 等于 true 时,安全性代码必须知道 SecurityServer 驻留的位置。通常,当 java.naming.provider.url 属性设置为系统属性或在 jndi.properties 文件中设置了该属性时,缺省 InitialContext 是足够的。在其他情况下,不希望在系统范围作用域中设置相同的 java.naming.provider.url 属性。在这种情况下,需要在 sas.client.props 文件中指定特定于安全性的引导信息。以下步骤提供了确定如何在纯 Java 客户机中查找 SecurityServer 的优先顺序:

过程

  1. 使用 sas.client.props 文件和查找下列属性:
    com.ibm.CORBA.securityServerHost=myhost.mydomain
    com.ibm.CORBA.securityServerPort=mybootstrap port
    如果您指定这些属性,请确保安全性在此处查找 SecurityServer。指定的主机和端口可以代表任何有效的 WebSphere 主机和引导端口。SecurityServer 驻留在所有服务器进程上,因此您选择哪个主机或端口并不重要。如果指定了主机和端口,那么客户机进程内的安全性基础结构将基于 sas.client.props 文件中的信息查找 SecurityServer。
  2. 在您的客户机应用程序中放置下列代码以获取新的 InitialContext():
    ...
       import java.util.Hashtable;
      	import javax.naming.Context;
      	import javax.naming.InitialContext;
      	...
       
    // Perform an InitialContext and default lookup prior to logging 
    // in so that target realm and bootstrap host/port can be 
    // determined for SecurityServer lookup.
       
       			Hashtable env = new Hashtable();
       			env.put(Context.INITIAL_CONTEXT_FACTORY, 			"
                  com.ibm.websphere.naming.WsnInitialContextFactory");
       			env.put(Context.PROVIDER_URL, 			
                  "corbaloc:iiop:myhost.mycompany.com:2809");
       			Context initialContext = new InitialContext(env);
       			Object obj = initialContext.lookup("");
    
    			// programmatic login code goes here.
    
    在运行任何程序化登录之前完成此步骤。您正是在此代码中为您的命名上下文指定 URL 提供程序,但它必须指向您要认证的单元中的有效 WebSphere Application Server。指向一个单元允许特定于线程的程序化登录转至不同的单元以具有单个系统范围的 SecurityServer 位置。
  3. 根据命名优先权规则使用新的缺省 InitialContext() 方法。 这些规则在示例:获取缺省初始上下文 一文中定义。

示例

LoginContext lc = null;
	Subject subject = null;

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

try {          
lc.login(); 
		subject = lc.getSubject();
// setting the subject on the thread to use for outbound requests.            
// Note:  This overrides the existing subject which you might want to save first.      
	com.ibm.websphere.security.auth.WSSubject.setRunAsSubject(subject);
} catch (LoginException le) {
System.out.println("Fails to create Subject. " + le.getMessage());
 // Insert the error processing code
}

为 Java 认证和授权服务配置程序化登录

可使用管理控制台添加和修改新的 JAAS 登录配置。更改保存在单元级安全文档中,并且可供所有受管应用程序服务器使用。

在您开始之前

Java 认证和授权服务(JAAS)是 WebSphere Application Server 中的一项功能。JAAS 是 WebSphere Application Server 战略认证 API 集合,它替换了公共对象请求代理体系结构(CORBA)程序化登录 API。

WebSphere Application Server 提供了一些对 JAAS 的扩展:
  • com.ibm.websphere.security.auth.WSSubject。com.ibm.websphere.security.auth.WSSubject API 将 JAAS 授权模型扩展到 Java 2 Platform, Enterprise Edition(J2EE)资源。
  • 可以在管理控制台中配置 JAAS 登录并将此登录配置存储在 Application Server 配置中。但是,WebSphere Application Server 仍支持由 JAAS 缺省实现提供的缺省 JAAS 登录配置格式(纯文本文件)。如果在 WebSphere Application Server 配置 API 和纯文本文件格式中定义了重复的登录配置,那么优先使用在前者中定义的登录配置。在 WebSphere 配置 API 中定义登录配置的优点包括:
    • 支持使用用户界面来定义 JAAS 登录配置
    • 对 JAAS 登录配置进行集中管理
    由于 JAAS V1.0 中的设计疏忽,javax.security.auth.Subject.getSubject 方法在 java.security.AccessController.doPrivileged 代码块中不返回与正在运行的线程相关联的主体集。此问题表示存在不一致情况,这可能会引起不良结果。com.ibm.websphere.security.auth.WSSubject API 提供了使主体集与正在运行的线程相关联的变通方法。
  • 代理 LoginModule。代理 LoginModule 装入实际的 LoginModule 模块。缺省 JAAS 实现不使用线程上下文类装入器来装入类。如果 LoginModule 类文件不在应用程序类装入器或 Java 扩展类装入器类路径中,那么无法装入 LoginModule 模块。由于这个类装入器可视性问题,WebSphere Application Server 提供了代理 LoginModule 模块,以使用线程上下文类装入器来装入 JAAS LoginModule。不需要将 LoginModule 实现放入应用程序类装入器或者放入具有此代理 LoginModule 模块的 Java 扩展类装入器的类路径中。

    如果您不想使用代理 LoginModule 模块,那么可以将 LoginModule 模块放在 app_server_root/lib/ext/ 目录中。但是,由于安全风险问题,建议您不要这样做。

JAAS 登录配置是在 WebSphere Application Server 配置应用程序编程接口(API)安全性文档中定义的。单击安全性 > 全局安全性。在“认证”下,单击 JAAS 配置 > 应用程序登录。提供了下列 JAAS 登录配置:

ClientContainer
定义登录配置和 LoginModule 实现,这类似于 WSLogin 配置,但对 WebSphere Application Server 客户机容器有一些要求。有关更多信息,请参阅 Java 认证和授权服务的配置条目设置
DefaultPrincipalMapping
定义特殊的 LoginModule 模块,通常,J2EE 连接器使用该模块将已认证的 WebSphere Application Server 用户标识映射至指定后端企业信息系统(EIS)的一组用户认证数据(用户标识和密码)。有关 J2EE 连接器和 DefaultMappingModule 模块的更多信息,请参阅 J2EE 安全性部分。
WSLogin
定义通常可供应用程序使用的登录配置和 LoginModule 实现。

可使用管理控制台添加和修改新的 JAAS 登录配置。更改保存在单元级安全文档中,并且可供所有受管应用程序服务器使用。要使更改在运行时生效,需要重新启动应用程序服务器。

注意: 不要除去或删除预定义的 JAAS 登录配置(例如 ClientContainer、WSLogin 和 DefaultPrincipalMapping)。删除或除去它们会导致其他企业应用程序失败。

过程

  1. 删除 JAAS 登录配置。
    1. 单击安全性 > 全局安全性
    2. 在“认证”下,单击 JAAS 配置 > 应用程序登录。 这就显示了“应用程序登录配置”面板。
    3. 选中要删除的登录配置的复选框,然后单击删除
  2. 创建新的 JAAS 登录配置。
    1. 单击安全性 > 全局安全性
    2. 单击 JAAS 配置 > 应用程序登录
    3. 单击新建。 这就显示了“应用程序登录配置”面板。
    4. 指定新 JAAS 登录配置的别名,然后单击应用。 此值就是在 javax.security.auth.login.LoginContext 实现(用于创建新的 LoginContext 上下文)中传递的登录配置名。

      单击应用以保存更改并添加优先于原始别名的附加节点名。单击确定并不会将新的更改保存在 security.xml 文件中。

    5. 在“其他属性”下,单击 JAAS 登录模块
    6. 单击新建
    7. 指定模块类名。 由于类装入器可视性的限制,所以,请指定 WebSphere Application Server 代理 LoginModule 模块。
    8. 指定 LoginModule 实现作为代理 LoginModule 模块的代表属性。 WebSphere Application Server 代理 LoginModule 类名为 com.ibm.ws.security.common.auth.module.proxy.WSLoginModuleProxy。
    9. 从列表中选择认证策略,然后单击应用
    10. 在“其他属性”下,单击定制属性。 这就显示了所选 LoginModule 的“定制属性”面板。
    11. 创建名为 delegate 并且值为实际 LoginModule 实现的新属性。 可以指定其他属性,例如值为 true 的 debug。这些属性将作为 LoginModule 实例的 initialize 方法的选项传递给 LoginModule 类。
    12. 单击保存
    可以将 JAAS 登录模块放到 WebSphere Application Server 目录结构中的若干个位置中。以下列表按建议顺序提供了 JAAS 登录模块的位置:
    • 特定 Java 2 Platform, Enterprise Edition(J2EE)应用程序的企业归档(EAR)文件。

      如果将登录模块放在 EAR 文件中,那么该登录模块只能由特定应用程序访问。

    • WebSphere Application Server 共享库。

      如果将登录模块放在共享库中,那么必须指定可访问该模块的应用程序。有关共享库的更多信息,请参阅管理共享库

    • 在 Java 扩展 /QIBM/UserData/Java400/ext 目录中。

      如果将 JAAS 登录模块放在 Java 扩展目录中,那么该登录模块可供所有应用程序使用。

    虽然 Java 扩展目录为登录模块提供了最大程度的可用性,但是请将登录模块放在应用程序 EAR 文件中。如果其他应用程序需要访问同一个登录模块,那么考虑使用共享库。

  3. 更改明文文本文件。

    WebSphere Application Server 支持由 JAAS 缺省实现提供的缺省 JAAS 登录配置格式,即纯文本文件。但是,未提供用于编辑此格式纯文本文件的工具。可以在纯文本文件(app_server_root/properties/wsjaas.conf)中定义 JAAS 登录配置。任何语法错误都会导致不正确地解析纯文本 JAAS 登录配置文件。此问题可能会导致其他应用程序失败。

    必须在指定了 JAAS 配置文件的情况下调用使用 Java 认证和授权服务(JAAS)来进行认证的 Java 客户机程序。此配置文件是在  app_server_root/bin/launchClient.bat文件中设置的,如下所示:
    set JAAS_LOGIN_CONFIG=-Djava.security.auth.login.config=%install_root%\properties\wsjaas_client.conf
    如果未使用  launchClient.bat 文件来调用 Java 客户机程序,那么验证是否使用  -Djava.security.auth.login.config 标志将适当的 JAAS 配置文件传递给了 Java 虚拟机。

结果

创建了新的 JAAS 登录配置,或者除去了旧的 JAAS 登录配置。企业应用程序可使用新创建的 JAAS 登录配置,而不必重新启动应用程序服务器进程。

但是,app_server_root/properties/wsjaas.conf 文件中定义的新 JAAS 登录配置不会自动刷新。重新启动应用程序服务器以验证更改。这些 JAAS 登录配置特定于特定的节点,不可供其他节点上运行的其他应用程序服务器使用。

下一步做什么?

创建新的 JAAS 登录配置,企业应用程序将使用这些登录配置来执行定制认证。使用这些新定义的 JAAS 登录配置来执行程序化登录。

如示例中所示,新的登录上下文是使用 WSLogin 登录配置和 WSCallbackHandlerImpl 回调处理程序初始化的。在不需要提示的服务器端应用程序上使用 WSCallbackHandlerImpl 实例。WSCallbackHandlerImpl 是通过指定的用户标识、密码和域信息来初始化的。目前,由 WSLogin 登录配置指定的当前 WSLoginModuleImpl 类实现只能检索来自指定回调处理程序的认证信息。可使用主体集对象构造登录上下文,但是主体集会被当前的 WSLoginModuleImpl 实现所忽视。对于产品客户机容器应用程序,用 ClientContainer 登录配置(指定针对客户机容器要求而定制的 WSClientLoginModuleImpl 实现)替换 WSLogin 登录配置。

对于纯 Java 应用程序客户机,产品提供其他两个回调处理程序实现:WSStdinCallbackHandlerImpl 和 WSGUICallbackHandlerImpl,这两个实现将分别在命令行和弹出面板上提示输入用户标识、密码和域信息。可根据特定应用程序环境选择这两个产品回调处理程序实现中的任一个。如果这两个实现都不适合特定的应用程序要求,那么可以开发新的回调处理程序。

如果缺省 WSLoginModuleImpl 实现无法满足所有要求,也可以开发您自己的登录模块。此产品提供了可供定制登录模块使用的实用程序功能,这在下一部分中描述。

如果 java.naming.provider.url 属性未设置为系统属性,或者在 jndi.properties 文件中不存在该属性,那么当产品服务器不在 localhost:2809 位置时,缺省 InitialContext 上下文将无法正常工作。在这种情况下,应在 JAAS 登录前以编程方式构造新的 InitialContext 上下文。JAAS 需要知道安全服务器驻留在何处,以便在执行落实方法前验证输入的用户标识或密码是否正确。通过按下面指定的方法来构造新的 InitialContext 上下文,安全性代码就有了查找安全服务器位置和目标域所需要的信息。

注意: 以  env.put 开头的第一行已分割成了两行,这仅用于说明。
import java.util.Hashtable;
   import javax.naming.Context;
   import javax.naming.InitialContext;
   ...
   
// Perform an InitialContext and default lookup prior to logging in so that target realm
// and bootstrap host/port can be determined for SecurityServer lookup.
   
   Hashtable env = new Hashtable();
   env.put(Context.INITIAL_CONTEXT_FACTORY,
           "com.ibm.websphere.naming.WsnInitialContextFactory");
   env.put(Context.PROVIDER_URL, "corbaloc:iiop:myhost.mycompany.com:2809");
   Context initialContext = new InitialContext(env);
   Object obj = initialContext.lookup("");
   
    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 (LoginException le) {
         System.out.printlin("Fails to create Subject. " + le.getMessage());
          // Insert error processing code
    }




定制应用程序登录以执行身份声明

使用 Java 认证和授权服务(JAAS)登录框架,可创建用于执行登录至标识声明的 JAAS 登录配置。

在您开始之前

可允许应用程序或系统提供程序来执行带有信任验证的身份声明。为此,请使用 JAAS 登录框架,将在一个登录模块中完成信任验证,而在另一个模块中完成凭证创建。这两个定制登录模块允许您创建可用来执行登录到标识声明的 JAAS 登录配置。
需要两个定制登录模块:
用户实现的信任关联登录模块(信任验证)
用户实现的信任关联登录模块执行用户需要的任何信任验证。进行信任验证时,必须在登录模块处于共享状态时将信任验证状态与登录身份放置到一个图中,以使凭证创建登录模块可以使用该信息。此图应存储在属性中:

com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule.state
      (它包括如下项)

com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule.trusted
      (如果可信,那么设置为 true,如果不可信,那么设置为 false

com.ibm.wsspi.security.common.auth.module.IdenityAssertionLoginModule.principal 
       (包含身份的主体)

com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule.certificates
       (包含身份的证书)

身份声明登录模块(凭证创建)
com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule 执行凭证创建。此模块依赖于处于登录上下文共享状态的信任状态信息。此登录模块受下列各项的 Java 2 安全性运行时许可权保护:
  • com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule.initialize
  • com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule.login
身份声明登录模块查找共享状态属性 com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule.state 中的信任信息,该属性包含信任状态和要登录的身份,并且应包括:

com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule.trusted
       (为 true 时指示可信,为 false 时指示不可信)

com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule.principal 
       (包含要登录的身份的主体,如果使用主体的话)

com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule.certificates
       (包含一组证书链,而该证书链包含要登录的身份,如果使用证书的话)

如果缺少状态、信任或标识信息,那么会返回 WSLoginFailedException。然后,登录模块执行身份登录,并且该主题将包含新身份

过程

  1. 将信任验证委托给用户实现的插入点。 信任验证必须在定制登录模块中完成。此定制登录模块应执行必需的任何信任验证,然后在共享状态下设置要传递至身份声明登录模块的信任信息和身份信息。共享状态键 com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule.state 中需要一个图。如果缺少状态,那么 IdentityAssertionLoginModule 会抛出 WSLoginFailedException。此图必须包括:
    • 信任键 com.ibm.wsspi.secuirty.common.auth.module.IdentityAssertionLoginModule.trust。如果键设置为 true,那么会建立信任。如果键设置为 false 则不会建立信任。如果信任键未设置为 true,那么 IdentityAssertionLoginModule 将抛出 WSLoginFailedException。
    • • 设置身份键:可在 com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule.principal 键中设置 java.security.Principal。
    • 或者,可在 com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule.certficates 键中设置 java.security.cert.X509Certificate[]。
    如果同时提供了主体和证书,那么会使用主体并发出警告。
  2. 为应用程序登录创建新的 JAAS 配置 JAAS 配置将包含用户实现的信任验证定制模块和 IdentityAssertionLoginModule。接下来,为了配置应用程序登录配置,请在管理控制台上执行以下操作:
    1. 展开安全性 > 安全管理、应用程序和基础结构
    2. 展开 Java 认证和授权服务 > 应用程序登录
    3. 选择新建
    4. 对 JAAS 配置指定别名。
    5. 单击应用
    6. 选择 JAAS 登录模块
    7. 选择新建
    8. 输入用户实现的信任验证定制登录模块的模块类名
    9. 单击应用
    10. 输入 com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule 的模块类名
    11. 确保模块类名类的顺序正确。在列表中,用户实现的信任验证登录模块应该是第一个类,而 IdentityAssertionLoginModule 应该是第二个类。
    12. 单击保存
    应用程序将使用此 JAAS 配置来执行身份声明。
  3. 执行可编程身份声明。 现在,程序可以使用 JAAS 登录配置来执行程序化身份声明。应用程序可对第 2 步中创建的 JAAS 配置创建登录上下文,然后使用它们将声明的身份登录至该登录上下文。如果登录成功,就会在当前运行进程中设置该身份。以下是这类代码如何操作的示例:
    MyCallbackHandler handler = new MyCallbackHandler(new MyPrincipal(“Joe”));
    LoginContext lc = new LoginContext(“MyAppLoginConfig”, handler);
    lc.login();  //assume successful
    Subject s = lc.getSubject();
    WSSubject.setRunAsSubject(s);
    // From here on , the runas identity is “Joe”

结果

通过使用 JAAS 登录框架和两个用户实现的登录模块,可创建用于执行登录至身份声明的 JAAS 登录配置。

定制服务器端 Java 认证和授权服务认证和登录配置

WebSphere Application Server 支持将定制 Java 认证和授权服务(JAAS)登录模块插入到 WebSphere Application Server 系统登录模块之前或之后。然而,WebSphere Application Server 不支持替换 WebSphere Application Server 系统登录模块,这些模块用于创建主体集中的 WSCredential 凭证和 WSPrincipal 凭证。通过使用定制登录模块,您可以作出其他认证决策,也可以将信息添加到主体集中以便在 Java 2 Platform, Enterprise Edition(J2EE)应用程序中作出其他潜在的细粒度授权决策。

关于本任务

WebSphere Application Server 使您能传播由定制登录模块添加到主体集的信息下游。有关更多信息,请参阅安全性属性传播 。要确定插入定制登录模块时要使用的登录配置,请参阅Java 认证和授权服务的系统登录配置条目设置 中的登录配置描述。

WebSphere Application Server 支持通过管理控制台和使用 wsadmin 脚本编制实用程序修改系统登录配置。要使用管理控制台来配置系统登录配置,请单击安全性 > 全局安全性。在“认证”下,单击 JAAS 配置 > 系统登录

过程

  • 配置系统登录配置。

    请参阅以下使用 wsadmin 工具配置系统登录配置的代码样本。以下样本 Jacl 脚本将定制登录模块添加到轻量级第三方认证(LTPA)Web 系统登录配置中:

    注意: 在以下代码样本中,第 32、33 和 34 行分成了两行。
    1.	#########################################
    2.	#
    3.	# Open security.xml
    4.	#
    5.	#########################################
    6.	
    7.	
    8.	set sec [$AdminConfig getid /Cell:hillside/Security:/]
    9.	
    10.	
    11.	#########################################
    12.	#
    13.	# Locate systemLoginConfig
    14.	#
    15.	#########################################
    16.	
    17.	
    18.	set slc [$AdminConfig showAttribute $sec systemLoginConfig]
    19.	
    20.	set entries [lindex [$AdminConfig showAttribute $slc entries] 0]
    21.	
    22.	
    23.	#########################################
    24.	#
    25.	# Append a new LoginModule to LTPA_WEB
    26.	#
    27.	#########################################
    28.	
    29.	foreach entry $entries {
    30.	set alias [$AdminConfig showAttribute $entry alias]
    31.	if {$alias == "LTPA_WEB"} {
    32.	   set newJAASLoginModuleId [$AdminConfig create JAASLoginModule
            $entry {{moduleClassName
            "com.ibm.ws.security.common.auth.module.proxy.WSLoginModuleProxy"}}]
    33.	   set newPropertyId [$AdminConfig create Property
            $newJAASLoginModuleId {{name delegate}{value
            "com.ABC.security.auth.CustomLoginModule"}}]
    34.	   $AdminConfig modify $newJAASLoginModuleId
            {{authenticationStrategy REQUIRED}}
    35.	         break
    36.	   }
    37.	}
    38.	
    39.	
    40.	#########################################
    41.	#
    42.	# save the change
    43.	#
    44.	#########################################
    45.	
    46.	$AdminConfig save 47.	
    
    注意: wsadmin 脚本编制实用程序将新对象插入到列表末尾。要将定制登录模块插入到 AuthenLoginModule 登录模块前面,请删除 AuthenLoginModule 登录模块,然后在插入定制登录模块后重新创建它。将样本脚本保存到  sample.jacl 文件中,然后使用以下命令来运行样本脚本:
    wsadmin -f sample.jacl
  • 除去当前的 LTPA_WEB 登录配置和所有登录模块。
    可使用以下样本 Jacl 脚本来除去当前 LTPA_WEB 登录配置和所有登录模块:
    48.	#########################################
    49.	#
    50.	# Open security.xml
    51.	#
    52.	#########################################
    53.	
    54.	
    55.	set sec [$AdminConfig getid /Cell:hillside/Security:/]
    56.	
    57.	
    58.	#########################################
    59.	#
    60.	# Locate systemLoginConfig
    61.	#
    62.	#########################################
    63.	
    64.	
    65.	set slc [$AdminConfig showAttribute $sec systemLoginConfig]
    66.	
    67.	set entries [lindex [$AdminConfig showAttribute $slc entries] 0]
    68.	
    69.	
    70.	#########################################
    71.	#
    72.	# Remove the LTPA_WEB login configuration
    73.	#
    74.	#########################################
    75.	
    76.	foreach entry $entries {
    77.	   set alias [$AdminConfig showAttribute $entry alias]
    78.	   if {$alias == "LTPA_WEB"} {
    79.	      $AdminConfig remove $entry
    80.	      break
    81.	   }
    82.	}
    83.	
    84.	
    85.	#########################################
    86.	#
    87.	# save the change
    88.	#
    89.	#########################################
    90.	
    91.	$AdminConfig save 
  • 恢复原始 LTPA_WEB 配置。
    可使用以下样本 Jacl 脚本来恢复原始 LTPA_WEB 配置:
    注意: 在以下代码样本中,为了便于说明问题,第 122、124 和 126 行分成了两行或更多行。
    92.	#########################################
    93.	#
    94.	# Open security.xml
    95.	#
    96.	#########################################
    97.	
    98.	
    99.	set sec [$AdminConfig getid /Cell:hillside/Security:/]
    100.	
    101.	
    102.	#########################################
    103.	#
    104.	# Locate systemLoginConfig
    105.	#
    106.	#########################################
    107.	
    108.	
    109.	set slc [$AdminConfig showAttribute $sec systemLoginConfig]
    110.	
    111.	set entries [lindex [$AdminConfig showAttribute $slc entries] 0]
    112.	
    113.	                                                              
    114.	                                                                
    115.	#########################################
    116.	#
    117.	# Recreate the LTPA_WEB login configuration
    118.	#
    119.	#########################################
    120.	
    121.	
    122.	set newJAASConfigurationEntryId [$AdminConfig create JAASConfigurationEntry
         $slc {{alias LTPA_WEB}}]
    123.	
    124.	set newJAASLoginModuleId [$AdminConfig create JAASLoginModule
         $newJAASConfigurationEntryId
         {{moduleClassName
         "com.ibm.ws.security.common.auth.module.proxy.WSLoginModuleProxy"}}]
    125.	
    126.	set newPropertyId [$AdminConfig create Property
         $newJAASLoginModuleId {{name delegate}
         {value "com.ibm.ws.security.web.AuthenLoginModule"}}]
    127.	
    128.	$AdminConfig modify $newJAASLoginModuleId {{authenticationStrategy REQUIRED}}
    129.	
    130.	
    131.	#########################################
    132.	#
    133.	# save the change
    134.	#
    135.	#########################################
    136.	
    137.	$AdminConfig save 
  • 让 ltpaLoginModule 初始化登录方法中的回调数组。

    WebSphere Application Server 版本的 ltpaLoginModule 和 AuthenLoginModule 登录模块使用共享状态来保存状态信息,因此定制登录模块可以修改该信息。ltpaLoginModule 登录模块使用以下代码来初始化登录方法中的回调数组。仅当在共享状态区域中未定义数组时,ltpaLoginModule 登录模块才会创建回调数组。在以下代码样本中,已除去错误处理代码以使样本简明。如果在 ltpaLoginModule 前面插入定制登录模块,那么定制登录模块可能按照同一样式将回调保存到共享状态中。

    注意: 在以下代码样本中,为了便于说明问题,有几行代码分成了两行。
    138.	        Callback callbacks[] = null;
    139.	        if (!sharedState.containsKey(
                     com.ibm.wsspi.security.auth.callback.Constants.
                     CALLBACK_KEY)) {
    140.	            callbacks = new Callback[3];
    141.	            callbacks[0] = new NameCallback("Username: ");
    142.	            callbacks[1] = new PasswordCallback("Password: ", false);
    143.	            callbacks[2] = new com.ibm.websphere.security.auth.callback.
                     WSCredTokenCallbackImpl( "Credential Token: ");
    144.	            try {
    145.	                callbackHandler.handle(callbacks);
    146.	            } catch (java.io.IOException e) {
    147.	                . . .
    148.	           } catch (UnsupportedCallbackException uce) {
    149.	                . . .
    150.	           }
    151.	           sharedState.put(
                    com.ibm.wsspi.security.auth.callback.Constants.CALLBACK_KEY,
                    callbacks);
    152.	        } else {
    153.	            callbacks = (Callback [])
                     sharedState.get( com.ibm.wsspi.security.auth.callback.
                     Constants.CALLBACK_KEY);
    154.	        }
    
  • 让 AuthenLoginModule 初始化回调数组。

    ltpaLoginModule 和 AuthenLoginModule 登录模块都生成 WSPrincipal 对象和 WSCredential 对象来表示已认证的用户标识和安全凭证。WSPrincipal 和 WSCredential 对象也保存在共享声明中。JAAS 登录使用两阶段落实协议。

    首先,调用登录模块中在登录配置中配置的登录方法。然后,调用它们的落实方法。在 ltpaLoginModule 和 AuthenLoginModule 登录模块后面插入的定制登录模块可以在落实 WSPrincipal 和 WSCredential 对象之前修改它们。完成登录之后,WSCredential 和 WSPrincipal 对象必须存在于主体集中。如果主体集中没有这些对象,WebSphere Application Server 运行时代码就会拒绝该主体集以作出安全性决策。

    AuthenLoginModule 使用以下代码初始化回调数组:

    注意: 在以下代码样本中,为了便于说明问题,有几行代码分成了两行。
    155.	        Callback callbacks[] = null;
    156.	        if (!sharedState.containsKey(
                     com.ibm.wsspi.security.auth.callback.Constants.
                     CALLBACK_KEY)) {
    157.	            callbacks = new Callback[6];
    158.	            callbacks[0] = new NameCallback("Username: ");
    159.	            callbacks[1] = new PasswordCallback("Password: ", false);
    160.	            callbacks[2] =
                     new com.ibm.websphere.security.auth.callback.WSCredTokenCallbackImpl(
                     "Credential Token: ");			
    161.	            callbacks[3] =
                     new com.ibm.wsspi.security.auth.callback.WSServletRequestCallback(
                     "HttpServletRequest: ");
    162.	            callbacks[4] =
                     new com.ibm.wsspi.security.auth.callback.WSServletResponseCallback(
                     "HttpServletResponse: ");
    163.	            callbacks[5] =
                     new com.ibm.wsspi.security.auth.callback.WSAppContextCallback(
                     "ApplicationContextCallback: ");
    164.	            try {
    165.	                callbackHandler.handle(callbacks);
    166.	            } catch (java.io.IOException e) {
    167.	              . . .
    168.	            } catch (UnsupportedCallbackException uce {
    169.	              . . .
    170.	            }
    171.	            sharedState.put( com.ibm.wsspi.security.auth.callback.
                     Constants.CALLBACK_KEY, callbacks);
    172.	        } else {
    173.	            callbacks = (Callback []) sharedState.get(
                     com.ibm.wsspi.security.auth.callback.
                     Constants.CALLBACK_KEY);
    174.	        }
    
  • 获取应用程序上下文。

    另外又将三个对象从 Web 容器传递到 AuthenLoginModule 登录模块中,这些对象包含登录的回调信息:java.util.Map、HttpServletRequest 和 HttpServletResponse 对象。这些对象代表 Web 应用程序上下文。WebSphere Application Server V5.1 应用程序上下文(java.util.Map 对象)包含应用程序名和错误页面 Web 地址。可通过对 WSAppContextCallback 对象调用 getContext() 方法来获取应用程序上下文(java.util.Map 对象)。java.util.Map 对象是使用以下部署描述符信息创建的。

    注意: 在以下代码样本中,为了便于说明问题,有几行代码分成了两行。
    175.	       HashMap appContext = new HashMap(2);
    176.	       appContext.put(
                com.ibm.wsspi.security.auth.callback.Constants.WEB_APP_NAME,
                web_application_name);
    177.	       appContext.put(
                com.ibm.wsspi.security.auth.callback.Constants.REDIRECT_URL,
                errorPage);
    

示例

下一步做什么?

定制登录模块可以读取应用程序名和 HttpServletRequest 对象以执行映射功能。定制登录模块可以修改基于表单的登录的错误页面。除 JAAS 框架以外,WebSphere Application Server 还支持信任关联接口(TAI)。

在认证过程中,可以使用定制登录模块来将其他凭证类型和信息添加到调用者主体集。调用者主体集中的第三方凭证由 WebSphere Application Server 作为安全上下文的一部分管理。在处理请求期间,调用者主体集与正在运行的线程绑定。当将 Web 或 Enterprise JavaBeans(EJB)模块配置为使用调用者标识时,会将用户标识传播到 EJB 请求中的下游服务。不会将调用者主体集中的 WSCredential 凭证和任何第三方凭证向下游传播。一些信息可改为根据已传播的标识在目标服务器重新生成。将第三方凭证在认证阶段添加到调用者主体集。从 WSSubject.getCallerSubject 方法返回的调用者主体集是只读的,因而不能修改。有关 WSSubject 主体集的更多信息,请参阅“从线程获取调用者主体集的示例”。

启用带信任验证的标识声明

通过启用带信任验证的标识声明,应用程序可以使用 JAAS 登录配置来执行程序化标识声明。

关于本任务

要启用带信任验证的标识声明,请遵循以下步骤:

过程

  1. 创建定制登录模块以执行信任验证。 登录模块必须在在共享状态下设置信任和标识信息,然后将该信息传递到 IdentityAssertionLoginModule。信任和标识信息以共享状态存储在键 com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule.state 下的映射中。如果此键未处于共享状态,那么 IdentityAssertionLoginModule 模块会抛出 WSLoginFailedException 错误。定制登录模块应包括以下各项:
    • 名为 com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule.trust 的信任键。如果信任键设置为 true,那么会建立信任。如果信任键设置为 false,那么 IdentityAssertionLoginModule 模块会产生 WSLoginFailedException 错误。
    • 在 com.ibm.wsspi.security.common.auth.module.IdenityAssertionLoginModule.principal 键中设置的、类型为 java.security.Principal 的标识。
    • 在 com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule.certificates 键中设置的、格式为 java,security.cert.X509Certificate[] 证书的标识。
    注: 如果提供了主体和证书,那么会使用该主体,并发出一条警告。
  2. 为应用程序登录创建新的 Java 认证和授权服务(JAAS)配置。 它包含用户实现的信任验证定制登录模块和 IdentityAssertionLoginModule 模块。要从管理控制台配置应用程序登录配置,请完成以下步骤:
    1. 单击安全性 > 全局安全性 > JAAS 配置 > 应用程序登录
    2. 单击新建
    3. 在“Java 认证和授权服务”下,单击应用程序登录 > 新建
    4. 为 JAAS 配置提供一个别名,然后单击应用
    5. 在“其他属性”下,单击 JAAS 登录模块 > 新建
    6. 输入用户实现的信任验证定制登录模块的模块类名,然后单击应用
    7. 输入 com.ibm.wsspi.security.common.auth.module.IdentityAssertionLoginModule 模块类名。
    8. 确保模块类名类的顺序正确。用户实现的信任验证登录模块必须是列表中的第一个类,IdentityAssertionLoginModule 模块必须是第二个类。
    9. 单击保存。应用程序将使用新的 JAAS 配置执行标识声明。

下一步做什么?

应用程序现在可以使用 JAAS 登录配置来执行程序化标识声明。应用程序可以为步骤 2 中创建的 JAAS 配置创建登录上下文,然后使用此配置所声明的标识登录该登录上下文。如果登录成功,那么可以在当前运行的进程中设置该标识,如以下示例中所示:
MyCallbackHandler handler = new MyCallbackHandler(new MyPrincipal(“Joe”));
LoginContext lc = new LoginContext(“MyAppLoginConfig”, handler);
lc.login();  //assume successful
Subject s = lc.getSubject();
WSSubject.setRunAsSubject(s);
// From here on, the runas identity is “Joe”
 

你可能感兴趣的:(java)