使用已配置的 JAAS 主题来验证 HttpURLConnection?
Using a configured JAAS subject to authenticate a HttpURLConnection?
过去有几次,我不得不在 WebSphere Application Server 上的应用 运行 中建立经过身份验证的 HTTP 或 HTTPS 连接。
我通常创建了一些自定义的方式来存储连接的用户名和密码 - 使用文本或 XML 文件,或者为了测试,只是 hard-coding - 并将这些详细信息添加到授权 header 在 HttpURLConnection 中,执行 HTTP 基本身份验证。
我最近考虑到 WAS Integrated Solutions Console 有一种配置用户名和密码的方法(在安全 -> Java 身份验证和授权服务 -> J2C 身份验证数据下),这很有意义使用 built-in 功能(如果可能),而不是总是以自定义方式执行此操作,但我在搜索了大约一个小时后仍无法弄清楚如何执行此操作。
那么,有人知道是否可以使用配置的 WAS J2C 身份验证数据来验证任意 HTTP 或 HTTPS 连接吗?
我认为它需要 WebSphere API 才能:
- 通过别名检索表示 J2C 身份验证条目的 object;和
- 执行以下操作之一:
- 从 JAAS/J2C object;
获取经过身份验证的 HttpURLConnection 或 HttpsURLConnection object
- 获取 plain-text 用户名和密码,以便将它们添加到授权中 header;或者
- 如果连接到同一域中的 IBM 平台:从 JAAS/J2C object 获取 LTPA 令牌,然后可以将其添加到连接中的 cookie。
此外:如果 Apache HttpClient 能让这一切变得更容易,我可以使用它,但仍然需要适当的 WebSphere API。
我找到了一个可能对 WebSphere Portal (com.ibm.wps.portletservice.credentialvault.credentials.LtpaTokenCredential
) 有用的 class,但我需要在 non-Portal 环境中执行此操作,因此我无法使用任何 Portal-specific classes 或接口。
我还需要它至少在以下类型的应用程序中工作:Servlet 和 WebSphere 信任关联拦截器。
我刚刚在 servlet 中尝试了以下 (Modified from here),它成功地获取了 auth 别名 user/pwd。
import com.ibm.websphere.security.NotImplementedException;
import com.ibm.wsspi.security.auth.callback.Constants;
import com.ibm.wsspi.security.auth.callback.WSMappingCallbackHandlerFactory;
import javax.resource.spi.security.PasswordCredential;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
Map map = new HashMap();
map.put(Constants.MAPPING_ALIAS, "REPLACE_WITH_YOUR_AUTH_ALIAS");
CallbackHandler callbackHandler = null;
try {
callbackHandler = WSMappingCallbackHandlerFactory.getInstance().getCallbackHandler(map, null);
} catch (NotImplementedException e) {
}
LoginContext loginContext = null;
try {
loginContext = new LoginContext("DefaultPrincipalMapping", callbackHandler);
loginContext.login();
} catch (LoginException e) {
}
Subject subject = loginContext.getSubject();
Set credentials = subject.getPrivateCredentials();
PasswordCredential passwordCredential = (PasswordCredential) credentials.iterator().next();
String user = passwordCredential.getUserName();
String password = new String(passwordCredential.getPassword());
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<h1>User: " + user + " --- Password: " + password+"</h1>");
如果身份验证是在 WAS 服务器之间进行的,则无需费力;只要参与的 WAS 服务器构成同一安全域的一部分并相互信任,LTPA 令牌就足够了。
如果你的想法是从非WAS服务器转到WAS服务器,你可以看看TAI选项,但你仍然不需要使用Authentication Aliases。
当我们从一项服务向下游服务进行身份验证时,我们只需传入 LTPA 令牌,如下所示(LTPA 令牌不是 Portal 的东西,它是 WAS 的东西)。假设有人已经在您的服务上进行了身份验证,例如从 Portal 或 WAS 登录,我们想调用另一台 WAS 服务器上的下游 REST 服务。
/** For call to a REST client, use apache wink that comes with WAS:
* This method shows how to pass in the available LTPA token to create
* a RestClient
private org.apache.wink.client.RestClient getRestClient() {
if (restClient == null) {
org.apache.wink.client.ClientConfig config = new ClientConfig();
config.handlers(new org.apache.wink.client.handlers.LtpaAuthSecurityHandler());
restClient = new RestClient(config);
}
return restClient;
}
过去有几次,我不得不在 WebSphere Application Server 上的应用 运行 中建立经过身份验证的 HTTP 或 HTTPS 连接。
我通常创建了一些自定义的方式来存储连接的用户名和密码 - 使用文本或 XML 文件,或者为了测试,只是 hard-coding - 并将这些详细信息添加到授权 header 在 HttpURLConnection 中,执行 HTTP 基本身份验证。
我最近考虑到 WAS Integrated Solutions Console 有一种配置用户名和密码的方法(在安全 -> Java 身份验证和授权服务 -> J2C 身份验证数据下),这很有意义使用 built-in 功能(如果可能),而不是总是以自定义方式执行此操作,但我在搜索了大约一个小时后仍无法弄清楚如何执行此操作。
那么,有人知道是否可以使用配置的 WAS J2C 身份验证数据来验证任意 HTTP 或 HTTPS 连接吗?
我认为它需要 WebSphere API 才能:
- 通过别名检索表示 J2C 身份验证条目的 object;和
- 执行以下操作之一:
- 从 JAAS/J2C object; 获取经过身份验证的 HttpURLConnection 或 HttpsURLConnection object
- 获取 plain-text 用户名和密码,以便将它们添加到授权中 header;或者
- 如果连接到同一域中的 IBM 平台:从 JAAS/J2C object 获取 LTPA 令牌,然后可以将其添加到连接中的 cookie。
此外:如果 Apache HttpClient 能让这一切变得更容易,我可以使用它,但仍然需要适当的 WebSphere API。
我找到了一个可能对 WebSphere Portal (com.ibm.wps.portletservice.credentialvault.credentials.LtpaTokenCredential
) 有用的 class,但我需要在 non-Portal 环境中执行此操作,因此我无法使用任何 Portal-specific classes 或接口。
我还需要它至少在以下类型的应用程序中工作:Servlet 和 WebSphere 信任关联拦截器。
我刚刚在 servlet 中尝试了以下 (Modified from here),它成功地获取了 auth 别名 user/pwd。
import com.ibm.websphere.security.NotImplementedException;
import com.ibm.wsspi.security.auth.callback.Constants;
import com.ibm.wsspi.security.auth.callback.WSMappingCallbackHandlerFactory;
import javax.resource.spi.security.PasswordCredential;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
Map map = new HashMap();
map.put(Constants.MAPPING_ALIAS, "REPLACE_WITH_YOUR_AUTH_ALIAS");
CallbackHandler callbackHandler = null;
try {
callbackHandler = WSMappingCallbackHandlerFactory.getInstance().getCallbackHandler(map, null);
} catch (NotImplementedException e) {
}
LoginContext loginContext = null;
try {
loginContext = new LoginContext("DefaultPrincipalMapping", callbackHandler);
loginContext.login();
} catch (LoginException e) {
}
Subject subject = loginContext.getSubject();
Set credentials = subject.getPrivateCredentials();
PasswordCredential passwordCredential = (PasswordCredential) credentials.iterator().next();
String user = passwordCredential.getUserName();
String password = new String(passwordCredential.getPassword());
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<h1>User: " + user + " --- Password: " + password+"</h1>");
如果身份验证是在 WAS 服务器之间进行的,则无需费力;只要参与的 WAS 服务器构成同一安全域的一部分并相互信任,LTPA 令牌就足够了。
如果你的想法是从非WAS服务器转到WAS服务器,你可以看看TAI选项,但你仍然不需要使用Authentication Aliases。
当我们从一项服务向下游服务进行身份验证时,我们只需传入 LTPA 令牌,如下所示(LTPA 令牌不是 Portal 的东西,它是 WAS 的东西)。假设有人已经在您的服务上进行了身份验证,例如从 Portal 或 WAS 登录,我们想调用另一台 WAS 服务器上的下游 REST 服务。
/** For call to a REST client, use apache wink that comes with WAS:
* This method shows how to pass in the available LTPA token to create
* a RestClient
private org.apache.wink.client.RestClient getRestClient() {
if (restClient == null) {
org.apache.wink.client.ClientConfig config = new ClientConfig();
config.handlers(new org.apache.wink.client.handlers.LtpaAuthSecurityHandler());
restClient = new RestClient(config);
}
return restClient;
}