在我的Web应用程序中,加密不是由应用程序服务器进行的,而是由反向代理进行的。我想保持这种状态。 相关技术堆栈如下:
由于代理加密,appserver配置为不在web.xml中使用加密:
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
现在,websocket连接无法与活动代理一起使用,因为它是由客户端以非加密方式(ws:// ...)建立的。当内容以https。
传送时,浏览器会阻止此操作据我了解,浏览器和appserver的行为似乎都是正确的。虽然浏览器避免降级,但8.3和#34;运输保证&#34; websocket规范声明:
容器必须将NONE的传输保证解释为允许未加密的ws://连接 到websocket [WSC-8.3-1]
有没有办法强制加密(使用wss://)f:websocket,虽然在应用服务器上使用传输保证NONE?或者还有其他设置或更好的方法吗?
目前,我找不到一种方法来调整f:websocket的行为,不得不切换回使用普通的javascript websocket和经典的websocket serverendpoint。
答案 0 :(得分:2)
有没有办法强制加密(使用wss://)f:websocket,虽然在应用服务器上使用传输保证NONE?
websocket URL通过ExternalContext#encodeWebsocketURL()
进行编码。像往常一样在JSF中,所有东西都可以通过工厂进行装饰甚至替换,ExternalContext
也是如此。
下面是一个启动示例,它盲目地将websocket URL中的ws://
替换为wss://
。
public class CustomExternalContext extends ExternalContextWrapper {
public CustomExternalContext(ExternalContext wrapped) {
super(wrapped);
}
@Override
public String encodeWebsocketURL(String url) {
return super.encodeWebsocketURL(url).replaceFirst("ws://", "wss://");
}
public static class Factory extends ExternalContextFactory {
public Factory(ExternalContextFactory wrapped) {
super(wrapped);
}
@Override
public ExternalContext getExternalContext(Object context, Object request, Object response) throws FacesException {
return new CustomExternalContext(getWrapped().getExternalContext(context, request, response));
}
}
}
要使其运行,请在faces-config.xml
:
<factory>
<external-context-factory>com.example.CustomExternalContext$Factory</external-context-factory>
</factory>