pac4j从5.7.7迁移至6.0.0后SAML登录RoleDescriptor错误求助
问题:pac4j 从5.7.7迁移至6.x版本后ADFS SAML登录失败
将pac4j从5.7.7版本迁移至6.0.0版本后,ADFS的SAML登录功能无法正常使用,触发如下错误:
org.opensaml.core.xml.io.UnmarshallingException: Saw invalid child element {urn:oasis:names:tc:SAML:2.0:metadata}RoleDescriptor on parent {urn:oasis:names:tc:SAML:2.0:metadata}EntityDescriptor Error initializing idp metadata resolver org.pac4j.core.exception.TechnicalException: Error initializing idp metadata resolver at org.pac4j.saml.metadata.SAML2IdentityProviderMetadataResolver.initializeMetadataResolver(SAML2IdentityProviderMetadataResolver.java:108) at org.pac4j.saml.metadata.SAML2IdentityProviderMetadataResolver.internalLoad(SAML2IdentityProviderMetadataResolver.java:78) at org.pac4j.core.resource.SpringResourceLoader.load(SpringResourceLoader.java:50) at org.pac4j.saml.metadata.SAML2IdentityProviderMetadataResolver.resolve(SAML2IdentityProviderMetadataResolver.java:71) at org.pac4j.saml.client.SAML2Client.initIdentityProviderMetadataResolver(SAML2Client.java:221) at org.pac4j.saml.client.SAML2Client.internalInit(SAML2Client.java:115) at org.pac4j.core.util.InitializableObject.init(InitializableObject.java:61) at org.pac4j.core.util.InitializableObject.init(InitializableObject.java:38) at org.pac4j.core.client.IndirectClient.getRedirectionAction(IndirectClient.java:115) at org.pac4j.core.engine.DefaultSecurityLogic.redirectToIdentityProvider(DefaultSecurityLogic.java:240) at org.pac4j.core.engine.DefaultSecurityLogic.perform(DefaultSecurityLogic.java:160) Caused by: net.shibboleth.shared.component.ComponentInitializationException: Unable to unmarshall metadata element at org.opensaml.saml.metadata.resolver.impl.DOMMetadataResolver.initMetadataResolver(DOMMetadataResolver.java:67) at org.opensaml.saml.metadata.resolver.impl.AbstractMetadataResolver.doInitialize(AbstractMetadataResolver.java:373) at net.shibboleth.shared.component.AbstractInitializableComponent.initialize(AbstractInitializableComponent.java:62) at org.pac4j.saml.metadata.SAML2IdentityProviderMetadataResolver.initializeMetadataResolver(SAML2IdentityProviderMetadataResolver.java:103) Caused by: org.opensaml.core.xml.io.UnmarshallingException: Saw invalid child element {urn:oasis:names:tc:SAML:2.0:metadata}RoleDescriptor on parent {urn:oasis:names:tc:SAML:2.0:metadata}EntityDescriptor at org.opensaml.core.xml.io.AbstractXMLObjectUnmarshaller.processChildElement(AbstractXMLObjectUnmarshaller.java:383) at org.opensaml.saml.saml2.metadata.impl.EntityDescriptorUnmarshaller.processChildElement(EntityDescriptorUnmarshaller.java:64) at org.opensaml.core.xml.io.AbstractXMLObjectUnmarshaller.unmarshallChildElement(AbstractXMLObjectUnmarshaller.java:348) at org.opensaml.core.xml.io.AbstractXMLObjectUnmarshaller.unmarshall(AbstractXMLObjectUnmarshaller.java:139) at org.opensaml.saml.metadata.resolver.impl.DOMMetadataResolver.initMetadataResolver(DOMMetadataResolver.java:60)
排查日志更新
对比v5.7.7和v6.1.0的日志,发现差异出现在Pac4jHTTPPostDecoder - TokenController - Decoded SAML message之后:
- v5.7.7版本中有
SAML2IdentityProviderMetadataResolver和SAML2AuthnResponseValidator的相关日志 - v6.1.0版本中缺失这些日志,说明元数据初始化失败直接阻断了后续流程
导致问题的pac4j 6.x变更点
- OpenSAML版本升级:pac4j 6.x把依赖的OpenSAML从3.x升级到了4.x,新版本对SAML元数据的校验标准更严格。按照SAML 2.0规范,
EntityDescriptor的直接子元素应该是IDPSSODescriptor或SPSSODescriptor这类具体角色描述符,而非通用的RoleDescriptor,旧版本OpenSAML允许这种不规范结构,新版本直接判定为无效。 - 元数据解析逻辑收紧:pac4j 6.x的
SAML2IdentityProviderMetadataResolver不再自动兼容不符合规范的元数据结构,必须严格遵循SAML 2.0元数据规范才能完成初始化。
修复方案
- 修正ADFS元数据(推荐):联系ADFS管理员,重新生成符合SAML 2.0规范的元数据,确保
EntityDescriptor下直接包含的是IDPSSODescriptor而非通用的RoleDescriptor。 - 临时兼容配置:如果暂时无法修改ADFS元数据,可以通过自定义元数据解析器跳过无效元素校验:
// 自定义SAML元数据解析器,设置静默错误处理器跳过无效元素 SAML2IdentityProviderMetadataResolver resolver = new SAML2IdentityProviderMetadataResolver(resourceLoader, metadataResource) { @Override protected void initializeMetadataResolver(AbstractMetadataResolver metadataResolver) throws ComponentInitializationException { if (metadataResolver instanceof DOMMetadataResolver domResolver) { domResolver.setErrorHandler(new SilentErrorHandler()); } super.initializeMetadataResolver(metadataResolver); } }; - 检查pac4j配置:确认
SAML2Client的配置项完整,比如元数据签名校验、实体ID匹配等参数是否正确配置,避免因配置缺失导致的流程中断。
内容的提问来源于stack exchange,提问作者gaust
相关产品推荐
相关产品推荐

