2009-10-20 66 views
1

我有使用Python標準模塊(不使用ElementTree的,LXML等)的元數據是一個SAML身份提供元數據和的形式來寫一個xml文件的XML文件 -寫使用python

<?xml version="1.0"?> 
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" 
    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" 
    xmlns:ds="http://www.w3.org/2000/09/xmldsig#" 
    entityID="http://wsa.saas.com"> 
<IDPSSODescriptor> 
<KeyDescriptor use="signing"> 
    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
     <ds:X509Data><ds:X509Certificate>-----BEGIN CERTIFICATE----- 
MIIDnjCCAoagAwIBAgIBATANBgkqhkiG9w0BAQUFADBUMQswCQYDVQQGEwJGUjEP 
MA0GA1UECBMGRnJhbmNlMQ4wDAYDVQQHEwVQYXJpczETMBEGA1UEChMKRW50cm91 
dmVydDEPMA0GA1UEAxMGRGFtaWVuMB4XDTA2MTAyNzA5MDc1NFoXDTExMTAyNjA5 
MDc1NFowVDELMAkGA1UEBhMCRlIxDzANBgNVBAgTBkZyYW5jZTEOMAwGA1UEBxMF 
UGFyaXMxEzARBgNVBAoTCkVudHJvdXZlcnQxDzANBgNVBAMTBkRhbWllbjCCASIw 
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM06Hx6VgHYR9wUf/tZVVTRkVWNq 
h9x+PvHA2qH4OYMuqGs4Af6lU2YsZvnrmRdcFWv0+UkdAgXhReCWAZgtB1pd/W9m 
6qDRldCCyysow6xPPKRz/pOTwRXm/fM0QGPeXzwzj34BXOIOuFu+n764vKn18d+u 
uVAEzk1576pxTp4pQPzJfdNLrLeQ8vyCshoFU+MYJtp1UA+h2JoO0Y8oGvywbUxH 
ioHN5PvnzObfAM4XaDQohmfxM9Uc7Wp4xKAc1nUq5hwBrHpjFMRSz6UCfMoJSGIi 
+3xJMkNCjL0XEw5NKVc5jRKkzSkN5j8KTM/k1jPPsDHPRYzbWWhnNtd6JlkCAwEA 
AaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0 
ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFP2WWMDShux3iF74+SoO1xf6qhqaMB8G 
A1UdIwQYMBaAFGjl6TRXbQDHzSlZu+e8VeBaZMB5MA0GCSqGSIb3DQEBBQUAA4IB 
AQAZ/imK7UMognXbs5RfSB8cMW6iNAI+JZqe9XWjvtmLfIIPbHM96o953SiFvrvQ 
BZjGmmPMK3UH29cjzDx1R/RQaYTyMrHyTePLh3BMd5mpJ/9eeJCSxPzE2ECqWRUa 
pkjukecFXqmRItwgTxSIUE9QkpzvuQRb268PwmgroE0mwtiREADnvTFkLkdiEMew 
fiYxZfJJLPBqwlkw/7f1SyzXoPXnz5QbNwDmrHelga6rKSprYKb3pueqaIe8j/AP 
NC1/bzp8cGOcJ88BD5+Ny6qgPVCrMLE5twQumJ12V3SvjGNtzFBvg2c/9S5OmVqR 
LlTxKnCrWAXftSm1rNtewTsF 
-----END CERTIFICATE----- 
</ds:X509Certificate></ds:X509Data> 
    </ds:KeyInfo> 
    </KeyDescriptor> 

    <SingleSignOnService 
    Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" 
    Location="http://idp5/singleSignOn" /> 
</IDPSSODescriptor> 
</EntityDescriptor> 

我目前代碼做到這一點 -

