Bonjour je ne sais pas comment générer la signature dans mon header de ma Soap.
En suivant un tutorial, j'ai commencé par générer le service avec la commande :
Code : Sélectionner tout - Visualiser dans une fenêtre à part wsimport -keep -verbose https://blabla.wsdl
Puis j'ai créé mon client :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 import search.ByRegisterNumberRequest; import search.DetailPersonResponse; import search.SearchByRegisterNumberVer1; import search.SearchByRegisterNumberVer1Service; import org.apache.log4j.Logger; public class WsClient{ private static Logger log = Logger.getLogger(WsClient.class); public static void main(String[] args) throws Exception { SearchByRegisterNumberVer1Service sis = new SearchByRegisterNumberVer1Service(); SearchByRegisterNumberVer1 si = sis.getSearchByRegisterNumberVer1Port(); ByRegisterNumberRequest params = new ByRegisterNumberRequest(); params.setRegisterNumber("0123456789"); params.setType("RPREG"); DetailPersonResponse personne = si.searchByRegisterNumber(params); log.debug(personne); log.debug(personne.getBase()); log.debug(personne.getBase().getCode()); log.debug(personne.getBase().getWarning()); log.debug(personne.getBase().getError()); log.debug(personne.getPerson()); } }
Je doit réussir à avoir un message équivalent à :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 <soapenv:Header xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa="http://www.w3.org/2005/08/addressing"> <wsse:UsernameToken wsu:Id="USER-ID"> <wsse:Username>TOKEN</wsse:Username> <wsse:Password Type="wsse:PasswordDigest">ga4nbiCyh6JPPgOhaNQWS1DEXu8=</wsse:Password> <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">MzY4ODQ1NTcwNjk4ODk2MjkwNTc0NTc3MzQ0MTI0MjM1MjUyMzU=</wsse:Nonce> <wsu:Created>2011-11-24T08:59:52Z</wsu:Created> </wsse:UsernameToken> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <ds:Reference URI="#USER-ID"> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <ds:DigestValue>XoTwpTnzHBZtcM/jf8A95HA0OpE=</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>QA2/WeCFc+xdYoCkAUBSa1KSA4UYNPhH1rLZSBRzXsAjnZyJJyF8mntvIcuXxAWVzxabEZ19qtXWT7xEhQo2DbbxqlNGIvNB3UIj68AHeQ5H3fkIDN3FuOwWbKJqz388dTb3NeyYcDJCiFB6wDqa9t1WlWEUdk1nIJJER5Puj+I80yL1qCPSwukqFlLOGpzttpc7SQNTk85QEs+nKhe2kH8uvKjiMaD6OPKXSYkrjJoL2tYTQjpi66htA42LzLt/GRr8Fz+Vc4lEI50/TNb+JS9mNSdJSNMvi3xCEFCbXFZ/iW0Y4Te8BuMnDH7cV4DYr8k8jteisN/jhwjC23YMDw==</ds:SignatureValue> </ds:Signature> </wsse:Security> </soapenv:Header>
J'ai donc en suivant un tutorial ajouter l'annotation HandlerChain(file="handler-chain.xml") dans mon service.
Créé le fichier xml suivant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <javaee:handler-chains xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <javaee:handler-chain> <javaee:handler> <javaee:handler-class>SecurityHandler</javaee:handler-class> </javaee:handler> </javaee:handler-chain> </javaee:handler-chains>
et la class SecurityHandler suivante :
Il me reste donc à générer :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156 import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.Set; import java.util.TimeZone; import javax.xml.namespace.QName; import javax.xml.soap.SOAPElement; import javax.xml.soap.SOAPEnvelope; import javax.xml.soap.SOAPHeader; import javax.xml.soap.SOAPMessage; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.handler.soap.SOAPHandler; import javax.xml.ws.handler.soap.SOAPMessageContext; public class SecurityHandler implements SOAPHandler<SOAPMessageContext>{ @Override public boolean handleMessage(SOAPMessageContext context) { Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); if (outboundProperty.booleanValue()) { SOAPMessage message = context.getMessage(); try { SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope(); envelope.addNamespaceDeclaration("soapenc", "http://schemas.xmlsoap.org/soap/encoding/"); envelope.addNamespaceDeclaration("xsd", "http://www.w3.org/2001/XMLSchema"); envelope.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema-instance"); SOAPHeader header = envelope.addHeader(); SOAPElement security = header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); security.addNamespaceDeclaration("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"); security.addNamespaceDeclaration("wsa", "http://www.w3.org/2005/08/addressing"); security.addNamespaceDeclaration("ds", "http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd"); /** * 1er Niveau USERNAMETOKEN !! */ SOAPElement usernameToken = security.addChildElement("UsernameToken", "wsse"); usernameToken.addAttribute(new QName("wsu:Id"), "USER-ID"); SOAPElement username = usernameToken.addChildElement("Username", "wsse"); /** * Le token !! */ username.addTextNode("TOKEN"); SOAPElement password = usernameToken.addChildElement("Password", "wsse"); password.setAttribute("Type", "wsse:PasswordDigest"); /** * The Password element is filled according to the OASIS rules. It contains a Base64 encoded value of the SHA-1 hash of the string composed as Base64 decoded value of nonce + created (timestamp) + realPassword. See OASIS documentation for details. */ String nonceString = createNonce(30); String timestamp = createSoapTimestamp(); String pass = "opif"; byte[] tmp = java.security.MessageDigest.getInstance("SHA1").digest((nonceString + timestamp + pass).getBytes()); password.addTextNode(new sun.misc.BASE64Encoder().encode(tmp)); SOAPElement nonce = usernameToken.addChildElement("Nonce", "wsse"); nonce.setAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"); nonce.addTextNode(new sun.misc.BASE64Encoder().encode(nonceString.getBytes())); SOAPElement created = usernameToken.addChildElement("Created", "wsu"); created.addTextNode(timestamp); /** * 2eme Niveau : SIGNATURE, Comment la générer ? */ //Print out the outbound SOAP message to System.out message.writeTo(System.out); System.out.println(""); } catch (Exception e) { e.printStackTrace(); } } else { try { //This handler does nothing with the response from the Web Service so //we just print out the SOAP message. SOAPMessage message = context.getMessage(); message.writeTo(System.out); System.out.println(""); } catch (Exception ex) { ex.printStackTrace(); } } return outboundProperty; } public static String createSoapTimestamp() { String fmt = "yyyy-MM-dd'T'HH:mm:ss.000'Z'"; SimpleDateFormat df = new SimpleDateFormat(fmt, Locale.US); df.setTimeZone(TimeZone.getTimeZone("UTC")); String date = df.format(new Date()); return date; } public static String createNonce(int length) { final String CHARS = "01234567890abcdefghijkmlmnopqrstuvwxyz"; StringBuilder sb = new StringBuilder(); for(int i=0; i < length; i++) sb.append(CHARS.charAt((int)(Math.random()*CHARS.length()))); return sb.toString(); } @Override public boolean handleFault(SOAPMessageContext context) { System.out.println("Client : handleFault()......"); return true; } @Override public void close(MessageContext context) { System.out.println("Client : close()......"); } @Override public Set<QName> getHeaders() { System.out.println("Client : getHeaders()......"); return null; } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <ds:Reference URI="#USER-ID"> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/> <ds:DigestValue>XoTwpTnzHBZtcM/jf8A95HA0OpE=</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>QA2/WeCFc+xdYoCkAUBSa1KSA4UYNPhH1rLZSBRzXsAjnZyJJyF8mntvIcuXxAWVzxabEZ19qtXWT7xEhQo2DbbxqlNGIvNB3UIj68AHeQ5H3fkIDN3FuOwWbKJqz388dTb3NeyYcDJCiFB6wDqa9t1WlWEUdk1nIJJER5Puj+I80yL1qCPSwukqFlLOGpzttpc7SQNTk85QEs+nKhe2kH8uvKjiMaD6OPKXSYkrjJoL2tYTQjpi66htA42LzLt/GRr8Fz+Vc4lEI50/TNb+JS9mNSdJSNMvi3xCEFCbXFZ/iW0Y4Te8BuMnDH7cV4DYr8k8jteisN/jhwjC23YMDw==</ds:SignatureValue> </ds:Signature>
Comment générer la signature? A quoi correspond digestValue et SignatureValue ?
Partager