我遵循了这篇关于使用Java EE设置websocket端点的教程:https://technology.amis.nl/2013/06/22/java-ee-7-ejb-publishing-cdi-events-that-are-pushed-over-websocket-to-browser-client/。
由于明显的原因,在安全方面还要做更多工作(例如没有SSL和访问限制/身份验证)。
所以我的目标是通过以下方式来改进websocket安全性:
- 使用SSL(wss://而不是ws://)-完成
- 设置用户身份验证(web.xml)-完成
- 强制执行SSL通信(web.xml)-完成
- 用令牌(有限生命周期)保护websocket连接
我的问题:我如何在ServerEndpoint中验证我在LoginBean中创建的令牌?
附加问题:我是否遗漏了在Java EE中保护websocket的重要部分?
这是我到目前为止的内容:
ServerEndpoint
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint("/user/endpoint/{token}")
public class ThisIsTheSecuredEndpoint {
@OnOpen
public void onOpen(@PathParam("token") String incomingToken,
Session session) throws IOException {
//How can i check if the token is valid?
}
}
LoginBean
@ManagedBean
@SessionScoped
public class LoginBean {
public String login() {
FacesContext facesContext = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest)facesContext.getExternalContext().getRequest();
try {
request.login("userID", "password");
HttpSession session = request.getSession();
// here we put the token in the session
session.setAttribute("token", "someVeeeeryLongRandomValue123hfgrtwpqllkiw");
} catch (ServletException e) {
facesContext.addMessage(null, new FacesMessage("Login failed."));
return "error";
}
return "home";
}
}
Javascipt
这是我想使用的连接到 WebSocket 的代码:
// use SSL
// retrive the token from session via EL-expression #{session.getAttribute("token")}
var wsUri = "wss://someHost.com/user/endpoint/#{session.getAttribute("token")}";
var websocket = new WebSocket(wsUri);
websocket.onerror = function(evt) { onError(evt) };
function onError(evt) {
writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
}
// For testing purposes
var output = document.getElementById("output");
websocket.onopen = function(evt) { onOpen(evt) };
function writeToScreen(message) {
output.innerHTML += message + "<br>";
}
function onOpen() {
writeToScreen("Connected to " + wsUri);
}
web-xml:
使用登录验证和SSL加密通信来保护“/user/*”目录
<security-constraint>
...
<web-resource-name>Secured Area</web-resource-name>
<url-pattern>pathToSecuredDicrtoy</url-pattern>
...
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
...
</security-constraint>
<login-config>
<auth-method>FORM</auth-method> ...
</login-config>
注意: 我正在使用JSF
非常感谢您的任何反馈。
web.xml
中添加了以下内容:
jsp
*.js
对于我的用例来说,这是可以的,因为该页面的访问率非常低。 - Tobi Tiggers