You have 2 different ways. Depending on your choice of websocket use.
Jetty 9.1 WebSocket API technique:
Use a custom org.eclipse.jetty.websocket.servlet.WebSocketCreator as such.
package examples;
import java.io.IOException;
import java.security.Principal;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
public class MyAuthedCreator implements WebSocketCreator
{
@Override
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
{
try
{
// Is Authenticated?
Principal principal = req.getPrincipal();
if (principal == null)
{
resp.sendForbidden("Not authenticated yet");
return null;
}
// Is Authorized?
if (!req.isUserInRole("websocket"))
{
resp.sendForbidden("Not authorized yet");
return null;
}
// Return websocket
return new MyEchoSocket();
}
catch (IOException e)
{
e.printStackTrace(System.err);
}
// no websocket
return null;
}
}
And let your servlet know you want to use it.
package examples;
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
public class MyAuthedServlet extends WebSocketServlet
{
@Override
public void configure(WebSocketServletFactory factory)
{
factory.setCreator(new MyAuthedCreator());
}
}
Or if you want to use the javax.websocket API ...
package examples;
import javax.websocket.OnMessage;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint(value = "/secured/socket", configurator = MyAuthedConfigurator.class)
public class MyAuthedSocket
{
@OnMessage
public String onMessage(String msg)
{
// echo the message back to the remote
return msg;
}
}
This uses a custom ServerEndpointConfig.Configurator as such ...
package examples;
import java.security.Principal;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
public class MyAuthedConfigurator extends ServerEndpointConfig.Configurator
{
@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response)
{
// Is Authenticated?
Principal principal = request.getUserPrincipal();
if (principal == null)
{
throw new RuntimeException("Not authenticated");
}
// Is Authorized?
if (!request.isUserInRole("websocket"))
{
throw new RuntimeException("Not authorized");
}
// normal operation
super.modifyHandshake(sec,request,response);
}
}
For this scenario, the Jetty 9.1 WebSocket API is better, as the JSR-356 spec isn't terribly clear about how to fail a upgrade for authentication or authorization reasons.