Liberty 中的安全性公用 API
Liberty 中的安全性公用 API 提供了一种扩展安全性基础结构的方法。
Liberty 包含可用来实现安全性功能的公用 API。Liberty 中的安全性公用 API 是 WebSphere® Application Server 传统版安全性公用 API 的子集。主要类是 WSSecurityHelper、WSSubject 和 RegistryHelper。这些类包含 WebSphere Application Server 传统版中可用的方法的子集。此外,还有一个新类 WebSecurityHelper。
下列部分描述了这些主要类。还有其他类,例如 UserRegistry、WSCredential 和其他异常类。
Liberty 支持的所有安全性公用 API 都在 Java™ API 文档中。在 ${wlp.install.dir}/dev 目录的某个 Javadoc 子目录中的一个独立 .zip 文件内,提供了每个 Liberty API 的 Java API 文档。
- WSSecurityHelper
- 此类仅包含方法 isServerSecurityEnabled() 和 isGlobalSecurityEnabled()。此外,如果启用了 appSecurity-2.0 或 zosSecurity-1.0,那么这些调用返回 true。否则,这两个方法都将返回 false。从WebSphere Application Server 传统版 WSSecurityHelper 类执行这两个方法以确保兼容性。
- 注:
- Liberty 中没有单元,因此 Liberty 在全局安全性和服务器安全性之间没有差别。因此,这两个方法返回相同的值。
- 方法 revokeSSOCookies(javax.servlet.http.HttpServletRequest req,javax.servlet.http.HttpServletResponse res) 在 Liberty 中不受支持。可以改用 Servlet 3.0 注销函数。
- 方法 getLTPACookieFromSSOToken() 将重命名为新的公用 API 类:WebSecurityHelper。
- WSSubject
- 此类提供实用程序方法来查询和设置安全性线程上下文。Liberty 支持WebSphere Application Server 传统版 WSSubject 中的所有方法。注: Java 2 安全性在 Liberty 中受支持,但缺省情况下未启用。所以,在缺省情况下,不会在 WSSubject 中执行 Java 2 安全性检查。
- RegistryHelper
- 此类提供对 UserRegistry 对象及可信域信息的访问权。在 Liberty 中,它包含下列WebSphere Application Server 传统版方法子集:
- 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)
- 注: 此方法涉及可能会随 OSGI 动态服务更改而更改的动态信息。检索到的值可能会变得过时。永远不应对 UserRegistry 引用进行高速缓存。
- WebSecurityHelper
- 此类包含重命名的 getLTPACookieFromSSOToken() 方法,该方法已从 WSSecurityHelper 中移出:
- public static Cookie getSSOCookieFromSSOToken() throws Exception
- PasswordUtil
- 这个类提供用于保护敏感信息的编码和解码方法。要将这个类作为 API 启用,请在 server.xml
文件中配置 passwordUtilities-1.0 功能部件。注: 这个类还存在于WebSphere Application Server 传统版中。但是,Liberty 添加了更多引入额外方法的功能。
安全性公用 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; } } } }