背景
一次在迁移服务器组件的时候,发现一个奇怪的错误,cas客户端怎么也登录不上,查询日志发现cas-server已经校验成功了。但是客户端还是登录不上。
问题定位
公司内部管理系统使用的是cas来完成登录验证的。
客户端依赖如下:
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>3.4.1</version>
</dependency>
服务端依赖如下:
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-actions</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-cookie</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-redis-ticket-registry</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-core-logout</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-webapp-tomcat</artifactId>
<version>${cas.version}</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
<!--jdbc认证 -->
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-jdbc</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-audit-jdbc</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-throttle-jdbc</artifactId>
<version>${cas.version}</version>
</dependency>
问题现象,客户端组件每次登录的时候都会报如下错误:
红色框中的部分是真正抛出异常的地方,我们再后面分析,初次见到这个错误,以为是cas-server部署有问题,导致返回的数据解析失败。但是通过排查实际cas-server没有问题(该组件使用的是HTTP+XML协议来进行客户端与cas-server之间传输数据)。由于我是先在本地断点来排查这个问题,发现本地居然可以登录。cas-server返回的数据如下(只截到了解析报错的地方):
后又断点了服务器:
返回的数据如下:
可以看到两者数据返回的格式都是一样,也没有出现错乱的情况。从报错的信息( Element or attribute “cas:0c025fe1020d442e9e94c835794ccc0b” do not match QName production: QName::=(NCName:)?NCName)来看似乎是返回的格式不匹配解析的格式导致的。而且我在端点报错红框的位置,本地根本没有对应的代码。说明我们本地和服务器代码其实是不一样的。本地代码如下:
XMLEntityScanner这个类其实是在jre下面的resources.jar包下。由此我们可以猜测是不同jdk版本导致这里解析结果不一样。我本地使用的jdk1.8.0_111 而 服务器使用的jdk1.8.0_131 。
问题解决
我在服务更换了jdk版本,将其升级到1.8.0_161 问题解决。注意更换的时候需要设置软连接:ln -s /home/java/jdk1.8.0_161/bin/java /usr/bin/java ,否则会找不到java命令。这个没有去阅读源码,为什么1.8.0_131会出现这样的问题,后面抽空去阅读一下,及时更新。