从外部应用程序登录到 Content Navigator
Logging into Content Navigator from external application
我正在尝试从我的 Java 应用程序(FileNet P8 中的事件操作处理程序)访问 Content Navigator 上的 PluginService。该应用程序使用 JAXRS 登录服务从 Content Navigator 服务器接收 security_token
。但是,如果我尝试调用 PluginService,我会收到一个响应,提示我的登录已过期。
我能够获取安全令牌,如代码块中所述:
URL logonUrl = new URL("http://icn-host:9081/jaxrs/logon"
+ "?userid=user"
+ "&password=password"
+ "&desktop=admin"
+ "&contextPath=%2Fnavigator");
HttpURLConnection logonConnection = (HttpURLConnection)logonUrl.openConnection();
logonConnection.setRequestMethod("POST");
logonConnection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
logonConnection.setDoOutput(true);
InputStream logonResponse = logonConnection.getInputStream();
String responseText = IOUtils.toString(logonResponse, "UTF-8")
.replaceFirst("^\{}&&", "");
JSONObject responseJson = JSONObject.parse(responseText);
return (String)responseJson.get("security_token");
但是当我尝试发出另一个请求时,我收到错误响应:
URL requestUrl = new URL("http://icn-host:9081/plugin.do"
+ "?plugin=myPlugin&action=myPluginService&myRequestProps=foobar");
HttpURLConnection requestConnection =
(HttpURLConnection)requestUrl.openConnection();
requestConnection.setRequestMethod("GET");
String securityToken = getSecurityToken(); // calls above code
requestConnection.setRequestProperty("security_token", securityToken);
equestConnection.setDoOutput(true);
InputStream responseStream = requestConnection.getInputStream();
String responseText = IOUtils.toString(responseStream, "UTF-8")
.replaceFirst("^\{}&&", "");
log.info("response was: " + responseText);
我总是收到以下回复:
{
"messagesEncoded":true,
"errors": [
{
"adminResponse":null,
"moreInformation":null,
"explanation":"Your session expired because of inactivity.",
"number":"1003",
"userResponse":"Log in again.",
"text":"Your session expired."
}
]
}
我也试过设置 cookie,但没有成功。
java.net.CookieManager cookieManager = new java.net.CookieManager();
Map<String, List<String>> headerFields = logonConnection.getHeaderFields();
List<String> cookiesHeader = headerFields.get("Set-Cookie");
if (cookiesHeader != null) {
for (String cookie : cookiesHeader) {
cookieManager.getCookieStore().add(null, HttpCookie.parse(cookie).get(0));
}
}
// ...
StringBuilder cookieHeader = new StringBuilder();
List<HttpCookie> cookies = cookieManager.getCookieStore().getCookies();
for (int i = 0; i < cookies.size(); i++) {
if (i > 0) {
cookieHeader.append(";");
}
HttpCookie cookie = cookies.get(i);
log.info("Cookie " + i + ": " + cookie.toString());
cookieHeader.append(cookie.toString());
}
requestConnection.setRequestProperty("Cookie", cookieHeader.toString());
我尝试在 Content Navigator window 中使用 XMLHttpRequest 复制请求,它按预期工作:
var xhr = new XMLHttpRequest();
xhr.open("GET", "plugin.do" +
"?plugin=myPlugin" +
"&action=myPluginService" +
"&myRequestProps=foobar");
xhr.setRequestHeader("security_token", ecm.model.Request._security_token);
xhr.send();
几个月前,我遇到了一个客户的类似挑战,我不得不自动执行安装插件和应用配置的过程 CI 目的。
我发现获取桌面是登录后第一个 api 调用的关键,会话变为 'valid'。
所以首先 jaxrs/logon,然后 jaxrs/getDesktop,然后调用您的服务。
一点旁注:如果您计划以后使用容器管理身份验证,则过程会有所不同。 jaxrs/logon 将不起作用,而 jaxrs/getDesktop 将提供 security_token.
但要注意一点:拥有一个共享库,您可以将事件操作中的两者都用作 ICN 服务,这不是更好的解决方案吗?
使用共享库(参见 Ivo 的回答)绝对是最好的方法,调用 jaxrs/getDesktop
对我不起作用。相反,我只是使用 Maven Assembly Plugin 来包含更新版本的 org.apache.httpcomponents
依赖项并使用 HttpClient 调用请求。
我的最终代码如下所示:
CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultCookieStore(cookieStore)
.setDefaultRequestConfig(requestConfig)
.build();
HttpUriRequest logonRequest = RequestBuilder.post()
.setUri("http://icn-host:9081/navigator/jarxrs/logon")
.addParameter("desktop", "admin")
.addParameter("contextPath", "/navigator")
.addParameter("userid", "icnadmin")
.addParameter("password", "password")
.build();
CloseableHttpResponse logonResponse = httpClient.execute(logonRequest);
HttpEntity responseEntity = logonResponse.getEntity();
String responseText = EntityUtils.toString(responseEntity)
.replaceFirst("^\{}&&", "");
JSONObject responseJson = JSONObject.parse(responseText);
String securityToken = (String) responseJson.get("security_token");
HttpUriRequest request = RequestBuilder.get()
.setUri("http://icn-host:9081/navigator/plugin.do")
.addParameter("plugin", "myPlugin")
.addParameter("action", "myPluginService")
.addParameter("myRequestProps", "foobar")
.addHeader("security_token", securityToken)
.build();
HttpClientContext context = HttpClientContext.create();
CookieStore cookieStore = new BasicCookieStore();
context.setCookieStore(cookieStore);
CloseableHttpResponse response = httpClient.execute(request, context);
我正在尝试从我的 Java 应用程序(FileNet P8 中的事件操作处理程序)访问 Content Navigator 上的 PluginService。该应用程序使用 JAXRS 登录服务从 Content Navigator 服务器接收 security_token
。但是,如果我尝试调用 PluginService,我会收到一个响应,提示我的登录已过期。
我能够获取安全令牌,如代码块中所述:
URL logonUrl = new URL("http://icn-host:9081/jaxrs/logon"
+ "?userid=user"
+ "&password=password"
+ "&desktop=admin"
+ "&contextPath=%2Fnavigator");
HttpURLConnection logonConnection = (HttpURLConnection)logonUrl.openConnection();
logonConnection.setRequestMethod("POST");
logonConnection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
logonConnection.setDoOutput(true);
InputStream logonResponse = logonConnection.getInputStream();
String responseText = IOUtils.toString(logonResponse, "UTF-8")
.replaceFirst("^\{}&&", "");
JSONObject responseJson = JSONObject.parse(responseText);
return (String)responseJson.get("security_token");
但是当我尝试发出另一个请求时,我收到错误响应:
URL requestUrl = new URL("http://icn-host:9081/plugin.do"
+ "?plugin=myPlugin&action=myPluginService&myRequestProps=foobar");
HttpURLConnection requestConnection =
(HttpURLConnection)requestUrl.openConnection();
requestConnection.setRequestMethod("GET");
String securityToken = getSecurityToken(); // calls above code
requestConnection.setRequestProperty("security_token", securityToken);
equestConnection.setDoOutput(true);
InputStream responseStream = requestConnection.getInputStream();
String responseText = IOUtils.toString(responseStream, "UTF-8")
.replaceFirst("^\{}&&", "");
log.info("response was: " + responseText);
我总是收到以下回复:
{
"messagesEncoded":true,
"errors": [
{
"adminResponse":null,
"moreInformation":null,
"explanation":"Your session expired because of inactivity.",
"number":"1003",
"userResponse":"Log in again.",
"text":"Your session expired."
}
]
}
我也试过设置 cookie,但没有成功。
java.net.CookieManager cookieManager = new java.net.CookieManager();
Map<String, List<String>> headerFields = logonConnection.getHeaderFields();
List<String> cookiesHeader = headerFields.get("Set-Cookie");
if (cookiesHeader != null) {
for (String cookie : cookiesHeader) {
cookieManager.getCookieStore().add(null, HttpCookie.parse(cookie).get(0));
}
}
// ...
StringBuilder cookieHeader = new StringBuilder();
List<HttpCookie> cookies = cookieManager.getCookieStore().getCookies();
for (int i = 0; i < cookies.size(); i++) {
if (i > 0) {
cookieHeader.append(";");
}
HttpCookie cookie = cookies.get(i);
log.info("Cookie " + i + ": " + cookie.toString());
cookieHeader.append(cookie.toString());
}
requestConnection.setRequestProperty("Cookie", cookieHeader.toString());
我尝试在 Content Navigator window 中使用 XMLHttpRequest 复制请求,它按预期工作:
var xhr = new XMLHttpRequest();
xhr.open("GET", "plugin.do" +
"?plugin=myPlugin" +
"&action=myPluginService" +
"&myRequestProps=foobar");
xhr.setRequestHeader("security_token", ecm.model.Request._security_token);
xhr.send();
几个月前,我遇到了一个客户的类似挑战,我不得不自动执行安装插件和应用配置的过程 CI 目的。
我发现获取桌面是登录后第一个 api 调用的关键,会话变为 'valid'。
所以首先 jaxrs/logon,然后 jaxrs/getDesktop,然后调用您的服务。
一点旁注:如果您计划以后使用容器管理身份验证,则过程会有所不同。 jaxrs/logon 将不起作用,而 jaxrs/getDesktop 将提供 security_token.
但要注意一点:拥有一个共享库,您可以将事件操作中的两者都用作 ICN 服务,这不是更好的解决方案吗?
使用共享库(参见 Ivo 的回答)绝对是最好的方法,调用 jaxrs/getDesktop
对我不起作用。相反,我只是使用 Maven Assembly Plugin 来包含更新版本的 org.apache.httpcomponents
依赖项并使用 HttpClient 调用请求。
我的最终代码如下所示:
CloseableHttpClient httpClient = HttpClients.custom()
.setDefaultCookieStore(cookieStore)
.setDefaultRequestConfig(requestConfig)
.build();
HttpUriRequest logonRequest = RequestBuilder.post()
.setUri("http://icn-host:9081/navigator/jarxrs/logon")
.addParameter("desktop", "admin")
.addParameter("contextPath", "/navigator")
.addParameter("userid", "icnadmin")
.addParameter("password", "password")
.build();
CloseableHttpResponse logonResponse = httpClient.execute(logonRequest);
HttpEntity responseEntity = logonResponse.getEntity();
String responseText = EntityUtils.toString(responseEntity)
.replaceFirst("^\{}&&", "");
JSONObject responseJson = JSONObject.parse(responseText);
String securityToken = (String) responseJson.get("security_token");
HttpUriRequest request = RequestBuilder.get()
.setUri("http://icn-host:9081/navigator/plugin.do")
.addParameter("plugin", "myPlugin")
.addParameter("action", "myPluginService")
.addParameter("myRequestProps", "foobar")
.addHeader("security_token", securityToken)
.build();
HttpClientContext context = HttpClientContext.create();
CookieStore cookieStore = new BasicCookieStore();
context.setCookieStore(cookieStore);
CloseableHttpResponse response = httpClient.execute(request, context);