Java解析无类型SAML属性值返回null的非客户端修改解决方案咨询
解决JAXB解析无类型SAML AttributeValue返回null的问题
我之前处理SAML断言时也碰到过一模一样的情况——客户端发送的AttributeValue没指定类型,完全符合标准但JAXB解析出来就是null。不用强制客户端修改的话,这几个方案应该能帮到你:
1. 自定义JAXB XmlAdapter处理无类型值
JAXB默认对带类型的AttributeValue处理更顺畅,但无类型的情况可以通过适配器强制提取文本内容。
首先创建一个适配器类:
import javax.xml.bind.annotation.adapters.XmlAdapter; import org.w3c.dom.Element; public class AttributeValueAdapter extends XmlAdapter<Element, String> { @Override public String unmarshal(Element element) { // 直接提取节点的文本内容 return element.getTextContent().trim(); } @Override public Element marshal(String value) { // 如果需要生成断言的话实现这个方法,仅解析用可留空或抛出异常 throw new UnsupportedOperationException("Not implemented"); } }
然后在你的SAML AttributeValue对应的JAXB实体类上添加注解:
@XmlElement(name = "AttributeValue", namespace = "urn:oasis:names:tc:SAML:2.0:assertion") @XmlJavaTypeAdapter(AttributeValueAdapter.class) private String attributeValue;
这样JAXB在解析时就会通过适配器把无类型的AttributeValue节点的文本内容提取出来,不会返回null了。
2. 绕过JAXB,直接用DOM API提取值
如果不想修改JAXB实体类,也可以在解析完成后,直接操作DOM节点获取值。比如当你用JAXB解析完断言后,拿到对应的Attribute节点的DOM对象:
// 假设你已经解析得到了samlAttribute对象(JAXB生成的Attribute类) Element attributeElement = (Element) JAXBIntrospector.getValue(samlAttribute); NodeList valueNodes = attributeElement.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:assertion", "AttributeValue"); if (valueNodes.getLength() > 0) { String attributeValue = valueNodes.item(0).getTextContent().trim(); // 这里就拿到了属性值 }
这种方法比较直接,适合临时快速解决问题,不用改动现有的JAXB映射配置。
3. 修改JAXB绑定配置文件
如果你的JAXB实体类是通过XSD生成的,可以通过外部绑定文件(binding.xml)来指定无类型AttributeValue的处理方式。比如:
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" version="2.1"> <jaxb:bindings schemaLocation="saml-schema-assertion-2.0.xsd" node="/xsd:schema"> <!-- 针对无类型的AttributeValue,绑定到String类型 --> <jaxb:bindings node="//xsd:element[@name='AttributeValue']"> <jaxb:property> <jaxb:baseType name="java.lang.String"/> </jaxb:property> </jaxb:bindings> </jaxb:bindings> </jaxb:bindings>
然后在生成JAXB实体类的时候指定这个绑定文件,生成的类就会自动把无类型的AttributeValue解析为String,不会返回null。
这三个方案都是在服务端处理,完全不需要客户端修改他们的SAML断言格式,你可以根据自己的代码架构选最适合的那个。
内容的提问来源于stack exchange,提问作者uriBaba
相关产品推荐
相关产品推荐

