客户端
我有一个基本的使用POST或GET方法连接到远程服务器的Java应用程序:
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setAllowUserInteraction(false);
conn.setRequestProperty("Content-type", "text/xml; charset=" + ENCODING);
conn.connect();
conn.getOutputStream().write(data.getBytes(ENCODING));
conn.getOutputStream().close();
(我不能改变这个代码,唯一的东西,我可以改变的是urlStr
和data
调用方法时发送到服务器)。
[编辑],客户端可以是一个Java客户端或任何其他客户端(C ++,目标c,...)。 这里的关键是,我只能访问什么在我的帖子的正文以及网址。
服务器端
在我的服务器端,我想实现的Spring Security(SecurityContext中和会话持久性)。
据我所知,春天的安全性是基于浏览器的Cookie当它是一个WebApp
,以保存有关信息session id
。 但对我来说没有任何浏览器。
谢谢。
[编辑]
由@zagyi指出的那样,我就可以使用URL会话令牌传递到春天,但我仍然无法弄清楚如何。
在url中传递的JSESSIONID只是在这样的URL的末尾追加它的事情:
http://localhost:8080/example/auth/login;jsessionid=A06F00609BBA8A4C2B005FB25F90C4C9
如果您配置的浏览器不接受任何Cookie,在这种情况下,服务器会自动包含在URL中的会话ID(假设默认配置Tomcat),你可以在工作的看到这一点。 这个话题也讨论了这个问题 。
可存在用于该客户端的解决方案。
行动点,我们可以互动是在这里:
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
我们将提供自己的(包裹) HttpURLConnection
,它将处理JSESSIONID
。 但不幸的是,我们必须进一步启动了一下。
诀窍是,我们注册一个新的协议,如“xhttp”,我们用它来包装一个真正的“HTTP”协议连接。 所以,你的URL看起来像:
xhttp://www.example.com/...
首先,定义一个URLStreamHandlerFactory
类
public class MyURLStreamHandlerFactory implements URLStreamHandlerFactory {
public URLStreamHandler createURLStreamHandler(String protocol) {
if ("xhttp".equals(protocol)) {
return new MyURLStreamHandler();
}
return null;
}
}
在Java(或应用程序)初始化时,我们可以设置它。 你可以这样做只有一次每个JVM。
URLStreamHandlerFactory fac = new MyURLStreamHandlerFactory();
URL.setURLStreamHandlerFactory(fac);
所以,让我们继续用MyURLStreamHandler
。
public class MyURLStreamHandler extends URLStreamHandler {
@Override
protected URLConnection openConnection(URL url) throws IOException {
return new MyHttpURLConnection(url);
}
}
这是非常简单的,我们创造我们自己的连接。 让我们做的脏东西:
public final class MyHttpURLConnection extends HttpURLConnection {
private HttpURLConnection conn;
public MyHttpURLConnection(URL url) throws MalformedURLException, IOException {
super(url);
String newUrlString = url.toExternalForm().substring(1);
conn = (HttpURLConnection) new URL(newUrlString).openConnection();
}
@Override
public void disconnect() {
conn.disconnect();
}
@Override
public boolean usingProxy() {
return false;
}
@Override
public void connect() throws IOException {
conn.connect();
conn.setRequestProperty("JSESSIONID", "X");
}
}
瞧,我们成功地访问我们的连接,并设置JSESSIONID
头。
所有你需要的是编译的类,类文件添加到客户端罐子,使运行在上面的代码运行在同一个JVM某种方式初始化代码。
如果你不能做到这一点,还有另外一种可能:设置以下系统参数到客户端Java应用程序:
-Djava.protocol.handler.pkgs=com.example.myprotocol
在这种情况下创建一个com.example.myprotocol.xhttp
(xhttp喜欢你的协议名称),我们重命名MyURLStreamHandler
类com.example.myprotocol.xhttp.Handler
。 这是固定的名称,其中协议解析器将寻找它。 请注意,这java.protocol.handler.pkgs
属性由安全管理检查。