1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.wss4j.stax.test.saml;
20
21 import java.io.ByteArrayInputStream;
22 import java.io.ByteArrayOutputStream;
23 import java.io.InputStream;
24 import java.time.Duration;
25 import java.time.Instant;
26 import java.util.Properties;
27
28 import javax.security.auth.callback.CallbackHandler;
29 import javax.xml.stream.XMLStreamException;
30 import javax.xml.stream.XMLStreamReader;
31 import javax.xml.transform.dom.DOMSource;
32 import javax.xml.transform.stream.StreamResult;
33
34 import org.apache.wss4j.common.saml.builder.SAML1Constants;
35 import org.apache.wss4j.common.saml.builder.SAML2Constants;
36 import org.apache.wss4j.dom.handler.WSHandlerConstants;
37 import org.apache.wss4j.stax.ext.WSSConstants;
38 import org.apache.wss4j.stax.ext.WSSSecurityProperties;
39 import org.apache.wss4j.stax.setup.InboundWSSec;
40 import org.apache.wss4j.stax.setup.WSSec;
41 import org.apache.wss4j.stax.test.AbstractTestBase;
42 import org.apache.wss4j.stax.test.utils.StAX2DOM;
43 import org.junit.jupiter.api.Test;
44 import org.w3c.dom.Document;
45 import org.w3c.dom.NodeList;
46
47 import static org.junit.jupiter.api.Assertions.assertEquals;
48 import static org.junit.jupiter.api.Assertions.assertFalse;
49 import static org.junit.jupiter.api.Assertions.assertNotNull;
50 import static org.junit.jupiter.api.Assertions.fail;
51
52
53
54
55 public class SamlAuthnTest extends AbstractTestBase {
56
57 private static final String IP_ADDRESS = "127.0.0.1";
58
59 @Test
60 public void testSAML1AuthnAssertion() throws Exception {
61
62 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
63 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
64 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
65 callbackHandler.setIssuer("www.example.com");
66
67 createDOMMessageAndVerifyStAX(callbackHandler, true);
68 }
69
70 @Test
71 public void testSAML2AuthnAssertion() throws Exception {
72
73 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
74 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
75 callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
76 callbackHandler.setIssuer("www.example.com");
77
78 createDOMMessageAndVerifyStAX(callbackHandler, true);
79 }
80
81 @Test
82 public void testSAML1FutureAuthnInstant() throws Exception {
83
84 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
85 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
86 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
87 callbackHandler.setIssuer("www.example.com");
88
89 callbackHandler.setAuthenticationInstant(Instant.now().plus(Duration.ofMinutes(70)));
90
91 createDOMMessageAndVerifyStAX(callbackHandler, false);
92 }
93
94 @Test
95 public void testSAML2FutureAuthnInstant() throws Exception {
96
97 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
98 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
99 callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
100 callbackHandler.setIssuer("www.example.com");
101
102 callbackHandler.setAuthenticationInstant(Instant.now().plus(Duration.ofMinutes(70)));
103
104 createDOMMessageAndVerifyStAX(callbackHandler, false);
105 }
106
107 @Test
108 public void testSAML2StaleSessionNotOnOrAfter() throws Exception {
109
110 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
111 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
112 callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
113 callbackHandler.setIssuer("www.example.com");
114
115 callbackHandler.setSessionNotOnOrAfter(Instant.now().minus(Duration.ofMinutes(70)));
116
117 createDOMMessageAndVerifyStAX(callbackHandler, false);
118 }
119
120 @Test
121 public void testSAML1ValidSubjectLocality() throws Exception {
122
123 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
124 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
125 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
126 callbackHandler.setIssuer("www.example.com");
127
128 callbackHandler.setSubjectLocality(IP_ADDRESS, "xyz.ws.apache.org");
129
130 createDOMMessageAndVerifyStAX(callbackHandler, true);
131 }
132
133 @Test
134 public void testSAML2ValidSubjectLocality() throws Exception {
135
136 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
137 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
138 callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
139 callbackHandler.setIssuer("www.example.com");
140
141 callbackHandler.setSubjectLocality(IP_ADDRESS, "xyz.ws.apache.org");
142
143 createDOMMessageAndVerifyStAX(callbackHandler, true);
144 }
145
146 @Test
147 public void testSAML1InvalidSubjectLocality() throws Exception {
148
149 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
150 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
151 callbackHandler.setConfirmationMethod(SAML1Constants.CONF_HOLDER_KEY);
152 callbackHandler.setIssuer("www.example.com");
153
154 callbackHandler.setSubjectLocality("xyz.ws.apache.org", "xyz.ws.apache.org");
155
156 createDOMMessageAndVerifyStAX(callbackHandler, false);
157 }
158
159 @Test
160 public void testSAML2InvalidSubjectLocality() throws Exception {
161
162 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
163 callbackHandler.setStatement(SAML2CallbackHandler.Statement.AUTHN);
164 callbackHandler.setConfirmationMethod(SAML2Constants.CONF_HOLDER_KEY);
165 callbackHandler.setIssuer("www.example.com");
166
167 callbackHandler.setSubjectLocality("xyz.ws.apache.org", "xyz.ws.apache.org");
168
169 createDOMMessageAndVerifyStAX(callbackHandler, false);
170 }
171
172 private void createDOMMessageAndVerifyStAX(
173 CallbackHandler samlCallbackHandler, boolean success
174 ) throws Exception {
175 ByteArrayOutputStream baos = new ByteArrayOutputStream();
176 {
177 InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
178 String action = WSHandlerConstants.SAML_TOKEN_SIGNED;
179 Properties properties = new Properties();
180 properties.put(WSHandlerConstants.SAML_CALLBACK_REF, samlCallbackHandler);
181 Document securedDocument = doOutboundSecurityWithWSS4J(sourceDocument, action, properties);
182
183
184 NodeList nodeList = securedDocument.getElementsByTagNameNS(WSSConstants.TAG_dsig_Signature.getNamespaceURI(), WSSConstants.TAG_dsig_Signature.getLocalPart());
185 assertEquals(nodeList.getLength(), 2);
186 assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_SAML_ASSERTION.getLocalPart());
187 assertEquals(nodeList.item(1).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
188
189 javax.xml.transform.Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
190 transformer.transform(new DOMSource(securedDocument), new StreamResult(baos));
191 }
192
193
194 {
195 WSSSecurityProperties securityProperties = new WSSSecurityProperties();
196 securityProperties.loadSignatureVerificationKeystore(this.getClass().getClassLoader().getResource("receiver.jks"), "default".toCharArray());
197 InboundWSSec wsSecIn = WSSec.getInboundWSSec(securityProperties);
198 XMLStreamReader xmlStreamReader = wsSecIn.processInMessage(xmlInputFactory.createXMLStreamReader(new ByteArrayInputStream(baos.toByteArray())));
199
200 try {
201 Document document =
202 StAX2DOM.readDoc(documentBuilderFactory.newDocumentBuilder(), xmlStreamReader);
203 if (!success) {
204 fail("XMLStreamException expected");
205 }
206 assertNotNull(document);
207 } catch (XMLStreamException e) {
208 assertFalse(success);
209 assertNotNull(e.getCause());
210 }
211 }
212 }
213
214 }