1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.wss4j.dom.saml;
21
22 import java.time.Duration;
23 import java.time.Instant;
24
25 import javax.security.auth.callback.CallbackHandler;
26
27 import org.apache.wss4j.common.ext.WSSecurityException;
28 import org.apache.wss4j.common.saml.SAMLCallback;
29 import org.apache.wss4j.common.saml.SAMLUtil;
30 import org.apache.wss4j.common.saml.SamlAssertionWrapper;
31 import org.apache.wss4j.common.util.SOAPUtil;
32 import org.apache.wss4j.common.util.XMLUtils;
33 import org.apache.wss4j.dom.WSConstants;
34 import org.apache.wss4j.dom.common.CustomSamlAssertionValidator;
35 import org.apache.wss4j.dom.common.SAML1CallbackHandler;
36 import org.apache.wss4j.dom.common.SAML2CallbackHandler;
37
38 import org.apache.wss4j.dom.engine.WSSConfig;
39 import org.apache.wss4j.dom.engine.WSSecurityEngine;
40 import org.apache.wss4j.dom.handler.RequestData;
41 import org.apache.wss4j.dom.handler.WSHandlerResult;
42 import org.apache.wss4j.dom.message.WSSecHeader;
43 import org.apache.wss4j.dom.message.WSSecSAMLToken;
44
45 import org.junit.jupiter.api.Test;
46 import org.w3c.dom.Document;
47
48 import static org.junit.jupiter.api.Assertions.assertFalse;
49 import static org.junit.jupiter.api.Assertions.assertTrue;
50 import static org.junit.jupiter.api.Assertions.fail;
51
52
53
54
55 public class SamlAuthnTest {
56 private static final org.slf4j.Logger LOG =
57 org.slf4j.LoggerFactory.getLogger(SamlAuthnTest.class);
58 private WSSecurityEngine secEngine = new WSSecurityEngine();
59
60 public SamlAuthnTest() {
61 WSSConfig config = WSSConfig.getNewInstance();
62 config.setValidator(WSConstants.SAML_TOKEN, new CustomSamlAssertionValidator());
63 config.setValidator(WSConstants.SAML2_TOKEN, new CustomSamlAssertionValidator());
64 secEngine.setWssConfig(config);
65 }
66
67 @Test
68 public void testSAML1AuthnAssertion() throws Exception {
69 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
70 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
71 callbackHandler.setIssuer("www.example.com");
72
73 createAndVerifyMessage(callbackHandler, true);
74 }
75
76 @Test
77 public void testSAML2AuthnAssertion() throws Exception {
78 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
79 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
80 callbackHandler.setIssuer("www.example.com");
81
82 createAndVerifyMessage(callbackHandler, true);
83 }
84
85 @Test
86 public void testSAML1FutureAuthnInstant() throws Exception {
87 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
88 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
89 callbackHandler.setIssuer("www.example.com");
90
91 callbackHandler.setAuthenticationInstant(Instant.now().plus(Duration.ofMinutes(70)));
92
93 createAndVerifyMessage(callbackHandler, false);
94 }
95
96 @Test
97 public void testSAML2FutureAuthnInstant() throws Exception {
98 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
99 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
100 callbackHandler.setIssuer("www.example.com");
101
102 callbackHandler.setAuthenticationInstant(Instant.now().plus(Duration.ofMinutes(70)));
103
104 createAndVerifyMessage(callbackHandler, false);
105 }
106
107 @Test
108 public void testSAML2StaleSessionNotOnOrAfter() throws Exception {
109 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
110 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
111 callbackHandler.setIssuer("www.example.com");
112
113 callbackHandler.setSessionNotOnOrAfter(Instant.now().minus(Duration.ofMinutes(70)));
114
115 createAndVerifyMessage(callbackHandler, false);
116 }
117
118 @Test
119 public void testSAML1ValidSubjectLocality() throws Exception {
120 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
121 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
122 callbackHandler.setIssuer("www.example.com");
123
124 callbackHandler.setSubjectLocality("127.0.0.1", "xyz.ws.apache.org");
125
126 createAndVerifyMessage(callbackHandler, true);
127 }
128
129 @Test
130 public void testSAML2ValidSubjectLocality() throws Exception {
131 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
132 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
133 callbackHandler.setIssuer("www.example.com");
134
135 callbackHandler.setSubjectLocality("127.0.0.1", "xyz.ws.apache.org");
136
137 createAndVerifyMessage(callbackHandler, true);
138 }
139
140 @Test
141 public void testSAML1InvalidSubjectLocality() throws Exception {
142 SAML1CallbackHandler callbackHandler = new SAML1CallbackHandler();
143 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
144 callbackHandler.setIssuer("www.example.com");
145
146 callbackHandler.setSubjectLocality("xyz.ws.apache.org", "xyz.ws.apache.org");
147
148 createAndVerifyMessage(callbackHandler, false);
149 }
150
151 @Test
152 public void testSAML2InalidSubjectLocality() throws Exception {
153 SAML2CallbackHandler callbackHandler = new SAML2CallbackHandler();
154 callbackHandler.setStatement(SAML1CallbackHandler.Statement.AUTHN);
155 callbackHandler.setIssuer("www.example.com");
156
157 callbackHandler.setSubjectLocality("xyz.ws.apache.org", "xyz.ws.apache.org");
158
159 createAndVerifyMessage(callbackHandler, false);
160 }
161
162 private void createAndVerifyMessage(
163 CallbackHandler samlCallbackHandler, boolean success
164 ) throws Exception {
165 SAMLCallback samlCallback = new SAMLCallback();
166 SAMLUtil.doSAMLCallback(samlCallbackHandler, samlCallback);
167 SamlAssertionWrapper samlAssertion = new SamlAssertionWrapper(samlCallback);
168
169 Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
170 WSSecHeader secHeader = new WSSecHeader(doc);
171 secHeader.insertSecurityHeader();
172
173 WSSecSAMLToken wsSign = new WSSecSAMLToken(secHeader);
174
175 Document unsignedDoc = wsSign.build(samlAssertion);
176
177 if (LOG.isDebugEnabled()) {
178 String outputString =
179 XMLUtils.prettyDocumentToString(unsignedDoc);
180 LOG.debug(outputString);
181 }
182
183 try {
184 verify(unsignedDoc);
185 if (!success) {
186 fail("Failure expected in processing the SAML assertion");
187 }
188 } catch (WSSecurityException ex) {
189 assertFalse(success);
190 assertTrue(ex.getMessage().contains("SAML token security failure"));
191 }
192 }
193
194
195
196
197
198
199
200
201 private WSHandlerResult verify(Document doc) throws Exception {
202 RequestData requestData = new RequestData();
203 requestData.setValidateSamlSubjectConfirmation(false);
204
205 WSHandlerResult results = secEngine.processSecurityHeader(doc, requestData);
206 String outputString =
207 XMLUtils.prettyDocumentToString(doc);
208 assertTrue(outputString.indexOf("counter_port_type") > 0 ? true : false);
209 return results;
210 }
211
212 }