1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.ws.security.validate;
21
22 import java.io.IOException;
23
24 import javax.security.auth.callback.Callback;
25 import javax.security.auth.callback.UnsupportedCallbackException;
26
27 import org.apache.ws.security.WSConstants;
28 import org.apache.ws.security.WSPasswordCallback;
29 import org.apache.ws.security.WSSConfig;
30 import org.apache.ws.security.WSSecurityException;
31 import org.apache.ws.security.handler.RequestData;
32 import org.apache.ws.security.message.token.UsernameToken;
33 import org.apache.ws.security.util.Base64;
34
35
36
37
38
39 public class UsernameTokenValidator implements Validator {
40
41 private static org.apache.commons.logging.Log log =
42 org.apache.commons.logging.LogFactory.getLog(UsernameTokenValidator.class);
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 public Credential validate(Credential credential, RequestData data) throws WSSecurityException {
59 if (credential == null || credential.getUsernametoken() == null) {
60 throw new WSSecurityException(WSSecurityException.FAILURE, "noCredential");
61 }
62
63 boolean handleCustomPasswordTypes = false;
64 boolean passwordsAreEncoded = false;
65 String requiredPasswordType = null;
66 WSSConfig wssConfig = data.getWssConfig();
67 if (wssConfig != null) {
68 handleCustomPasswordTypes = wssConfig.getHandleCustomPasswordTypes();
69 passwordsAreEncoded = wssConfig.getPasswordsAreEncoded();
70 requiredPasswordType = wssConfig.getRequiredPasswordType();
71 }
72
73 UsernameToken usernameToken = credential.getUsernametoken();
74 usernameToken.setPasswordsAreEncoded(passwordsAreEncoded);
75
76 String pwType = usernameToken.getPasswordType();
77 if (log.isDebugEnabled()) {
78 log.debug("UsernameToken user " + usernameToken.getName());
79 log.debug("UsernameToken password type " + pwType);
80 }
81
82 if (requiredPasswordType != null && !requiredPasswordType.equals(pwType)) {
83 if (log.isDebugEnabled()) {
84 log.debug("Authentication failed as the received password type does not "
85 + "match the required password type of: " + requiredPasswordType);
86 }
87 throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
88 }
89
90
91
92
93
94
95 String password = usernameToken.getPassword();
96 if (usernameToken.isHashed()) {
97 verifyDigestPassword(usernameToken, data);
98 } else if (WSConstants.PASSWORD_TEXT.equals(pwType)
99 || (password != null && (pwType == null || "".equals(pwType.trim())))) {
100 verifyPlaintextPassword(usernameToken, data);
101 } else if (password != null) {
102 if (!handleCustomPasswordTypes) {
103 if (log.isDebugEnabled()) {
104 log.debug("Authentication failed as handleCustomUsernameTokenTypes is false");
105 }
106 throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
107 }
108 verifyCustomPassword(usernameToken, data);
109 } else {
110 verifyUnknownPassword(usernameToken, data);
111 }
112 return credential;
113 }
114
115
116
117
118
119
120
121
122
123
124
125 protected void verifyCustomPassword(UsernameToken usernameToken,
126 RequestData data) throws WSSecurityException {
127 verifyPlaintextPassword(usernameToken, data);
128 }
129
130
131
132
133
134
135
136
137
138
139
140 protected void verifyPlaintextPassword(UsernameToken usernameToken,
141 RequestData data) throws WSSecurityException {
142 verifyDigestPassword(usernameToken, data);
143 }
144
145
146
147
148
149
150
151
152 protected void verifyDigestPassword(UsernameToken usernameToken,
153 RequestData data) throws WSSecurityException {
154 if (data.getCallbackHandler() == null) {
155 throw new WSSecurityException(WSSecurityException.FAILURE, "noCallback");
156 }
157
158 String user = usernameToken.getName();
159 String password = usernameToken.getPassword();
160 String nonce = usernameToken.getNonce();
161 String createdTime = usernameToken.getCreated();
162 String pwType = usernameToken.getPasswordType();
163 boolean passwordsAreEncoded = usernameToken.getPasswordsAreEncoded();
164
165 WSPasswordCallback pwCb =
166 new WSPasswordCallback(user, null, pwType, WSPasswordCallback.USERNAME_TOKEN, data);
167 try {
168 data.getCallbackHandler().handle(new Callback[]{pwCb});
169 } catch (IOException e) {
170 if (log.isDebugEnabled()) {
171 log.debug(e);
172 }
173 throw new WSSecurityException(
174 WSSecurityException.FAILED_AUTHENTICATION, null, null, e
175 );
176 } catch (UnsupportedCallbackException e) {
177 if (log.isDebugEnabled()) {
178 log.debug(e);
179 }
180 throw new WSSecurityException(
181 WSSecurityException.FAILED_AUTHENTICATION, null, null, e
182 );
183 }
184 String origPassword = pwCb.getPassword();
185 if (origPassword == null) {
186 if (log.isDebugEnabled()) {
187 log.debug("Callback supplied no password for: " + user);
188 }
189 throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
190 }
191 if (usernameToken.isHashed()) {
192 String passDigest;
193 if (passwordsAreEncoded) {
194 passDigest = UsernameToken.doPasswordDigest(nonce, createdTime, Base64.decode(origPassword));
195 } else {
196 passDigest = UsernameToken.doPasswordDigest(nonce, createdTime, origPassword);
197 }
198 if (!passDigest.equals(password)) {
199 throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
200 }
201 } else {
202 if (!origPassword.equals(password)) {
203 throw new WSSecurityException(WSSecurityException.FAILED_AUTHENTICATION);
204 }
205 }
206 }
207
208
209
210
211
212
213
214 protected void verifyUnknownPassword(UsernameToken usernameToken,
215 RequestData data) throws WSSecurityException {
216
217 }
218
219 }