Java 认证和授权服务授权
Java™ 2 安全性体系结构使用安全策略以指定将哪些访问权授权给运行代码。此体系结构以代码为中心。根据代码特征授权许可权,这些代码特征包括代码从何而来、它是否被数字签名以及是谁的签名。Java 认证和授权服务 (JAAS) 的授权使用新的以用户为中心的访问控制来扩大现有以代码为中心的访问控制。根据什么代码正在运行以及谁在运行它来授权许可权。
使用 JAAS 认证方法来认证用户时,将创建一个主体集以表示已认证的用户。主体集包含一组主体,其中的每个主体都代表该用户的身份。您可以通过策略将许可权授予特定主体。认证用户之后,应用程序可以将主体集和当前访问控制上下文关联。对于每个后续的安全性检查的操作,Java 运行时会自动确定该策略是否将必需的许可权仅授权给特定的主体。如果这样,仅当与访问控制上下文关联的主体集包含指定的主体时才支持此操作。
通过从主体集类中调用静态 doAs 方法,并将已认证的主体集和 java.security.PrivilegedAction 或 java.security.PrivilegedExceptionAction 方法传递到该方法,将主体集与当前的访问控制上下文关联。doAs 方法将提供的主体集与当前的访问控制上下文相关联,然后从操作中调用运行方法。该运行方法实现包含所有作为指定主体集而运行的代码。此操作作为指定主体集运行。
在 Java 2 Platform, Enterprise Edition (J2EE) 编程模型中,当从企业 Bean 或 servlet 调用 Enterprise JavaBeans (EJB) 方法时,该方法在由 run-as 设置所确定的用户标识下运行。J2EE V1.4 规范不会表明当从 EJB 代码或 Servlet 代码中的 Subject.doAs 操作块调用企业 Bean 时,使用哪个用户标识。调用 Subject doAs 操作块中的 EJB 方法时,逻辑扩展名将使用主体集中指定的正确标识。
让 Subject.doAs 覆盖 run-as 标识设置是将 JAAS 编程模型与 J2EE 运行时环境集成的理想方法。但是,当 JAAS V1.0 或更高版本实现与 Java 2 安全性体系结构集成时,JAAS 引入了一个问题到 Software Development Kit (SDK)、Java Technology Edition V1.3 或更高版本。当在 Subject.doAs 操作块中发生 doPrivileged 调用时,doPrivileged 调用会切断与访问控制上下文关联的主体集。直到更正此问题之后,可靠的和运行时有效方法才可用于保证 J2EE 运行时环境中的 Subject.doAs 操作的正确行为。
Subject.doAs(subject, new java.security.PrivilegedAction() {
Public Object run() {
// Subject is associated with the current thread context
java.security.AccessController.doPrivileged( new
java.security.PrivilegedAction() {
public Object run() {
// Subject was cut off from the current
// thread context
return null;
}
});
// Subject is associated with the current thread context
return null;
}
});
要解决此困难,WebSphere® Application Server 会提供 WSSubject helper 类,以将 JAAS 授权扩展到 J2EE EJB 方法调用(如先前所述)。WSSubject 类提供具有与主体集类等同特征符的静态 doAs 和 doAsPrivileged 方法。WSSubject.doAs 方法将 Subject 与当前运行的线程关联。接着,WSSubject.doAs 和 WSSubject.doAsPrivileged 方法调用相应的 Subject.doAs 和 Subject.doAsPrivileged 方法。会复原原始凭证,并且根据保留的 WSSubject.doAs 和 WSSubject.doAsPrivileged 方法,将该凭证与运行线程关联。
WSSubject 类不是主体集对象的替换而是 helper 类,只要进行 EJB 方法调用,它就用于确保一致的运行时行为。
WSSubject.doAs(subject, new java.security.PrivilegedAction() {
Public Object run() {
// Subject is associated with the current thread context
java.security.AccessController.doPrivileged( new
java.security.PrivilegedAction() {
public Object run() {
// Subject was cut off from the current thread
// context.
return null;
}
});
// Subject is associated with the current thread context
return null;
}
});
- 由 WSLoginModuleImpl 实例和 WSClientLoginModuleImpl 实例生成的主体集对象包含实现 WSPrincipal 接口的主体。为 WSPrincipal 对象使用 getCredential 方法返回一个实现 WSCredential 接口的对象。您还可以在主体集实例的 PublicCredentials 列表中找到 WSCredential 对象实例。从 PublicCredentials 列表而不是使用 getCredential 方法来检索 WSCredential 对象。
- WSSubject 类的 getCallerPrincipal 方法返回一个表示调用者安全身份的字符串。返回类型与 java.security.Principal EJBContext 接口的 getCallerPrincipal 方法不同。
- Java 2 连接器 (J2C) DefaultPrincipalMapping 模块生成的主体集对象包含资源主体和 PasswordCredentials 列表。资源主体表示运行方式标识。