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.processor;
21
22 import java.time.Instant;
23 import java.util.List;
24
25 import org.apache.wss4j.common.principal.SAMLTokenPrincipalImpl;
26 import org.apache.wss4j.common.principal.WSUsernameTokenPrincipalImpl;
27 import org.apache.wss4j.common.util.UsernameTokenUtil;
28 import org.w3c.dom.Element;
29 import org.apache.wss4j.common.cache.ReplayCache;
30 import org.apache.wss4j.common.ext.WSSecurityException;
31 import org.apache.wss4j.dom.WSConstants;
32 import org.apache.wss4j.dom.engine.WSSecurityEngineResult;
33 import org.apache.wss4j.dom.handler.RequestData;
34 import org.apache.wss4j.dom.message.token.UsernameToken;
35 import org.apache.wss4j.dom.validate.Credential;
36 import org.apache.wss4j.dom.validate.Validator;
37 import org.apache.xml.security.utils.XMLUtils;
38
39 public class UsernameTokenProcessor implements Processor {
40 private static final org.slf4j.Logger LOG =
41 org.slf4j.LoggerFactory.getLogger(UsernameTokenProcessor.class);
42
43 public List<WSSecurityEngineResult> handleToken(
44 Element elem,
45 RequestData data
46 ) throws WSSecurityException {
47 LOG.debug("Found UsernameToken list element");
48
49 String id = elem.getAttributeNS(WSConstants.WSU_NS, "Id");
50 if (id.length() != 0) {
51 Element foundElement = data.getWsDocInfo().getTokenElement(id);
52 if (elem.equals(foundElement)) {
53 WSSecurityEngineResult result = data.getWsDocInfo().getResult(id);
54 return java.util.Collections.singletonList(result);
55 } else if (foundElement != null) {
56 throw new WSSecurityException(
57 WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN, "duplicateError"
58 );
59 }
60 }
61
62 Validator validator = data.getValidator(WSConstants.USERNAME_TOKEN);
63 Credential credential = handleUsernameToken(elem, validator, data);
64 UsernameToken token = credential.getUsernametoken();
65
66 int action = WSConstants.UT;
67 byte[] secretKey = null;
68 if (token.getPassword() == null) {
69 action = WSConstants.UT_NOPASSWORD;
70 if (token.isDerivedKey()) {
71 String rawPassword =
72 UsernameTokenUtil.getRawPassword(data.getCallbackHandler(), token.getName(),
73 token.getPassword(), token.getPasswordType());
74 secretKey = token.getDerivedKey(data.getBSPEnforcer(), rawPassword);
75 }
76 }
77 WSSecurityEngineResult result = new WSSecurityEngineResult(action, token);
78 String tokenId = token.getID();
79 if (tokenId.length() != 0) {
80 result.put(WSSecurityEngineResult.TAG_ID, tokenId);
81 }
82 result.put(WSSecurityEngineResult.TAG_SECRET, secretKey);
83
84 if (validator != null) {
85 result.put(WSSecurityEngineResult.TAG_VALIDATED_TOKEN, Boolean.TRUE);
86 if (credential.getTransformedToken() != null) {
87 result.put(
88 WSSecurityEngineResult.TAG_TRANSFORMED_TOKEN, credential.getTransformedToken()
89 );
90 if (credential.getPrincipal() != null) {
91 result.put(WSSecurityEngineResult.TAG_PRINCIPAL, credential.getPrincipal());
92 } else {
93 SAMLTokenPrincipalImpl samlPrincipal =
94 new SAMLTokenPrincipalImpl(credential.getTransformedToken());
95 result.put(WSSecurityEngineResult.TAG_PRINCIPAL, samlPrincipal);
96 }
97 } else if (credential.getPrincipal() != null) {
98 result.put(WSSecurityEngineResult.TAG_PRINCIPAL, credential.getPrincipal());
99 } else {
100 WSUsernameTokenPrincipalImpl principal =
101 new WSUsernameTokenPrincipalImpl(token.getName(), token.isHashed());
102 if (token.getNonce() != null) {
103 principal.setNonce(XMLUtils.decode(token.getNonce()));
104 }
105 principal.setPassword(token.getPassword());
106 principal.setCreatedTime(token.getCreated());
107 principal.setPasswordType(token.getPasswordType());
108 result.put(WSSecurityEngineResult.TAG_PRINCIPAL, principal);
109 }
110 result.put(WSSecurityEngineResult.TAG_SUBJECT, credential.getSubject());
111 }
112
113 data.getWsDocInfo().addTokenElement(elem);
114 data.getWsDocInfo().addResult(result);
115 return java.util.Collections.singletonList(result);
116 }
117
118
119
120
121
122
123
124
125
126 private Credential
127 handleUsernameToken(
128 Element token,
129 Validator validator,
130 RequestData data
131 ) throws WSSecurityException {
132 boolean allowNamespaceQualifiedPasswordTypes = data.isAllowNamespaceQualifiedPasswordTypes();
133 int utTTL = data.getUtTTL();
134 int futureTimeToLive = data.getUtFutureTTL();
135
136
137
138
139 UsernameToken ut =
140 new UsernameToken(token, allowNamespaceQualifiedPasswordTypes, data.getBSPEnforcer());
141
142
143 if (!ut.verifyCreated(utTTL, futureTimeToLive)) {
144 throw new WSSecurityException(WSSecurityException.ErrorCode.MESSAGE_EXPIRED);
145 }
146
147
148 ReplayCache replayCache = data.getNonceReplayCache();
149 if (replayCache != null && ut.getNonce() != null) {
150 if (replayCache.contains(ut.getNonce())) {
151 throw new WSSecurityException(
152 WSSecurityException.ErrorCode.INVALID_SECURITY,
153 "badUsernameToken",
154 new Object[] {"A replay attack has been detected"}
155 );
156 }
157
158
159
160
161 Instant created = ut.getCreatedDate();
162 if (created == null || utTTL <= 0) {
163 replayCache.add(ut.getNonce());
164 } else {
165 replayCache.add(ut.getNonce(), Instant.now().plusSeconds(utTTL));
166 }
167 }
168
169 Credential credential = new Credential();
170 credential.setUsernametoken(ut);
171 if (validator != null) {
172 return validator.validate(credential, data);
173 }
174 return credential;
175 }
176
177 }