1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.wss4j.stax.impl.processor.output;
20
21 import java.util.ArrayList;
22 import java.util.List;
23
24 import javax.xml.namespace.QName;
25 import javax.xml.stream.XMLStreamException;
26
27 import org.apache.wss4j.stax.ext.WSSConstants;
28 import org.apache.wss4j.stax.ext.WSSSecurityProperties;
29 import org.apache.wss4j.stax.impl.securityToken.KerberosClientSecurityToken;
30 import org.apache.wss4j.stax.securityToken.WSSecurityTokenConstants;
31 import org.apache.wss4j.stax.utils.WSSUtils;
32 import org.apache.xml.security.exceptions.XMLSecurityException;
33 import org.apache.xml.security.stax.ext.AbstractOutputProcessor;
34 import org.apache.xml.security.stax.ext.OutputProcessorChain;
35 import org.apache.xml.security.stax.ext.XMLSecurityConstants;
36 import org.apache.xml.security.stax.ext.stax.XMLSecAttribute;
37 import org.apache.xml.security.stax.ext.stax.XMLSecEvent;
38 import org.apache.xml.security.stax.impl.securityToken.GenericOutboundSecurityToken;
39 import org.apache.xml.security.stax.securityToken.OutboundSecurityToken;
40 import org.apache.xml.security.stax.securityToken.SecurityTokenProvider;
41 import org.apache.xml.security.utils.XMLUtils;
42
43 public class BinarySecurityTokenOutputProcessor extends AbstractOutputProcessor {
44
45 public BinarySecurityTokenOutputProcessor() throws XMLSecurityException {
46 super();
47 addBeforeProcessor(WSSSignatureOutputProcessor.class);
48 }
49
50 @Override
51 public void processEvent(XMLSecEvent xmlSecEvent, OutputProcessorChain outputProcessorChain)
52 throws XMLStreamException, XMLSecurityException {
53 try {
54 GenericOutboundSecurityToken securityToken = null;
55
56 XMLSecurityConstants.Action action = getAction();
57 String tokenId = null;
58 if (WSSConstants.SIGNATURE.equals(action)
59 || WSSConstants.SAML_TOKEN_SIGNED.equals(action)) {
60 tokenId = outputProcessorChain.getSecurityContext().get(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_SIGNATURE);
61 } else if (WSSConstants.ENCRYPTION.equals(action)) {
62 tokenId = outputProcessorChain.getSecurityContext().get(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_ENCRYPTED_KEY);
63 } else if (WSSConstants.ENCRYPTION_WITH_KERBEROS_TOKEN.equals(getAction())
64 || WSSConstants.SIGNATURE_WITH_KERBEROS_TOKEN.equals(getAction())
65 || WSSConstants.KERBEROS_TOKEN.equals(getAction())) {
66 tokenId = outputProcessorChain.getSecurityContext().get(WSSConstants.PROP_USE_THIS_TOKEN_ID_FOR_KERBEROS);
67 }
68
69 SecurityTokenProvider<OutboundSecurityToken> tokenProvider = null;
70 if (tokenId != null) {
71 tokenProvider =
72 outputProcessorChain.getSecurityContext().getSecurityTokenProvider(tokenId);
73 if (tokenProvider != null) {
74 securityToken = (GenericOutboundSecurityToken)tokenProvider.getSecurityToken();
75 }
76 }
77
78 boolean includeToken = false;
79 WSSecurityTokenConstants.KeyIdentifier keyIdentifier = null;
80 if ((WSSConstants.SIGNATURE.equals(action) || WSSConstants.SAML_TOKEN_SIGNED.equals(action))
81 && !getSecurityProperties().getSignatureKeyIdentifiers().isEmpty()) {
82 includeToken = ((WSSSecurityProperties) getSecurityProperties()).isIncludeSignatureToken();
83 keyIdentifier = getSecurityProperties().getSignatureKeyIdentifiers().get(0);
84 } else if (WSSConstants.ENCRYPTION.equals(action)) {
85 includeToken = ((WSSSecurityProperties) getSecurityProperties()).isIncludeEncryptionToken();
86 keyIdentifier = getSecurityProperties().getEncryptionKeyIdentifier();
87 }
88
89 if (securityToken != null) {
90 if (WSSConstants.SIGNATURE.equals(action)
91 && (includeToken || WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE.equals(keyIdentifier))
92 && (securityToken.getTokenType() == null
93 || WSSecurityTokenConstants.X509V3Token.equals(securityToken.getTokenType()))) {
94 FinalBinarySecurityTokenOutputProcessor finalBinarySecurityTokenOutputProcessor =
95 new FinalBinarySecurityTokenOutputProcessor(securityToken);
96 finalBinarySecurityTokenOutputProcessor.setXMLSecurityProperties(getSecurityProperties());
97 finalBinarySecurityTokenOutputProcessor.setAction(getAction(), getActionOrder());
98 finalBinarySecurityTokenOutputProcessor.addBeforeProcessor(WSSSignatureOutputProcessor.class);
99 finalBinarySecurityTokenOutputProcessor.init(outputProcessorChain);
100 securityToken.setProcessor(finalBinarySecurityTokenOutputProcessor);
101 } else if (WSSConstants.SAML_TOKEN_SIGNED.equals(action) && includeToken
102 && (securityToken.getTokenType() == null
103 || WSSecurityTokenConstants.X509V3Token.equals(securityToken.getTokenType()))) {
104 FinalBinarySecurityTokenOutputProcessor finalBinarySecurityTokenOutputProcessor =
105 new FinalBinarySecurityTokenOutputProcessor(securityToken);
106 finalBinarySecurityTokenOutputProcessor.setXMLSecurityProperties(getSecurityProperties());
107 finalBinarySecurityTokenOutputProcessor.setAction(getAction(), getActionOrder());
108 finalBinarySecurityTokenOutputProcessor.addBeforeProcessor(WSSSignatureOutputProcessor.class);
109 finalBinarySecurityTokenOutputProcessor.init(outputProcessorChain);
110 securityToken.setProcessor(finalBinarySecurityTokenOutputProcessor);
111 } else if (WSSConstants.ENCRYPTION.equals(action)
112 && (includeToken || WSSecurityTokenConstants.KEYIDENTIFIER_SECURITY_TOKEN_DIRECT_REFERENCE.equals(keyIdentifier))
113 && (securityToken.getTokenType() == null
114 || WSSecurityTokenConstants.X509V3Token.equals(securityToken.getTokenType()))) {
115 FinalBinarySecurityTokenOutputProcessor finalBinarySecurityTokenOutputProcessor =
116 new FinalBinarySecurityTokenOutputProcessor(securityToken);
117 finalBinarySecurityTokenOutputProcessor.setXMLSecurityProperties(getSecurityProperties());
118 finalBinarySecurityTokenOutputProcessor.setAction(getAction(), getActionOrder());
119 finalBinarySecurityTokenOutputProcessor.addAfterProcessor(EncryptEndingOutputProcessor.class);
120 finalBinarySecurityTokenOutputProcessor.init(outputProcessorChain);
121 securityToken.setProcessor(finalBinarySecurityTokenOutputProcessor);
122 } else if (WSSConstants.ENCRYPTION_WITH_KERBEROS_TOKEN.equals(getAction())
123 || WSSConstants.SIGNATURE_WITH_KERBEROS_TOKEN.equals(getAction())
124 || WSSConstants.KERBEROS_TOKEN.equals(getAction())) {
125 FinalBinarySecurityTokenOutputProcessor finalBinarySecurityTokenOutputProcessor =
126 new FinalBinarySecurityTokenOutputProcessor(securityToken);
127 finalBinarySecurityTokenOutputProcessor.setXMLSecurityProperties(getSecurityProperties());
128 finalBinarySecurityTokenOutputProcessor.setAction(getAction(), getActionOrder());
129 finalBinarySecurityTokenOutputProcessor.addBeforeProcessor(WSSSignatureOutputProcessor.class);
130 finalBinarySecurityTokenOutputProcessor.init(outputProcessorChain);
131 securityToken.setProcessor(finalBinarySecurityTokenOutputProcessor);
132 }
133 }
134 } finally {
135 outputProcessorChain.removeProcessor(this);
136 }
137 outputProcessorChain.processEvent(xmlSecEvent);
138 }
139
140 static class FinalBinarySecurityTokenOutputProcessor extends AbstractOutputProcessor {
141
142 private final OutboundSecurityToken securityToken;
143
144 FinalBinarySecurityTokenOutputProcessor(OutboundSecurityToken securityToken) throws XMLSecurityException {
145 super();
146 this.addAfterProcessor(BinarySecurityTokenOutputProcessor.class);
147 this.securityToken = securityToken;
148 }
149
150 @Override
151 public void processEvent(XMLSecEvent xmlSecEvent, OutputProcessorChain outputProcessorChain)
152 throws XMLStreamException, XMLSecurityException {
153
154 outputProcessorChain.processEvent(xmlSecEvent);
155
156 if (WSSUtils.isSecurityHeaderElement(xmlSecEvent, ((WSSSecurityProperties) getSecurityProperties()).getActor())) {
157
158 final QName headerElementName = WSSConstants.TAG_WSSE_BINARY_SECURITY_TOKEN;
159
160 if (WSSConstants.ENCRYPTION_WITH_KERBEROS_TOKEN.equals(getAction())
161 || WSSConstants.SIGNATURE_WITH_KERBEROS_TOKEN.equals(getAction())
162 || WSSConstants.KERBEROS_TOKEN.equals(getAction())) {
163 OutputProcessorUtils.updateSecurityHeaderOrder(
164 outputProcessorChain, headerElementName, getAction(), false);
165 OutputProcessorChain subOutputProcessorChain = outputProcessorChain.createSubChain(this);
166
167 List<XMLSecAttribute> attributes = new ArrayList<>(3);
168 attributes.add(createAttribute(WSSConstants.ATT_NULL_ENCODING_TYPE, WSSConstants.SOAPMESSAGE_NS10_BASE64_ENCODING));
169 attributes.add(createAttribute(WSSConstants.ATT_NULL_VALUE_TYPE, WSSConstants.NS_GSS_KERBEROS5_AP_REQ));
170 attributes.add(createAttribute(WSSConstants.ATT_WSU_ID, securityToken.getId()));
171 createStartElementAndOutputAsEvent(subOutputProcessorChain, headerElementName, false, attributes);
172 createCharactersAndOutputAsEvent(subOutputProcessorChain,
173 XMLUtils.encodeToString(
174 ((KerberosClientSecurityToken)securityToken).getTicket())
175 );
176 createEndElementAndOutputAsEvent(subOutputProcessorChain, headerElementName);
177 if (WSSConstants.ENCRYPTION_WITH_KERBEROS_TOKEN.equals(getAction())) {
178 OutputProcessorUtils.updateSecurityHeaderOrder(outputProcessorChain, WSSConstants.TAG_xenc_ReferenceList,
179 getAction(), false);
180 WSSUtils.createReferenceListStructureForEncryption(this, subOutputProcessorChain);
181 }
182 } else if (securityToken.getX509Certificates() != null
183 && securityToken.getX509Certificates().length > 0) {
184 OutputProcessorUtils.updateSecurityHeaderOrder(
185 outputProcessorChain, headerElementName, getAction(), false);
186 OutputProcessorChain subOutputProcessorChain = outputProcessorChain.createSubChain(this);
187
188 boolean useSingleCertificate = getSecurityProperties().isUseSingleCert();
189 WSSUtils.createBinarySecurityTokenStructure(
190 this, subOutputProcessorChain, securityToken.getId(),
191 securityToken.getX509Certificates(), useSingleCertificate);
192 }
193
194 outputProcessorChain.removeProcessor(this);
195 }
196 }
197 }
198 }