开发带 Java 认证和授权服务的程序化登录
使用本主题开发带 Java™ 认证和授权服务的程序化登录
开始之前
JAAS 替换公共对象请求代理体系结构 (CORBA) 程序化登录应用程序编程接口 (API)。
- 请参阅有关开发使用 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 Platform, Enterprise Edition (Java EE) 资源授权检查的增强模型。
由于 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 Platform, Enterprise Edition (Java EE) 资源,以执行授权检查。如果主体集与 com.ibm.websphere.security.auth.WSSubject.doAs 方法中正在运行的线程相关联,或者 com.ibm.websphere.security.auth.WSSubject.doAsPrivileged 代码块包含代码产品凭证,那么主体集用于 Java EE 资源授权检查。
- 用于定义新的 JAAS 登录配置的用户界面支持。可以在管理控制台中配置 JAAS 登录配置并将 JAAS 登录配置存储在配置库中。应用程序可在管理控制台中定义新的 JAAS 登录配置,并且数据持久保存在配置库中。但是,WebSphere Application Server 仍支持由 JAAS 缺省实现提供的缺省 JAAS 登录配置格式(纯文本文件)。如果配置库和纯文本文件格式中定义了重复的登录配置,那么存储库中的定义优先。在配置库中定义登录配置的优点包括:
- 支持使用管理控制台来定义 JAAS 登录配置
- 对 JAAS 登录配置进行集中管理
- 分布 JAAS 登录配置
- 支持应用程序进行程序化认证。
WebSphere Application Server 为应用程序提供 JAAS 登录配置,以便对 WebSphere 安全性运行时执行程序化认证。这些配置根据提供的认证数据对 WebSphere Application Server 已配置的认证机制(简单 WebSphere 认证机制 (SWAM)、轻量级第三方认证 (LTPA))和用户注册表(本地操作系统、轻量级目录访问协议 (LDAP)、定制注册表或联合存储库)以及 Kerberos 认证执行认证。来自这些 JAAS 登录配置的已认证主体集包含 WebSphere 安全性运行时可以用来对 Java EE 基于角色的受保护资源执行授权检查的必需主体和凭证。
注: 在 WebSphere Application Server V9.0 中,不推荐使用 SWAM,在将来的发行版中将除去此认证机制。以下是 WebSphere Application Server 提供的一些 JAAS 登录配置:- WSLogin JAAS 登录配置。一般 JAAS 登录配置可以使用 Java 客户机、客户机容器应用程序、Servlet、JavaServer Pages (JSP) 文件和 Enterprise JavaBeans (EJB) 组件,根据用户标识和密码或到 WebSphere Application Server 安全性运行时的令牌执行认证。但是,此配置不支持在客户机容器部署描述符中指定的 CallbackHandler 处理程序。
- WSKRB5Login 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 主体集对 Java EE 资源执行授权检查。
- 客户定义的 JAAS 登录配置。
可以定义其他 JAAS 登录配置来执行程序化登录,这将在客户机或服务器进程中创建定制主体集。主体集中需要某些凭证和主体,以便产品安全性运行时使用此主体集从客户机通过协议发送认证信息,或者使用它在服务器上处理授权。根据提供的登录模块生成必需凭证。
纯 Java 客户机登录所需的登录模块如下所示:- com.ibm.ws.security.common.auth.module.WSLoginModuleImpl required;
- javax.security.auth.callback.NameCallback
- javax.security.auth.callback.PasswordCallback
有关对纯 Java 客户机启用传播的信息,请参阅在应用程序服务器之间传播安全性属性中的相应步骤。注: 对主体集添加的类必须可由 Java 序列化和反序列化,才能使这种情况正确发生。服务器登录所需的登录模块如下所示:- com.ibm.ws.security.server.lm.ltpaLoginModule required;
- com.ibm.ws.security.server.lm.wsMapDefaultInboundLoginModule required;
- 纯 Java 客户机上程序化登录的命名要求。
当程序化登录发生在纯 Java 客户机并且属性 com.ibm.CORBA.validateBasicAuth 等于 true 时,安全性代码必须知道 SecurityServer 所在的位置。通常,当 java.naming.provider.url 属性设置为系统属性或在 jndi.properties 文件中设置了该属性时,缺省 InitialContext 是足够的。在其他情况下,不希望在系统范围范围中设置相同的 java.naming.provider.url 属性。在这种情况下,需要在 sas.client.props 文件中指定特定于安全性的引导信息。以下步骤提供了确定如何在纯 Java 客户机中查找 SecurityServer 的优先顺序:
过程
示例:使用 BasicAuth 执行程序化登录
此示例说明了应用程序可以使用 BasicAuth 执行程序化登录的方式。
添加带有 Kerberos 令牌的程序化登录:
LoginContext lc = null;
try {
lc = new LoginContext("WSKRB5Login",
new WSCallbackHandlerImpl("userName", "password"));
} catch (LoginException le) {
System.out.println("Cannot create LoginContext. " + le.getMessage());
// Insert the error processing code
} catch(SecurityException se) {
System.out.println("Cannot create LoginContext." + se.getMessage());
// Insert the error processing code
}
try {
lc.login();
} catch(LoginException le) {
System.out.println("Fails to create Subject. " + le.getMessage());
// Insert the error processing code
如示例中所示,新的登录上下文是使用 WSKRB5Login 登录配置和 WSCallbackHandlerImpl 回调处理程序初始化的。在不需要提示的服务器端应用程序上使用 WSCallbackHandlerImpl 实例。WSCallbackHandlerImpl 实例是通过指定的用户标识、密码和领域信息来初始化的。由 WSKRB5Login 登录配置指定的当前 Krb5LoginModuleWrapperClient 类实现只能检索来自指定回调处理程序的认证信息。可使用主体集对象构造登录上下文,但是主体集会被当前的 Krb5LoginModuleWrapperClient 实现所忽视。
对于纯 Java 应用程序客户机,产品提供其他两个回调处理程序实现:WSStdinCallbackHandlerImpl 和 WSGUICallbackHandlerImpl,这两个实现将分别在命令行和弹出面板上提示输入用户标识、密码和领域信息。可根据特定应用程序环境选择这两个产品回调处理程序实现中的任一个。如果这两个实现都不适合特定的应用程序要求,那么可以开发新的回调处理程序。
还有其他可与 WSKRB5Login、WSAuthMechOidCallbackImpl 和 WSCcacheCallBackHandlerImpl 配合使用的回调。WSAuthMechOidCallbackImpl 允许您指定认证机制 OID,Kerberos 认证机制 OID 的值为“1.2.840.113554.1.2.2”。WSCcacheCallBackHandlerImpl 允许您指定用户名、Kerberos 域名、Kerberos 凭证高速缓存完整路径以及是否要使用 Kerberos 凭证高速缓存的缺省位置。如果选择使用 Kerberos 凭证高速缓存的缺省位置,那么将忽略 Kerberos 凭证高速缓存。如果您使用 Kerberos 进行认证,那么必须更新 sas.client.props 文件。
如果缺省 WSLoginModuleImpl 实现无法满足所有要求,也可以开发您自己的登录模块。此产品提供了可供定制登录模块使用的实用程序功能,这在下一部分中描述。
如果 java.naming.provider.url 属性未设置为系统属性,或者在 jndi.properties 文件中不存在该属性,那么当产品服务器不在 localhost:2809 位置时,缺省 InitialContext 上下文将无法正常工作。在这种情况下,应在 JAAS 登录前以编程方式构造新的 InitialContext 上下文。JAAS 需要知道安全服务器驻留在何处,以便在执行落实方法前验证输入的用户标识或密码是否正确。通过按本主题后续部分指定的方法来构造新的 InitialContext 上下文,安全性代码就有了查找安全服务器位置和目标域所需要的信息。
如果 java.naming.provider.url 属性未设置为系统属性,或者在 jndi.properties 文件中不存在该属性,那么当产品服务器不在 sever_name:2809 位置时,缺省 InitialContext 上下文将无法正常工作。在这种情况下,应在 JAAS 登录前以编程方式构造新的 InitialContext 上下文。JAAS 需要知道安全服务器驻留在何处,以便在执行落实方法前验证输入的用户标识或密码是否正确。通过按本主题后续部分指定的方法来构造新的 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("");
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
}