You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ADAL4J通过用户名密码获取Token时遇SAXParseException求助

解决ADAL4J获取微软Token时的SAXParseException(DOCTYPE被禁止)问题

嘿,我看你在用ADAL4J的用户名密码流获取微软身份验证Token时碰到了SAXParseException,核心错误是DOCTYPE is disallowed when the feature "http://apache.org/xml/features/disallow-doctype-decl" set to true。这个问题其实是ADAL4J解析微软元数据响应时的配置冲突导致的,下面给你一步步排查和解决:

1. 先升级ADAL4J版本(最稳妥的方案)

旧版本的ADAL4J在XML解析的安全配置上有小问题,后续版本已经修复了对DOCTYPE声明的兼容处理。建议你把ADAL4J的依赖升级到1.6.7及以上的稳定版。比如用Maven的话,修改依赖:

<dependency>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>adal4j</artifactId>
    <version>1.6.7</version>
</dependency>

升级后大部分情况下这个错误会直接消失,因为新版本调整了解析器的特性配置。

2. 检查你代码里的资源URI是否正确

我注意到你代码里写的是"&ltresource&gt",这是HTML转义后的占位符,实际运行时必须替换成真实的目标资源URI,比如:

  • 调用微软Graph API就用https://graph.microsoft.com
  • 调用Azure AD Graph API用https://graph.windows.net
  • 或者你自己的自定义API的资源ID

如果资源URI不对,可能返回的元数据响应格式异常,间接触发解析错误。修正后的代码片段参考:

// 初始化认证上下文
AuthenticationContext context = new AuthenticationContext("https://login.microsoftonline.com/common/", false, service);
// 替换成真实的资源URI、客户端ID、用户名和密码
Future<AuthenticationResult> future = context.acquireToken(
    "https://graph.microsoft.com",
    "your-client-id-here",
    "user@your-domain.com",
    "user-password-here",
    null
);
AuthenticationResult result = future.get();
// 输出Token信息
System.out.println("Access Token - " + result.getAccessToken());
System.out.println("Refresh Token - " + result.getRefreshToken());
System.out.println("ID Token - " + result.getIdToken());

3. 若无法升级版本,试试自定义XML解析配置(应急方案)

如果因为项目依赖限制没法升级ADAL4J,可以通过反射修改MexParser里的XML解析器配置,关闭禁止DOCTYPE的特性。不过这种方式比较“hack”,仅建议应急使用:

// 在调用acquireToken之前执行这段代码
try {
    // 反射获取MexParser类
    Class<?> mexParserClass = Class.forName("com.microsoft.aad.adal4j.MexParser");
    // 获取getPolicy方法并设置可访问
    Method getPolicyMethod = mexParserClass.getDeclaredMethod("getPolicy", Document.class);
    getPolicyMethod.setAccessible(true);
    
    // 配置DocumentBuilderFactory,关闭disallow-doctype-decl特性
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", false);
    // 这里需要替换MexParser内部使用的DocumentBuilderFactory,可能需要更复杂的反射操作
    // 注意:不同ADAL4J版本的内部实现可能不同,这个方法不一定通用
} catch (Exception e) {
    e.printStackTrace();
}

额外提醒

  • 确保你的Azure AD应用已经开启了资源所有者密码凭据流(ROPC),因为你用的是用户名密码方式获取Token,这个流需要在应用注册的“认证”页面里开启对应的权限。
  • 尽量避免使用ROPC流,微软更推荐用授权码流或设备码流,ROPC的安全性相对较低,仅适用于特定的 legacy 场景。

内容的提问来源于stack exchange,提问作者user2788875

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:42:29