1   /*
2    * Copyright 2005-2010 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.ws.soap.security.xwss;
18  
19  import javax.security.auth.callback.Callback;
20  import javax.security.auth.callback.CallbackHandler;
21  import javax.xml.soap.SOAPMessage;
22  
23  import org.springframework.core.io.ClassPathResource;
24  import org.springframework.ws.soap.saaj.SaajSoapMessage;
25  import org.springframework.ws.soap.security.callback.AbstractCallbackHandler;
26  
27  import com.sun.xml.wss.impl.callback.PasswordCallback;
28  import com.sun.xml.wss.impl.callback.PasswordValidationCallback;
29  import com.sun.xml.wss.impl.callback.TimestampValidationCallback;
30  import com.sun.xml.wss.impl.callback.UsernameCallback;
31  import org.junit.Test;
32  
33  import static org.junit.Assert.*;
34  
35  public class XwssMessageInterceptorUsernameTokenTest extends AbstractXwssMessageInterceptorTestCase {
36  
37  
38      @Test
39     public void testAddUsernameTokenDigest() throws Exception {
40          interceptor.setPolicyConfiguration(new ClassPathResource("usernameToken-digest-config.xml", getClass()));
41          CallbackHandler handler = new AbstractCallbackHandler() {
42  
43              @Override
44              protected void handleInternal(Callback callback) {
45                  if (callback instanceof UsernameCallback) {
46                      ((UsernameCallback) callback).setUsername("Bert");
47                  }
48                  else if (callback instanceof PasswordCallback) {
49                      PasswordCallback passwordCallback = (PasswordCallback) callback;
50                      passwordCallback.setPassword("Ernie");
51                  }
52                  else {
53                      fail("Unexpected callback");
54                  }
55              }
56          };
57          interceptor.setCallbackHandler(handler);
58          interceptor.afterPropertiesSet();
59          SaajSoapMessage message = loadSaajMessage("empty-soap.xml");
60          interceptor.secureMessage(message, null);
61          SOAPMessage result = message.getSaajMessage();
62          assertNotNull("No result returned", result);
63          assertXpathEvaluatesTo("Invalid Username", "Bert",
64                  "/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/wsse:UsernameToken/wsse:Username/text()", result);
65          assertXpathExists("Password does not exist",
66                  "/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/wsse:UsernameToken/wsse:Password[@Type='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest']",
67                  result);
68      }
69  
70      @Test
71      public void testAddUsernameTokenPlainText() throws Exception {
72          interceptor.setPolicyConfiguration(new ClassPathResource("usernameToken-plainText-config.xml", getClass()));
73          CallbackHandler handler = new AbstractCallbackHandler() {
74  
75              @Override
76              protected void handleInternal(Callback callback) {
77                  if (callback instanceof UsernameCallback) {
78                      ((UsernameCallback) callback).setUsername("Bert");
79                  }
80                  else if (callback instanceof PasswordCallback) {
81                      PasswordCallback passwordCallback = (PasswordCallback) callback;
82                      passwordCallback.setPassword("Ernie");
83                  }
84                  else {
85                      fail("Unexpected callback");
86                  }
87              }
88          };
89          interceptor.setCallbackHandler(handler);
90          interceptor.afterPropertiesSet();
91          SaajSoapMessage message = loadSaajMessage("empty-soap.xml");
92          interceptor.secureMessage(message, null);
93          SOAPMessage result = message.getSaajMessage();
94          assertNotNull("No result returned", result);
95          assertXpathEvaluatesTo("Invalid Username", "Bert",
96                  "/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/wsse:UsernameToken/wsse:Username/text()", result);
97          assertXpathEvaluatesTo("Invalid Password", "Ernie",
98                  "/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/wsse:UsernameToken/wsse:Password[@Type='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText']/text()",
99                  result);
100     }
101 
102     @Test
103     public void testValidateUsernameTokenPlainText() throws Exception {
104         interceptor
105                 .setPolicyConfiguration(new ClassPathResource("requireUsernameToken-plainText-config.xml", getClass()));
106         CallbackHandler handler = new AbstractCallbackHandler() {
107 
108             @Override
109             protected void handleInternal(Callback callback) {
110                 if (callback instanceof PasswordValidationCallback) {
111                     PasswordValidationCallback validationCallback = (PasswordValidationCallback) callback;
112                     validationCallback.setValidator(new PasswordValidationCallback.PasswordValidator() {
113                         public boolean validate(PasswordValidationCallback.Request request) {
114                             if (request instanceof PasswordValidationCallback.PlainTextPasswordRequest) {
115                                 PasswordValidationCallback.PlainTextPasswordRequest passwordRequest =
116                                         (PasswordValidationCallback.PlainTextPasswordRequest) request;
117                                 assertEquals("Invalid username", "Bert", passwordRequest.getUsername());
118                                 assertEquals("Invalid password", "Ernie", passwordRequest.getPassword());
119                                 return true;
120                             }
121                             else {
122                                 fail("Unexpected request");
123                                 return false;
124                             }
125                         }
126                     });
127                 }
128                 else {
129                     fail("Unexpected callback");
130                 }
131             }
132         };
133         interceptor.setCallbackHandler(handler);
134         interceptor.afterPropertiesSet();
135         SaajSoapMessage message = loadSaajMessage("usernameTokenPlainText-soap.xml");
136         interceptor.validateMessage(message, null);
137         SOAPMessage result = message.getSaajMessage();
138         assertNotNull("No result returned", result);
139         assertXpathNotExists("Security Header not removed", "/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security", result);
140     }
141 
142     @Test
143     public void testValidateUsernameTokenDigest() throws Exception {
144         interceptor.setPolicyConfiguration(new ClassPathResource("requireUsernameToken-digest-config.xml", getClass()));
145         CallbackHandler handler = new AbstractCallbackHandler() {
146 
147             @Override
148             protected void handleInternal(Callback callback) {
149                 if (callback instanceof PasswordValidationCallback) {
150                     PasswordValidationCallback validationCallback = (PasswordValidationCallback) callback;
151                     if (validationCallback.getRequest() instanceof PasswordValidationCallback.DigestPasswordRequest) {
152                         PasswordValidationCallback.DigestPasswordRequest passwordRequest =
153                                 (PasswordValidationCallback.DigestPasswordRequest) validationCallback.getRequest();
154                         assertEquals("Invalid username", "Bert", passwordRequest.getUsername());
155                         passwordRequest.setPassword("Ernie");
156                         validationCallback.setValidator(new PasswordValidationCallback.DigestPasswordValidator());
157                     }
158                     else {
159                         fail("Unexpected request");
160                     }
161                 }
162                 else if (callback instanceof TimestampValidationCallback) {
163                     TimestampValidationCallback validationCallback = (TimestampValidationCallback) callback;
164                     validationCallback.setValidator(new TimestampValidationCallback.TimestampValidator() {
165                         public void validate(TimestampValidationCallback.Request request) {
166                         }
167                     });
168                 }
169                 else {
170                     fail("Unexpected callback");
171                 }
172             }
173         };
174         interceptor.setCallbackHandler(handler);
175         interceptor.afterPropertiesSet();
176         SaajSoapMessage message = loadSaajMessage("usernameTokenDigest-soap.xml");
177         interceptor.validateMessage(message, null);
178         SOAPMessage result = message.getSaajMessage();
179         assertNotNull("No result returned", result);
180         assertXpathNotExists("Security Header not removed", "/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security", result);
181     }
182 
183 }