XML签名元素验证不通过与XSD

3
我有一个XML文件,正在针对一个模式进行验证。然而,在我们的网站上,我们使用Fiddler来监控它所发出的请求,并注意到了很多请求,我认为这些请求与我们的XML和XSD定义有关。
这一切都与我想要使用Microsoft的SignedXML对象将签名添加到我从应用程序生成的XML有关。我在让签名验证方面遇到了问题,但通过下面的评论得到了一些帮助,最终解决了这个问题。不过现在出现了这个问题。
我尝试在Notepad++中进行验证,但只得到“无法解析架构文件”的错误信息。
我的XML内容如下:
<?xml version="1.0" encoding="utf-8"?>
<EngineRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" EngineVersion="6.0" RequestTime="2012-01-07T12:46:15.31868+13:00" xmlns="analysis.org.nz">
  <Analysis xmlns="">
  ... Various elements here
  </Analysis>
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
      <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
      <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <Reference URI="">
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <DigestValue>QDhgJy28UHmqhB2SA825mudXkr0=</DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue>fVxTK70NBoDuMw/76Sxx8lH5bWrEDbx2w+RfB1pkuUCLpjafG06U1PptjM0ndHMFGxWBa7lhaqyQV3fQOQ/KFzyYdeijQRXdOsV39Ex0GBhM+Ajo5YCdm6XfQaLheoSGaAf5TX7H7+mxwiFd71VENxWDWKmnQEVA3nUaWRumHOM=</SignatureValue>
  </Signature>
</EngineRequest>

我的XSD如下:

<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"            
            xmlns:tns="analysis.org.nz"
            xmlns:ds="http://www.w3.org/2000/09/xmldsig#"            
            targetNamespace="analysis.org.nz"
            attributeFormDefault="unqualified"
            >

  <xsd:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="http://www.mywebsite.co.nz/xsd/xmldsig-core-schema.xsd"/>

  <xsd:complexType name="AnalysisType">
  ... Various elements etc here
  </xsd:complexType>
   <xsd:element name="EngineRequest">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="Analysis" type="tns:AnalysisType" />
        <xsd:element ref="ds:Signature" minOccurs="0" maxOccurs="1" />
      </xsd:sequence>
      <xsd:attribute name="EngineVersion" type="xsd:string" />
      <xsd:attribute name="RequestTime"   type="xsd:dateTime" use="required"/>
    </xsd:complexType>
  </xsd:element>
</xsd:schema> 

Fiddler的输出为:
www.mywebsite.co.nz/xsd/xmldsig-core-schema.xsd
www.w3.org/2001/XMLSchema.dtd
www.w3.org/2001/datatypes
www.mywebsite.co.nz/xsd/xmldsig-core-schema.xsd

以下是我在代码端进行验证的C#代码,我认为这可能导致Fiddler中看到多个请求:
public static bool Validate(String input)
    {
        _isValid = true; // set to false if any error occurs
        _message.Clear();

        StringReader xml = new StringReader(input);

        // load embedded schema resource to validate against
        Assembly assembly = Assembly.GetExecutingAssembly();

        // validation settings
        XmlReaderSettings settings = new XmlReaderSettings();            
        settings.ValidationType = ValidationType.Schema;

        settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
        settings.ValidationEventHandler += new System.Xml.Schema.ValidationEventHandler(ValidationEventHandler);

        // add schemas for validation
        AddSchema(assembly, settings);
        AddSignatureSchema(assembly, settings);

        // create xml validation reader            
        XmlReader reader = XmlReader.Create(xml, settings);

        // validation node by node
        while (reader.Read()) ;

        reader.Close();

        return IsValid;
    }

    private static void AddSchema(Assembly assembly, XmlReaderSettings settings)
    {
        Stream xsdStream = assembly.GetManifestResourceStream("Engine.Schema.Engine.xsd");
        XmlReader xsdReader = XmlReader.Create(xsdStream);

        settings.Schemas.Add("mywebsite.org.nz", xsdReader);
    }

    private static void AddSignatureSchema(Assembly assembly, XmlReaderSettings settings)
    {
        XmlReaderSettings sigSettings = new XmlReaderSettings()
        {
            ValidationType = ValidationType.DTD,
            DtdProcessing = DtdProcessing.Parse
        };

        Stream sigStream = assembly.GetManifestResourceStream("Engine.Schema.xmldsig-core-schema.xsd");
        XmlReader sigReader = XmlReader.Create(sigStream, sigSettings); 

        settings.Schemas.Add(null, sigReader); // signature schema

    }

