Reputation: 41
I'm currently writing a simple prototype Vert.x 3.3 application (Latest Github build using Jitpack.io) that tries to secure http endpoints and the eventbus with Keycloak.
I have two verticals and static index page with a button to send messages. Everything works fine unsecured but I don't know how to secure the SockJS eventbus bridge with Keycloak. Securing the http endpoint works fine.
Since Vert.x 3.3 is not officially released yet I haven't been able to find very much information. http://vertx.io/blog/vertx-3-and-keycloak-tutorial/ only covered securing the http endpoint and the 3.21 documentation on requiring authorization is specifically for using the BasicAuthHandler which I'm not sure how to modify to work with Keycloak: http://vertx.io/docs/vertx-web/java/#_requiring_authorisation_for_messages
Currently I have the following code:
public class VertxEventBusTest extends AbstractVerticle {
@Override
public void start(Future<Void> startFuture) throws Exception {
System.out.println("Primary Verticle Started");
Router router = Router.router(vertx);
HttpServer server = vertx.createHttpServer().requestHandler(router::accept);
OAuth2Auth oAuth2Auth = OAuth2Auth.createKeycloak(vertx, OAuth2FlowType.AUTH_CODE, getKeycloakJson());
OAuth2AuthHandler oAuth2AuthHandler = OAuth2AuthHandler.create(oAuth2Auth, "http://localhost:8091");
oAuth2AuthHandler.setupCallback(router.get("/callback"));
SockJSHandlerOptions options = new SockJSHandlerOptions().setHeartbeatInterval(2000);
BridgeOptions bridgeOptions = new BridgeOptions();
bridgeOptions.addInboundPermitted(new PermittedOptions().setAddress("click"));
bridgeOptions.addOutboundPermitted(new PermittedOptions().setAddress("click"));
SockJSHandler sockJSHandler = SockJSHandler.create(vertx, options).bridge(bridgeOptions);
router.route("/").handler(oAuth2AuthHandler);
router.route("/eventbus/*").handler(oAuth2AuthHandler);
router.route("/eventbus/*").handler(sockJSHandler);
vertx.eventBus().<JsonObject>consumer("click", msg -> System.out.println("Msg Received on Verticle1: " + msg.body()));
router.route().handler(StaticHandler.create().setWebRoot("webroot"));
server.listen(8091, result -> {
if (result.succeeded()) {
startFuture.complete();
} else {
startFuture.fail(result.cause());
}
});
}
private JsonObject getKeycloakJson() {
return new JsonObject("{\n" +
" \"realm\": \"Prototype\",\n" +
" \"realm-public-key\": \"<public key>",\n" +
" \"auth-server-url\": \"http://localhost:8180/auth\",\n" +
" \"ssl-required\": \"external\",\n" +
" \"resource\": \"prototype-eventbus\",\n" +
" \"credentials\": {\n" +
" \"secret\": \"<secret>\"\n" +
" }\n" +
"}");
}
}
My Static Html is:
<head>
<meta charset="UTF-8">
<script src='sockjs-0.3.4.js'></script>
<script src='vertx-eventbus.js'></script>
<script src='index-js.js'></script>
<title>VERT.X Test</title>
</head>
<body onload="load()">
<!-- JavaScript includes. -->
<button onclick="zclicker()">Test Click</button>
</body>
</html>
Javascript:
var eb = new EventBus('http://localhost:8091/eventbus');
function load() {
eb.onopen = function () {
eb.registerHandler('click', function (data) {})
};
}
function zclicker() {
eb.publish('click', {
'clicked': true
});
}
When running the vertical there are no errors but chrome developer tools shows the following error after login through keycloak:
XMLHttpRequest cannot load http://localhost:8180/auth/realms/Prototype/protocol/openid-connect/auth?re…direct_uri%3D%2Feventbus%2Finfo&state=&client_id=prototype-eventbus&scope=. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8091' is therefore not allowed access.
Upvotes: 4
Views: 978
Reputation: 6721
That looks like a CORS issue.
By the looks of your error you might just be able to add the following header in the response:
Access-Control-Allow-Origin: *
or
Access-Control-Allow-Origin: http://localhost:8091
depending on how much you care about security.
That's usually sufficient for simple GET for text/html, but if you want to handle other content types (eg JSON) or PUT / or DELETE methods, then you'll have to add more headers to allow them.
Some resources:
http://enable-cors.org/server.html
http://www.html5rocks.com/en/tutorials/cors/
Upvotes: 1