Spring Boot集成KeyCloak时出现Cookie非法控制字符异常
我正尝试按照官方教程部署并测试集成KeyCloak的简易Spring Boot应用,但浏览器显示“此页面无法正常工作”且未加载KeyCloak登录页,同时KeyCloak抛出异常:
IllegalArgumentException: An invalid control character was present in the cookie value or attribute
以下是我的pom.xml配置:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>demo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.13.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <keycloak.version>3.3.0.Final</keycloak.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.keycloak.bom</groupId> <artifactId>keycloak-adapter-bom</artifactId> <version>${keycloak.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
异常日志如下:
09:55:18,976 ERROR [io.undertow.request] (default task-7) UT005071: Undertow request failed HttpServerExchange{ GET /auth/ request {Accept= [text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8], Accept-Language=[en-US,en;q=0.9,ru-RU;q=0.8,ru;q=0.7], Cache-Control=[max-age=0], Accept-Encoding=[gzip, deflate, br], User-Agent=[Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36], Connection=[keep-alive], Cookie=[OAuth_Token_Request_State=2132636f-ed6a-44e2-915b-9cefed4dc446; JSESSIONID=D0DA2ADDBE8F62E55C9F65EB71BE85A0], Referer= [http://localhost:8080/], Upgrade-Insecure-Requests=[1], Host=[localhost:8080]} response {Cache-Control=[no-cache, must-revalidate, no-transform, no-store], X-Powered-By=[Undertow/1], Server=[WildFly/11], X-XSS-Protection=[1; mode=block], X-Frame-Options=[SAMEORIGIN], Content-Security-Policy=[frame-src 'self'; frame ancestors 'self'; object-src 'none';], Date=[Wed, 23 May 2018 03:55:18 GMT], Connection= [keep-alive], X-Robots-Tag=[none], X-Content-Type-Options=[nosniff], Content-Type= [text/html;charset=utf-8], Content-Length=[2740]}}: java.lang.IllegalArgumentException: UT000173: An invalid control character [1087] was present in the cookie value or attribute at io.undertow.util.LegacyCookieSupport.isHttpSeparator(LegacyCookieSupport.java:142) at io.undertow.util.LegacyCookieSupport.isHttpToken(LegacyCookieSupport.java:163) at io.undertow.util.LegacyCookieSupport.adjustedCookieVersion(LegacyCookieSupport.java:248) at io.undertow.server.Connectors.getCookieString(Connectors.java:154) at io.undertow.server.Connectors.flattenCookies(Connectors.java:99) at io.undertow.server.protocol.http.HttpResponseConduit.processWrite(HttpResponseConduit.java:161) at io.undertow.server.protocol.http.HttpResponseConduit.write(HttpResponseConduit.java:5
问题分析与解决方案
我来帮你捋捋这个问题——从异常日志里的UT000173: An invalid control character [1087] was present in the cookie value or attribute可以看出,核心问题是Cookie里混入了非法的控制字符(ASCII码1087对应西里尔字母'п',大概率是你配置里用到了俄语相关的非ASCII字符)。结合你用的Keycloak 3.3.0.Final版本,这个版本在处理非ASCII Cookie值时存在已知bug。
给你几个可行的解决办法:
升级Keycloak版本
旧版本的Keycloak在Cookie编码处理上有缺陷,后续4.x及以上版本已经修复了这个问题。修改你的pom.xml里的Keycloak版本,比如升级到4.8.3.Final(稳定版):<keycloak.version>4.8.3.Final</keycloak.version>修改后清理Maven缓存,重新构建项目,重启Keycloak和Spring Boot应用。
检查并清理非ASCII配置
检查你的Keycloak Realm名称、客户端名称、用户属性等配置项,确保没有使用俄语或其他非ASCII字符。如果有,改成纯ASCII字符后再测试。调整Undertow Cookie配置
如果你暂时不想升级Keycloak,可以在Spring Boot配置里禁用Undertow的Legacy Cookie支持,强制使用RFC 6265标准的Cookie处理:
在application.properties里添加:server.undertow.cookie.legacy-samesite-cookie=false server.undertow.cookie.rfc6265-compliant=true
按上面的步骤操作后,应该就能正常加载Keycloak登录页了。
内容的提问来源于stack exchange,提问作者Mukhamedali Zhadigerov