理想情况下,我不想以那种方式导入Signature命名空间,但如果不这样做,我就无法访问Signature元素。当我尝试创建自己的Signature元素以匹配xmldsig-core-schema时,由于Microsoft SignedXML()对象将xmlns="http://www.w3.org/2000/09/xmldsig#"错误放置在生成的XML中,我遇到了验证错误。
注意:由于我修改了XML和XSD后错误稍有改变,因此更新了此问题。然而,我的问题仍然存在,即我很难添加看似简单的东西?

你能否发布更多的XSD文件?看起来你没有为Signature元素定义。根据所显示的内容,似乎一个请求只能有以下子元素:Analysis、EngineVersion和RequestTime。此外,空闭合标签(</>)是你的XML的一部分还是仅仅是缩写? - bakoyaro
谢谢你,笨蛋。当我取消注释并添加定义时,我的C#代码会出现“SignatureType未声明”的错误。我想我可能需要将包含SignatureType声明的XSD添加到Schemas.Add()中? - dreza
你的XSD中如何声明SignatureType?我在你发布的版本中没有看到它。 - bakoyaro
我已经在我的XSD中添加了签名元素,但仍然收到相同的错误。 - dreza
2个回答

2
你有几个问题:
XSD说:
- {mynamespace}Request必须是根元素。 - {mynamespace}Analysis必须在Signature之前。

谢谢 David。我已经稍微更改了一下,因为我认为我发布的信息可能存在问题。不过仍然存在一个问题。 - dreza

1

问题似乎与AddSignatureSchema()方法有关。每次调用它时都会导致下载位于http://www.mywebsite.co.nz/xsd/xmldsig-core-schema.xsd的DTD。

我所要做的就是将XMLResolver设置为null,这样可以防止发生下载。我从解析xml时防止DTD下载的另一个问题中发现了这一点。

我还设置了DtdProcessing = DtdProcessing.Ignore标志。该方法看起来像

    private static void AddSignatureSchema(Assembly assembly, XmlReaderSettings settings)
    {
        XmlReaderSettings sigSettings = new XmlReaderSettings()
        {
            ValidationType = ValidationType.DTD,
            DtdProcessing = DtdProcessing.Ignore
        };

        // Prevent the DTD from downloading
        sigSettings.XmlResolver = null;

        Stream sigStream = assembly.GetManifestResourceStream("Engine.Schema.xmldsig-core-schema.xsd");
        XmlReader sigReader = XmlReader.Create(sigStream, sigSettings); 

        settings.Schemas.Add(null, sigReader); // signaturte schema

    }

我也在使用XML签名。我必须首先根据模式验证已签名的文档。但是,我一直收到“Anontype ReferenceSignedInfoSignature”的内容无效的错误。但是,在输入的XML文档中,引用元素中没有任何内容,它只包含一个转换元素。那么为什么会出现这个错误(异常)? - Ashwin
@Ashwin,你的元素声明允许minOccurs=0吗?很抱歉,没有更多信息很难知道。也许最好创建一个新问题,包括你的xml和xsd声明以及出现的错误消息? - dreza
我的同事已经发布了这个问题。请查看链接 http://stackoverflow.com/questions/10779764/xml-schema-validation-error - Ashwin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接