diff --git a/LTS-CHANGELOG.adoc b/LTS-CHANGELOG.adoc index bc40106032..ebeee4d61f 100644 --- a/LTS-CHANGELOG.adoc +++ b/LTS-CHANGELOG.adoc @@ -17,6 +17,11 @@ include::content/docs/variables.adoc-include[] The LTS changelog lists releases which are only accessible via a commercial subscription. All fixes and changes in LTS releases will be released the next minor release. Changes from LTS 1.4.x will be included in release 1.5.0. +[[v1.10.30]] +== 1.10.30 (TBD) + +icon:check[] Auth: A `HttpOnly` flag is set onto the JWT auth cookie. + [[v1.10.29]] == 1.10.29 (06.03.2024) diff --git a/common/src/main/java/com/gentics/mesh/auth/handler/MeshJWTAuthHandler.java b/common/src/main/java/com/gentics/mesh/auth/handler/MeshJWTAuthHandler.java index 263d9dfe38..970805bac8 100644 --- a/common/src/main/java/com/gentics/mesh/auth/handler/MeshJWTAuthHandler.java +++ b/common/src/main/java/com/gentics/mesh/auth/handler/MeshJWTAuthHandler.java @@ -149,9 +149,11 @@ private void handleJWTAuth(RoutingContext context, boolean ignoreDecodeErrors) { if (!result.isUsingAPIKey()) { String jwtToken = authProvider.generateToken(authenticatedUser); // Remove the original cookie and set the new one - context.removeCookie(SharedKeys.TOKEN_COOKIE_KEY); - context.addCookie(Cookie.cookie(SharedKeys.TOKEN_COOKIE_KEY, jwtToken) - .setMaxAge(meshOptions.getAuthenticationOptions().getTokenExpirationTime()).setPath("/")); + context.response().removeCookie(SharedKeys.TOKEN_COOKIE_KEY); + context.response().addCookie(Cookie.cookie(SharedKeys.TOKEN_COOKIE_KEY, jwtToken) + .setHttpOnly(true) + .setMaxAge(meshOptions.getAuthenticationOptions().getTokenExpirationTime()) + .setPath("/")); } context.next(); } else { diff --git a/common/src/main/java/com/gentics/mesh/auth/provider/MeshJWTAuthProvider.java b/common/src/main/java/com/gentics/mesh/auth/provider/MeshJWTAuthProvider.java index 5ec9aea46d..9956d5dcfc 100644 --- a/common/src/main/java/com/gentics/mesh/auth/provider/MeshJWTAuthProvider.java +++ b/common/src/main/java/com/gentics/mesh/auth/provider/MeshJWTAuthProvider.java @@ -8,9 +8,6 @@ import javax.inject.Inject; import javax.inject.Singleton; -import com.gentics.mesh.auth.handler.MeshJWTAuthHandler; -import io.vertx.core.http.Cookie; -import io.vertx.ext.auth.authentication.AuthenticationProvider; import org.apache.commons.lang.NotImplementedException; import org.apache.commons.lang3.StringUtils; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @@ -30,13 +27,14 @@ import io.vertx.core.Future; import io.vertx.core.Handler; import io.vertx.core.Vertx; +import io.vertx.core.http.Cookie; import io.vertx.core.json.JsonObject; import io.vertx.core.logging.Logger; import io.vertx.core.logging.LoggerFactory; -import io.vertx.ext.auth.AuthProvider; import io.vertx.ext.auth.JWTOptions; import io.vertx.ext.auth.KeyStoreOptions; import io.vertx.ext.auth.User; +import io.vertx.ext.auth.authentication.AuthenticationProvider; import io.vertx.ext.auth.jwt.JWTAuth; import io.vertx.ext.auth.jwt.JWTAuthOptions; @@ -299,7 +297,9 @@ private User loadUserByJWT(JsonObject jwt) throws Exception { public void login(InternalActionContext ac, String username, String password, String newPassword) { String token = generateToken(username, password, newPassword); ac.addCookie(Cookie.cookie(SharedKeys.TOKEN_COOKIE_KEY, token) - .setMaxAge(meshOptions.getAuthenticationOptions().getTokenExpirationTime()).setPath("/")); + .setHttpOnly(true) + .setMaxAge(meshOptions.getAuthenticationOptions().getTokenExpirationTime()) + .setPath("/")); ac.send(new TokenResponse(token).toJson()); } diff --git a/tests/tests-core/src/main/java/com/gentics/mesh/core/user/AuthenticationEndpointTest.java b/tests/tests-core/src/main/java/com/gentics/mesh/core/user/AuthenticationEndpointTest.java index 66c5164f34..801587c5e9 100644 --- a/tests/tests-core/src/main/java/com/gentics/mesh/core/user/AuthenticationEndpointTest.java +++ b/tests/tests-core/src/main/java/com/gentics/mesh/core/user/AuthenticationEndpointTest.java @@ -140,6 +140,7 @@ public void testBasicAuth() throws IOException { .build()).execute(); JsonObject responseBody = new JsonObject(response.body().string()); assertThat(responseBody.getString("username")).isEqualTo("admin"); + assertThat(response.header("set-cookie")).contains("HTTPOnly"); } private String base64(String input) {