Quarkus OIDC删除q_session cookie时如何设置SameSite=None?
你的问题核心是:Quarkus OIDC认证环节能给q_session Cookie设置SameSite=None,但删除该Cookie时这个配置不生效,导致iframe实现的单点注销(SLO)无法清除Cookie,残留会话。针对Quarkus 3.2.0.Final版本,有以下几种可行方案:
1. 自定义响应过滤器强制设置SameSite属性
通过JAX-RS的ContainerResponseFilter拦截响应,找到正在被删除的q_session Cookie,手动添加SameSite=None和Secure属性(SameSite=None必须搭配Secure,仅HTTPS环境生效):
import jakarta.ws.rs.container.ContainerRequestContext; import jakarta.ws.rs.container.ContainerResponseContext; import jakarta.ws.rs.container.ContainerResponseFilter; import jakarta.ws.rs.ext.Provider; import org.jboss.resteasy.spi.HttpResponse; import org.jboss.resteasy.spi.ResteasyProviderFactory; import jakarta.ws.rs.core.NewCookie; @Provider public class QSessionCookieCleanupFilter implements ContainerResponseFilter { @Override public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) { HttpResponse response = ResteasyProviderFactory.getContextData(HttpResponse.class); if (response != null) { response.getHttpHeaders().getCookies().forEach((cookieName, cookie) -> { if ("q_session".equals(cookieName) && cookie.getMaxAge() == 0) { // 重新构建Cookie,添加SameSite=None和Secure属性 NewCookie updatedCookie = new NewCookie( cookie.getName(), cookie.getValue(), cookie.getPath(), cookie.getDomain(), cookie.getVersion(), cookie.getComment(), cookie.getMaxAge(), cookie.getExpiry(), true, cookie.isHttpOnly(), NewCookie.SameSite.NONE ); response.getHttpHeaders().add("Set-Cookie", updatedCookie.toString()); } }); } } }
注册这个过滤器后,当q_session Cookie被标记为删除(maxAge=0)时,会自动带上SameSite=None属性,确保iframe能正常清除Cookie。
2. 升级Quarkus版本至3.3+
Quarkus官方在后续版本(比如3.3.0及以上)修复了OIDC删除Cookie时未同步SameSite配置的问题。升级后,删除q_session Cookie时会自动沿用认证阶段设置的SameSite属性,无需额外代码处理。
3. 自定义OidcUtils逻辑(备选方案)
如果无法升级版本且过滤器方案不适用,可以通过Quarkus的CDI替代机制替换默认的OidcUtils实现,在removeCookie方法中补充SameSite设置:
// 自定义OidcUtils,重写removeCookie方法 public class CustomOidcUtils extends OidcUtils { public static void removeCookie(RoutingContext context, ServerCookie cookie, OidcTenantConfig oidcConfig) { super.removeCookie(context, cookie, oidcConfig); if (cookie != null && "q_session".equals(cookie.getName())) { cookie.setSameSite("None"); cookie.setSecure(true); } } }
这种方法需要深入Quarkus内部扩展逻辑,维护成本较高,仅作为应急备选。
内容的提问来源于stack exchange,提问作者Daichi
相关产品推荐
相关产品推荐

