--
You received this message because you are subscribed to a topic in the Google Groups "vert.x" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/vertx/CuXhbf0_qGo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to vertx+un...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/4aa0b5fd-5174-450b-8a5e-66272de8f731n%40googlegroups.com.
Dominique I look into the stack trace and found that your code always will throws that exception with "buffer" option in your pubSecKeys. When vertx find that key in your config it decodes the key with Decoder.RFC4648 or Decoder.RFC4648_URLSAFE, both constructs Decoder with isMIME parameter = false. And in java.util.Base64.decode(byte[] src, int sp, int sl, byte[] dst) when isMIME==false throws that exception.
The problem is that in io.vertx.core.json.impl.JsonUtil static block code never uses Base64.getMIMEDecoder() that is the only one that not throws that exception because uses Decoder.RFC2045. I don’t know if that is a bug in vertx 4.0.2 or if it is another thing.
I think you can try to remove the buffer key of the json and only let the public key. Maybe that forces vertx to use the deprecated io.vertx.ext.auth.setPublicKey(String publicKey). With that change, if throws “java.lang.IllegalArgumentException: PEM contains not enough lines” then set
“publicKey”:”-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEMy9p7xiTEhRvaYHuA9i1T/f2Z2A6qyCbR3abUdR5G/A6TFcfoow0InVfBTcpyMFW3DBaclWgqC3piMQXEreQ8Q==\n-----END PUBLIC KEY-----”
I hope that fix your problem. My current problem is with an io.vertx.core.impl.NoStackTraceThrowable exception. I can’t figure out where is the real problem and anyone in the group answer my question =(
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/4dfd4f34-89a9-47c2-8470-01135a06ff10n%40googlegroups.com.
Hello Dominique,
I am currently migrating to vertx 4.0.2 too and without “buffer” it works for me. But I am using a custom JWTAuth implementation and OAuth2FlowType.PASSWORD flow. I will send the code above and I hope that helps you to adapt it in your case. You will see some comments for you:
//Json config:
…
"keycloak": {
"enabled": true,
"auth-server-url": "https://XXX.com/auth",
"realm": "XXX",
"resource": "api-vertx-keycloak",
"secret": "XXX",
"username": "XXX",
"password": "XXX",
"realm-public-key": "XXX",
"ssl-required": "external"
},
"jwt" : {
"path" : "jwt.jceks",
"password" : "noysi.secret0.2015"
},
"jwtOpenIDC" : {
"public-key" : "XXX"
}
…
//JWTAuth creation
JWTAuth jwtAuth = new CustomJWTAuth(vertx, configuration.getJsonObject("jwt"),
configuration.getJsonObject("jwtOpenIDC", new JsonObject()));
//Custom JWTAuth class
public class CustomJWTAuth implements JWTAuth {
Vertx vertx;
JWTAuth legacyAuthDelegate;
AuthenticationProvider openidAuthDelegate;
public CustomJWTAuth(Vertx vertx, JsonObject legacyJWTConfig, JsonObject openidJWTConfig) {
this.vertx = vertx;
// Build legacy delegate
JsonObject args = new JsonObject().put("keyStore",
new JsonObject().put("path", legacyJWTConfig.getString("path")).put("type", "jceks")
.put("password", legacyJWTConfig.getString("password")));
JWTAuthOptions authOptions = new JWTAuthOptions(args);
legacyAuthDelegate = JWTAuth.create(vertx, authOptions);
// Build openid delegate
String oipPublicKey = openidJWTConfig.getString("public-key", "");
if (!oipPublicKey.isEmpty()) {
args = new JsonObject().put("public-key", oipPublicKey).put("permissionsClaimKey",
"resource_access/uid");
JWTAuthOptions openidOptions = new JWTAuthOptions(args);
openidAuthDelegate = JWTAuth.create(vertx, openidOptions);
}
}
@Override
public String generateToken(JsonObject claims, io.vertx.ext.auth.JWTOptions jwtOptions) {
return legacyAuthDelegate.generateToken(claims, jwtOptions);
}
@Override
public String generateToken(JsonObject claims) {
return legacyAuthDelegate.generateToken(claims);
}
@Override
public void authenticate(JsonObject jsonObject, Handler<AsyncResult<User>> handler) {
// For compatibility with vertx 4 because they need “token” insted of “jwt”(vertx 3). This was another issue that took me several hours to solve
jsonObject.put("jwt", jsonObject.getValue("token"));
// Run auth through both legacy and openid provider. Auth will fail if none of them succeed.
legacyAuthDelegate.authenticate(jsonObject).onSuccess(user -> {
handler.handle(Future.succeededFuture(user));
}).onFailure(err -> {
err.printStackTrace();
if (Objects.isNull(openidAuthDelegate)) {
handler.handle(Future.failedFuture(err.getCause()));
} else {
openidAuthDelegate.authenticate(jsonObject).onSuccess(user -> {
handler.handle(Future.succeededFuture(user));
}).onFailure(openidErr -> {
openidErr.printStackTrace();
handler.handle(Future.failedFuture(openidErr.getCause()));
});
}
});
}
}
//Auth implementation
…
// I put BEGIN/END PUBLIC KEY here but in the json config will work too
JsonObject keycloakJson =
new JsonObject().put("realm", configuration.getJsonObject("keycloak").getString("realm"))
.put("realm-public-key",
"-----BEGIN PUBLIC KEY-----\n"
+ configuration.getJsonObject("keycloak").getString("realm-public-key")
+ "\n-----END PUBLIC KEY-----\n")
.put("auth-server-url",
configuration.getJsonObject("keycloak").getString("auth-server-url"))
.put("ssl-required", configuration.getJsonObject("keycloak").getString("ssl-required"))
.put("resource", configuration.getJsonObject("keycloak").getString("resource"))
.put("credentials", new JsonObject().put("secret",
configuration.getJsonObject("keycloak").getString("secret")));
router.post("/sign-in").produces("application/json").handler(rc -> {
JsonObject userJson = rc.getBodyAsJson();
userJson.put("username", userJson.getString("email"));
userJson.put("password", PasswordEncoder.encode(rc.getBodyAsJson().getString("password")));
if (configuration.getJsonObject("keycloak").getBoolean("enabled") == true) {
OAuth2Auth oauth2 = KeycloakAuth.create(vertx, OAuth2FlowType.PASSWORD, keycloakJson);
oauth2.authenticate(userJson).onSuccess(userResponse -> {
String httpAuthorizationHeader = userResponse.principal().getString("access_token");
userJson.put("password", rc.getBodyAsJson().getString("password"));
users.signIn(userJson, async -> {
if (async.failed()) {
rc.response().setStatusCode(404).end(async.cause().getMessage());
} else {
User user = async.result();
String token = security.jwt(new JsonObject().put("uid", user.getId()));
rc.response().setStatusCode(200).putHeader("X-Subject-Token", token)
.end(user.toJson().toString());
}
});
}).onFailure(err -> {
rc.response().setStatusCode(HttpResponseStatus.NOT_FOUND.code()).end();
});
} else {
users.signIn(rc.getBodyAsJson(), async -> {
if (async.failed()) {
rc.response().setStatusCode(404).end(async.cause().getMessage());
} else {
User user = async.result();
String token = security.jwt(new JsonObject().put("uid", user.getId()));
rc.response().setStatusCode(200).putHeader("X-Subject-Token", token)
.end(user.toJson().toString());
}
});
}
});
router.post("/sign-up").produces("application/json").handler(rc -> {
if (configuration.getJsonObject("keycloak").getBoolean("enabled") == true) {
JsonObject userJson = rc.getBodyAsJson();
userJson.put("password", PasswordEncoder.encode(rc.getBodyAsJson().getString("password")));
String userIdK = createAgentOnKeyclock(userJson, configuration.getJsonObject("keycloak"));
userJson.put("id_keycloak", userIdK);
if (!userIdK.equals("Failure")) {
userJson.put("password", rc.getBodyAsJson().getString("password"));
users.signUp(userJson, async -> {
if (async.failed()) {
NoysiException exception = (NoysiException) async.cause();
rc.response().setStatusCode(exception.getCode()).end();
} else {
users.signIn(userJson, async2 -> {
if (async2.failed()) {
rc.response().setStatusCode(404).end(async2.cause().getMessage());
} else {
User user = async2.result();
String token = security.jwt(new JsonObject().put("uid", user.getId()));
rc.response().setStatusCode(200).putHeader("X-Subject-Token", token)
.end(user.toJson().toString());
}
});
}
});
} else {
rc.response().setStatusCode(HttpResponseStatus.CONFLICT.code()).end();
}
} else {
users.signUp(rc.getBodyAsJson(), async -> {
if (async.failed()) {
NoysiException exception = (NoysiException) async.cause();
rc.response().setStatusCode(exception.getCode()).end();
} else {
users.signIn(rc.getBodyAsJson(), async2 -> {
if (async2.failed()) {
rc.response().setStatusCode(404).end(async2.cause().getMessage());
} else {
User user = async2.result();
String token = security.jwt(new JsonObject().put("uid", user.getId()));
rc.response().setStatusCode(200).putHeader("X-Subject-Token", token)
.end(user.toJson().toString());
}
});
}
});
}
….