>>> from xml.dom.minidom import Document 
>>> doc = Document() 
>>> entity_descriptor = doc.createElement("EntityDescriptor") 
>>> doc.appendChild(entity_descriptor) 
>>> entity_descriptor.setAttribute('xmlns', 'urn:oasis:names:tc:SAML:2.0:metadata') 
>>> entity_descriptor.setAttribute('xmlns:saml', 'urn:oasis:names:tc:SAML:2.0:assertion') 
>>> entity_descriptor.setAttribute('xmlns:ds', 'hxxp://xxx.w3.org/2000/09/xmldsig#') 
>>> entity_descriptor.setAttribute('entityID', 'hxxp://wsa.saas.com') 
>>> idpssodescr = doc.createElement('IDPSSODescriptor') 
>>> entity_descriptor.appendChild(idpssodescr) 
>>> keydescr = doc.createElement('KeyDescriptor') 
>>> keydescr.setAttribute('use', 'signing') 
>>> idpssodescr.appendChild(keydescr) 
>>> keyinfo = doc.createElement('ds:KeyInfo') 
>>> keyinfo.setAttribute('xmlns:ds', 'http://xxx.w3.org/2000/09/xmldsig#') 
>>> keydescr.appendChild(keyinfo) 
>>> x509data = doc.createElement('ds:X509Data') 
>>> keyinfo.appendChild(x509data) 
>>> x509cert = doc.createElement('ds:X509Certificate') 
>>> ptext = doc.createTextNode("This is a test!") 
>>> x509cert.appendChild(ptext) 
>>> x509data.appendChild(x509cert) 
>>> sso = doc.createElement('SingleSignOnService') 
>>> sso.setAttribute('Binding', 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect') 
>>> sso.setAttribute('Location', 'hxxx://idp5/singleSignOn') 
>>> idpssodescr.appendChild(sso) 
>>> print doc.toprettyxml(indent=" ") 
<?xml version="1.0" ?> 
<EntityDescriptor entityID="http://wsa.saas.com" xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> 
    <IDPSSODescriptor> 
    <KeyDescriptor use="signing"> 
     <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
     <ds:X509Data> 
      <ds:X509Certificate> 
      This is a test! 
      </ds:X509Certificate> 
     </ds:X509Data> 
     </ds:KeyInfo> 
    </KeyDescriptor> 
    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://idp5/singleSignOn"/> 
    </IDPSSODescriptor> 
</EntityDescriptor> 

我與證書的部分有點困惑。原來是<ds:X509Certificate>-----BEGIN CERTIFICATE---.....</ds:X509Certificate> 和我的是:

<ds:X509Certificate> 
    This is the cert 
</ds:X509Certificate> 

對不起,我沒有與XML太多經驗。 代碼是否適用於預期的任務。

謝謝。

+0

請使用代碼標籤 - 這是不可能的閱讀源 – shylent

+0

@OP:後是固定的。請,現在不要打破。 – SilentGhost

回答

2

好嗎?你的問題是什麼?在這兩條線:

>>> ptext = doc.createTextNode("This is a test!") 
>>> x509cert.appendChild(ptext) 

你是,的確,創建一個文本節點作爲一個節點"<ds:X509Certificate>" 的孩子。文本節點的內容是「這是一個測試!」。如果您希望將其他內容插入爲文本內容,則必須使用適當的參數調用.createTextNode。

編輯(考慮到OP的評論): 不,它不是文本內容。在XML中,一切都是一個節點。你認爲「標籤之間的文本」實際上是一個文本節點

0

只是爲了歸檔,我以前的代碼丟失了一個小小的更改,這就是爲什麼證書被拒絕。

from xml.dom.minidom import Document 
doc = Document() 
entity_descriptor = doc.createElement("EntityDescriptor") 
doc.appendChild(entity_descriptor) 
entity_descriptor.setAttribute('xmlns', 'urn:oasis:names:tc:SAML:2.0:metadata') 
entity_descriptor.setAttribute('xmlns:saml', 'urn:oasis:names:tc:SAML:2.0:assertion') 
entity_descriptor.setAttribute('xmlns:ds', 'http://www.w3.org/2000/09/xmldsig#') 
entity_descriptor.setAttribute('entityID', 'http://wsa.saas.com') 
idpssodescr = doc.createElement('IDPSSODescriptor') 
idpssodescr.setAttribute('WantAuthnRequestsSigned', 'true') 
idpssodescr.setAttribute('protocolSupportEnumeration', 
'urn:oasis:names:tc:SAML:2.0:protocol') 
entity_descriptor.appendChild(idpssodescr) 
keydescr = doc.createElement('KeyDescriptor') 
keydescr.setAttribute('use', 'signing') 
idpssodescr.appendChild(keydescr) 
keyinfo = doc.createElement('ds:KeyInfo') 
keyinfo.setAttribute('xmlns:ds', 'http://www.w3.org/2000/09/xmldsig#') 
keydescr.appendChild(keyinfo) 
x509data = doc.createElement('ds:X509Data') 
keyinfo.appendChild(x509data) 
x509cert = doc.createElement('ds:X509Certificate') 

# Read the certificate from some file. 
fp = file('idp.crt.pem', 'r') 
s = '' 
for i in fp.readlines(): 
    s+=''.join(i) 


ptext = doc.createTextNode(s) 
x509cert.appendChild(ptext) 
x509data.appendChild(x509cert) 
sso = doc.createElement('SingleSignOnService') 
sso.setAttribute('Binding', 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect') 
sso.setAttribute('Location', 'http://idp5/singleSignOn') 
idpssodescr.appendChild(sso) 

print doc.toprettyxml(indent=" ") 
<?xml version="1.0" ?> 
<EntityDescriptor entityID="http://wsa.saas.com" 
xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09 
/xmldsig#" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> 
<IDPSSODescriptor WantAuthnRequestsSigned="true"  
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"> 
<KeyDescriptor use="signing"> 
    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
    <ds:X509Data> 
     <ds:X509Certificate> 
     -----BEGIN CERTIFICATE----- 
MIICfTCCAeagAwIBAgIJAPEn4h3J3p2dMA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV 
BAYTAmFhMQswCQYDVQQKEwJhYTELMAkGA1UECxMCYWExCzAJBgNVBAMTAmFhMB4X 
DTA5MTAxOTA4NTI1M1oXDTEwMTAxOTA4NTI1M1owNDELMAkGA1UEBhMCYWExCzAJ 
BgNVBAoTAmFhMQswCQYDVQQLEwJhYTELMAkGA1UEAxMCYWEwgZ8wDQYJKoZIhvcN 
AQEBBQADgY0AMIGJAoGBAMerInhZF/l0O0jmiD8M1lSSpHjFcT0peiwqWq+LZ8Ay 
b6mcpnHdFVmHQaGtUt+6i+0NqKDppxnaVW4vOdYD64OlmSVrG+WzkYMAmE/0EzJN 
A5pEA5ZK1w6MGo+IQLjrPDmm/qV6XrkARR2THjA2xKE8/L7s+VEJj/d+/CC8V7vP 
AgMBAAGjgZYwgZMwHQYDVR0OBBYEFOHoipN0T0TNs1IwFkmTwLDtsV0gMGQGA1Ud 
IwRdMFuAFOHoipN0T0TNs1IwFkmTwLDtsV0goTikNjA0MQswCQYDVQQGEwJhYTEL 
MAkGA1UEChMCYWExCzAJBgNVBAsTAmFhMQswCQYDVQQDEwJhYYIJAPEn4h3J3p2d 
MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEANTQgpYm+OBZTTYbLkyBH 
MQ9QygwgNWOQJ9hEbT0xpiL8xHXBTQdHJkMXD/PWzs1AyZShXsUwcKBaKgxyIsQj 
a36poKPyfAYbfsg8xLyijMVXbsW7OlKN9FjapaZTnEvHfsMO8ITAad4a7RVWAYQ8 
ucT7nO9OPFjOv8dwGsF5RVM= 
-----END CERTIFICATE----- 

     </ds:X509Certificate> 
    </ds:X509Data> 
    </ds:KeyInfo> 
</KeyDescriptor> 
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" 
Location="http://idp5/singleSignOn"/> 
</IDPSSODescriptor> 
</EntityDescriptor> 

x = open('metadata.xml', 'w') 
doc.writexml(x, " ", "", "\n", "UTF-8") 
x.close() 
0

Yattag是能爲這個

from yattag import Doc, indent 

doc, tag, text = Doc().tagtext() 

doc.asis('<?xml version="1.0"?>') 
with tag('EntityDescriptor', 
     ("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion"), 
     ("xmlns:ds", "http://www.w3.org/2000/09/xmldsig#"), 
     entityID = "http://wsa.saas.com", 
     xmlns = "urn:oasis:names:tc:SAML:2.0:metadata"): 
    with tag('IDPSSODescriptor'): 
     with tag('KeyDescriptor', use='signing'): 
      with tag('ds:KeyInfo', 
        ("xmlns:ds", "http://www.w3.org/2000/09/xmldsig#")): 
       with tag('ds:X509Data'): 
        with tag('ds:X509Certificate'): 
         text(
"""-----BEGIN CERTIFICATE----- 
MIIDnjCCAoagAwIBAgIBATANBgkqhkiG9w0BAQUFADBUMQswCQYDVQQGEwJGUjEP 
MA0GA1UECBMGRnJhbmNlMQ4wDAYDVQQHEwVQYXJpczETMBEGA1UEChMKRW50cm91 
dmVydDEPMA0GA1UEAxMGRGFtaWVuMB4XDTA2MTAyNzA5MDc1NFoXDTExMTAyNjA5 
MDc1NFowVDELMAkGA1UEBhMCRlIxDzANBgNVBAgTBkZyYW5jZTEOMAwGA1UEBxMF 
UGFyaXMxEzARBgNVBAoTCkVudHJvdXZlcnQxDzANBgNVBAMTBkRhbWllbjCCASIw 
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM06Hx6VgHYR9wUf/tZVVTRkVWNq 
h9x+PvHA2qH4OYMuqGs4Af6lU2YsZvnrmRdcFWv0+UkdAgXhReCWAZgtB1pd/W9m 
6qDRldCCyysow6xPPKRz/pOTwRXm/fM0QGPeXzwzj34BXOIOuFu+n764vKn18d+u 
uVAEzk1576pxTp4pQPzJfdNLrLeQ8vyCshoFU+MYJtp1UA+h2JoO0Y8oGvywbUxH 
ioHN5PvnzObfAM4XaDQohmfxM9Uc7Wp4xKAc1nUq5hwBrHpjFMRSz6UCfMoJSGIi 
+3xJMkNCjL0XEw5NKVc5jRKkzSkN5j8KTM/k1jPPsDHPRYzbWWhnNtd6JlkCAwEA 
AaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0 
ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFP2WWMDShux3iF74+SoO1xf6qhqaMB8G 
A1UdIwQYMBaAFGjl6TRXbQDHzSlZu+e8VeBaZMB5MA0GCSqGSIb3DQEBBQUAA4IB 
AQAZ/imK7UMognXbs5RfSB8cMW6iNAI+JZqe9XWjvtmLfIIPbHM96o953SiFvrvQ 
BZjGmmPMK3UH29cjzDx1R/RQaYTyMrHyTePLh3BMd5mpJ/9eeJCSxPzE2ECqWRUa 
pkjukecFXqmRItwgTxSIUE9QkpzvuQRb268PwmgroE0mwtiREADnvTFkLkdiEMew 
fiYxZfJJLPBqwlkw/7f1SyzXoPXnz5QbNwDmrHelga6rKSprYKb3pueqaIe8j/AP 
NC1/bzp8cGOcJ88BD5+Ny6qgPVCrMLE5twQumJ12V3SvjGNtzFBvg2c/9S5OmVqR 
LlTxKnCrWAXftSm1rNtewTsF 
-----END CERTIFICATE----- 
""") 
    with tag('SingleSignOnService', 
     Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", 
     Location="http://idp5/singleSignOn" 
    ): 
     pass 


result = indent(
    doc.getvalue(), 
    indentation = ' '*4, 
    newline = '\r\n' 
) 

print(result) 

很有趣你得到:

<?xml version="1.0"?> 
<EntityDescriptor xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" entityID="http://wsa.saas.com" xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
    <IDPSSODescriptor> 
     <KeyDescriptor use="signing"> 
      <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
       <ds:X509Data> 
        <ds:X509Certificate>-----BEGIN CERTIFICATE----- 
MIIDnjCCAoagAwIBAgIBATANBgkqhkiG9w0BAQUFADBUMQswCQYDVQQGEwJGUjEP 
MA0GA1UECBMGRnJhbmNlMQ4wDAYDVQQHEwVQYXJpczETMBEGA1UEChMKRW50cm91 
dmVydDEPMA0GA1UEAxMGRGFtaWVuMB4XDTA2MTAyNzA5MDc1NFoXDTExMTAyNjA5 
MDc1NFowVDELMAkGA1UEBhMCRlIxDzANBgNVBAgTBkZyYW5jZTEOMAwGA1UEBxMF 
UGFyaXMxEzARBgNVBAoTCkVudHJvdXZlcnQxDzANBgNVBAMTBkRhbWllbjCCASIw 
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM06Hx6VgHYR9wUf/tZVVTRkVWNq 
h9x+PvHA2qH4OYMuqGs4Af6lU2YsZvnrmRdcFWv0+UkdAgXhReCWAZgtB1pd/W9m 
6qDRldCCyysow6xPPKRz/pOTwRXm/fM0QGPeXzwzj34BXOIOuFu+n764vKn18d+u 
uVAEzk1576pxTp4pQPzJfdNLrLeQ8vyCshoFU+MYJtp1UA+h2JoO0Y8oGvywbUxH 
ioHN5PvnzObfAM4XaDQohmfxM9Uc7Wp4xKAc1nUq5hwBrHpjFMRSz6UCfMoJSGIi 
+3xJMkNCjL0XEw5NKVc5jRKkzSkN5j8KTM/k1jPPsDHPRYzbWWhnNtd6JlkCAwEA 
AaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0 
ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFP2WWMDShux3iF74+SoO1xf6qhqaMB8G 
A1UdIwQYMBaAFGjl6TRXbQDHzSlZu+e8VeBaZMB5MA0GCSqGSIb3DQEBBQUAA4IB 
AQAZ/imK7UMognXbs5RfSB8cMW6iNAI+JZqe9XWjvtmLfIIPbHM96o953SiFvrvQ 
BZjGmmPMK3UH29cjzDx1R/RQaYTyMrHyTePLh3BMd5mpJ/9eeJCSxPzE2ECqWRUa 
pkjukecFXqmRItwgTxSIUE9QkpzvuQRb268PwmgroE0mwtiREADnvTFkLkdiEMew 
fiYxZfJJLPBqwlkw/7f1SyzXoPXnz5QbNwDmrHelga6rKSprYKb3pueqaIe8j/AP 
NC1/bzp8cGOcJ88BD5+Ny6qgPVCrMLE5twQumJ12V3SvjGNtzFBvg2c/9S5OmVqR 
LlTxKnCrWAXftSm1rNtewTsF 
-----END CERTIFICATE----- 
</ds:X509Certificate> 
       </ds:X509Data> 
      </ds:KeyInfo> 
     </KeyDescriptor> 
    </IDPSSODescriptor> 
    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://idp5/singleSignOn"></SingleSignOnService> 
</EntityDescriptor>