安全性公共 API
Liberty 概要文件中的安全性公用 API 提供了一种扩展安全性基础结构的方法。
Liberty 概要文件包含可用来实现安全性功能的公用 API。Liberty 概要文件中的安全性公用 API 是 完整概要文件 安全性公用 API 的子集。主要类是 WSSecurityHelper、WSSubject 和 RegistryHelper。这些类包含完整概要文件版本中所提供方法的子集。此外,还有一个新类 WebSecurityHelper。
下列部分描述了这些主要类。还有其他类,例如 UserRegistry、WSCredential 和其他异常类。
Liberty 概要文件支持的所有安全性公用 API 都在 Java™ API 文档中。每个 Liberty 概要文件 API 的 Java API 文档均在信息中心中的编程接口 (API) 部分进行详细说明,而且还可以在 ${wlp.install.dir}/dev 目录的其中一个 javadoc 子目录下的单独 .zip 文件中找到。
- WSSecurityHelper
- 此类仅包含方法 isServerSecurityEnabled() 和 isGlobalSecurityEnabled()。如果在 server.xml 文件中启用了下列任一功能部件,那么这两个方法都将返回 true:
- appSecurity-2.0
- zosSecurity-1.0
- 注:
- Liberty 概要文件中没有单元,所以 Liberty 概要文件在全局安全性和服务器安全性之间没有差别。因此这两个方法返回相同的值。
- Liberty 概要文件中不支持方法 revokeSSOCookies(javax.servlet.http.HttpServletRequest req,javax.servlet.http.HttpServletResponse res)。可以改用 Servlet 3.0 注销函数。
- getLTPACookieFromSSOToken() 方法已重命名为新的公用 API 类:WebSecurityHelper。
- WSSubject
- 此类提供实用程序方法来查询和设置安全性线程上下文。Liberty 概要文件支持完整概要文件 WSSubject 中的所有方法。注: Java 2 安全性在 Liberty 概要文件中受支持,但缺省情况下未启用。所以,在缺省情况下,不会在 WSSubject 中执行 Java 2 安全性检查。
- RegistryHelper
- 此类提供对 UserRegistry 对象和可信域信息的访问。在 Liberty 概要文件中,它包含下列完整概要文件方法的子集:
- public static UserRegistry getUserRegistry(String realmName) throws WSSecurityException
- public static List<String> getInboundTrustedRealms(String realmName) throws WSSecurityException
- public static boolean isRealmInboundTrusted(String inboundRealm, String localRealm)
- WebSecurityHelper
- 此类包含重命名的 getLTPACookieFromSSOToken() 方法,该方法已从 WSSecurityHelper 中移出:
- public static Cookie getLTPACookieFromSSOToken() throws Exception
安全性公用 API 代码示例
以下示例说明如何在 Liberty 概要文件中使用安全性公用 API 来执行程序化登录并操作主体集。
- 示例 1:创建主体集并将其用于授权
- 此示例说明如何使用 WSSecurityHelper、WSSubject 和 UserRegistry 来执行程序化登录以创建 Java 主体集,然后执行操作并将该主体集用于任何需要的授权。注: 下列代码在执行进一步的安全处理之前使用 WSSecurityHelper 来检查是否启用了安全性。此检查由于 Liberty 概要文件的模块化性质而得到广泛使用:如果未启用安全性,那么不会装入安全性运行时。WSSecurityHelper 总是会装入,即使安全性并未启用也是如此。
import java.rmi.RemoteException; import java.security.PrivilegedAction; import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import com.ibm.websphere.security.CustomRegistryException; import com.ibm.websphere.security.UserRegistry; import com.ibm.websphere.security.WSSecurityException; import com.ibm.websphere.security.WSSecurityHelper; import com.ibm.websphere.security.auth.WSSubject; import com.ibm.websphere.security.auth.callback.WSCallbackHandlerImpl; import com.ibm.wsspi.security.registry.RegistryHelper; public class myServlet { ... if (WSSecurityHelper.isServerSecurityEnabled()) { UserRegistry ur = null; try { ur = RegistryHelper.getUserRegistry(null); } catch (WSSecurityException e1) { // record some diagnostic info return; } String userid = "user1"; String password = "user1password"; try { if (ur.isValidUser(userid)) { // create a Subject, authenticating with // a userid and password CallbackHandler wscbh = new WSCallbackHandlerImpl(userid, password); LoginContext ctx; ctx = new LoginContext("WSLogin", wscbh); ctx.login(); Subject subject = ctx.getSubject(); // Perform an action using the Subject for // any required authorization WSSubject.doAs(subject, action); } } catch (CustomRegistryException e) { // record some diagnostic info return; } catch (RemoteException e) { // record some diagnostic info return; } catch (LoginException e) { // record some diagnostic info return; } } ... private final PrivilegedAction action = new PrivilegedAction() { @Override public Object run() { // do something useful here return null; } }; }
- 示例 2:创建主体集并使其成为线程上的当前主体集
- 以下示例说明如何使用 WSSecurityHelper 和 WSSubject 来执行程序化登录以创建 Java 主体集,使该主体集成为线程上的当前主体集,最后复原原始安全性线程上下文。注: 下列代码在执行进一步的安全处理之前使用 WSSecurityHelper 来检查是否启用了安全性。
import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import com.ibm.websphere.security.WSSecurityException; import com.ibm.websphere.security.WSSecurityHelper; import com.ibm.websphere.security.auth.WSSubject; import com.ibm.websphere.security.auth.callback.WSCallbackHandlerImpl; ... if (WSSecurityHelper.isServerSecurityEnabled()) { CallbackHandler wscbh = new WSCallbackHandlerImpl("user1", "user1password"); LoginContext ctx; try { // create a Subject, authenticating with // a userid and password ctx = new LoginContext("WSLogin", wscbh); ctx.login(); Subject mySubject = ctx.getSubject(); Subject oldSubject = null; try { // Save a ref to the current Subject on the thread oldSubject = WSSubject.getRunAsSubject(); // Make mySubject the current Subject on the thread WSSubject.setRunAsSubject(mySubject); // Do something useful here. Any authorization // required will be performed using mySubject } catch (WSSecurityException e) { // record some diagnostic info return; } finally { // Put the original Subject back on the thread context if (oldSubject != null) { try { WSSubject.setRunAsSubject(oldSubject); } catch (WSSecurityException e) { // record some diagnostic info } } } } catch (LoginException e) { // record some diagnostic info return; } }
- 示例 3:获取线程上当前主体集的信息
- 以下示例说明如何使用 WSSecurityHelper、WSSubject 和 WSCredential 来获取有关线程上当前主体集的信息。注: 下列代码在执行进一步的安全处理之前使用 WSSecurityHelper 来检查是否启用了安全性。
import java.util.ArrayList; import java.util.Iterator; import java.util.Set; import javax.security.auth.Subject; import javax.security.auth.login.CredentialExpiredException; import com.ibm.websphere.security.WSSecurityException; import com.ibm.websphere.security.WSSecurityHelper; import com.ibm.websphere.security.auth.CredentialDestroyedException; import com.ibm.websphere.security.auth.WSSubject; import com.ibm.websphere.security.cred.WSCredential; ... if (WSSecurityHelper.isServerSecurityEnabled()) { // Get the caller's subject Subject callerSubject; try { callerSubject = WSSubject.getCallerSubject(); } catch (WSSecurityException e) { // record some diagnostic info return; } WSCredential wsCred = null; Set<WSCredential> wsCredentials = callerSubject.getPublicCredentials(WSCredential.class); Iterator<WSCredential> wsCredentialsIterator = wsCredentials.iterator(); if (wsCredentialsIterator.hasNext()) { wsCred = wsCredentialsIterator.next(); try { // Print out the groups ArrayList<String> groups = wsCred.getGroupIds(); for (String group : groups) { System.out.println("Group name: " + group); } } catch (CredentialExpiredException e) { // record some diagnostic info return; } catch (CredentialDestroyedException e) { // record some diagnostic info return; } } } }