1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.security.oauth.provider.token;
18
19 import org.springframework.security.core.AuthenticationException;
20 import org.springframework.security.core.Authentication;
21 import org.springframework.beans.factory.InitializingBean;
22 import org.springframework.beans.factory.annotation.Autowired;
23 import org.apache.commons.codec.binary.Base64;
24
25 import java.util.*;
26 import java.security.SecureRandom;
27
28
29
30
31
32
33
34
35
36
37 public abstract class RandomValueProviderTokenServices implements OAuthProviderTokenServices, InitializingBean, OAuthTokenLifecycleRegistry {
38
39 private Random random;
40 private int requestTokenValiditySeconds = 60 * 10;
41 private int accessTokenValiditySeconds = 60 * 60 * 12;
42 private int tokenSecretLengthBytes = 80;
43 private final Collection<OAuthTokenLifecycleListener> lifecycleListeners = new HashSet<OAuthTokenLifecycleListener>();
44
45
46
47
48
49
50
51 protected abstract OAuthProviderTokenImpl readToken(String token);
52
53
54
55
56
57
58
59 protected abstract void storeToken(String tokenValue, OAuthProviderTokenImpl token);
60
61
62
63
64
65
66
67 protected abstract OAuthProviderTokenImpl removeToken(String tokenValue);
68
69
70
71
72
73 public void afterPropertiesSet() throws Exception {
74 if (random == null) {
75 random = new SecureRandom();
76 }
77 }
78
79 public OAuthProviderToken getToken(String token) throws AuthenticationException {
80 OAuthProviderTokenImpl tokenImpl = readToken(token);
81
82 if (tokenImpl == null) {
83 throw new InvalidOAuthTokenException("Invalid token: " + token);
84 }
85 else if (isExpired(tokenImpl)) {
86 removeToken(token);
87 onTokenRemoved(tokenImpl);
88 throw new ExpiredOAuthTokenException("Expired token.");
89 }
90
91 return tokenImpl;
92 }
93
94
95
96
97
98
99
100 protected boolean isExpired(OAuthProviderTokenImpl authToken) {
101 if (authToken.isAccessToken()) {
102 if ((authToken.getTimestamp() + (getAccessTokenValiditySeconds() * 1000L)) < System.currentTimeMillis()) {
103 return true;
104 }
105 }
106 else {
107 if ((authToken.getTimestamp() + (getRequestTokenValiditySeconds() * 1000L)) < System.currentTimeMillis()) {
108 return true;
109 }
110 }
111
112 return false;
113 }
114
115 public OAuthProviderToken createUnauthorizedRequestToken(String consumerKey, String callbackUrl) throws AuthenticationException {
116 String tokenValue = UUID.randomUUID().toString();
117 byte[] secretBytes = new byte[getTokenSecretLengthBytes()];
118 getRandom().nextBytes(secretBytes);
119 String secret = new String(Base64.encodeBase64(secretBytes));
120 OAuthProviderTokenImplovider/token/OAuthProviderTokenImpl.html#OAuthProviderTokenImpl">OAuthProviderTokenImpl token = new OAuthProviderTokenImpl();
121 token.setAccessToken(false);
122 token.setConsumerKey(consumerKey);
123 token.setCallbackUrl(callbackUrl);
124 token.setUserAuthentication(null);
125 token.setSecret(secret);
126 token.setValue(tokenValue);
127 token.setTimestamp(System.currentTimeMillis());
128 onTokenCreated(token);
129 storeToken(tokenValue, token);
130 return token;
131 }
132
133 public void authorizeRequestToken(String requestToken, String verifier, Authentication authentication) throws AuthenticationException {
134 OAuthProviderTokenImpl tokenImpl = readToken(requestToken);
135
136 if (tokenImpl == null) {
137 throw new InvalidOAuthTokenException("Invalid token: " + requestToken);
138 }
139 else if (isExpired(tokenImpl)) {
140 removeToken(requestToken);
141 onTokenRemoved(tokenImpl);
142 throw new ExpiredOAuthTokenException("Expired token.");
143 }
144 else if (tokenImpl.isAccessToken()) {
145 throw new InvalidOAuthTokenException("Request to authorize an access token.");
146 }
147
148 tokenImpl.setUserAuthentication(authentication);
149 tokenImpl.setTimestamp(System.currentTimeMillis());
150 tokenImpl.setVerifier(verifier);
151 storeToken(requestToken, tokenImpl);
152 }
153
154 public OAuthAccessProviderToken createAccessToken(String requestToken) throws AuthenticationException {
155 OAuthProviderTokenImpl tokenImpl = readToken(requestToken);
156
157 if (tokenImpl == null) {
158 throw new InvalidOAuthTokenException("Invalid token: " + requestToken);
159 }
160 else if (isExpired(tokenImpl)) {
161 removeToken(requestToken);
162 onTokenRemoved(tokenImpl);
163 throw new ExpiredOAuthTokenException("Expired token.");
164 }
165 else if (tokenImpl.isAccessToken()) {
166 throw new InvalidOAuthTokenException("Not a request token.");
167 }
168 else if (tokenImpl.getUserAuthentication() == null) {
169 throw new InvalidOAuthTokenException("Request token has not been authorized.");
170 }
171
172 OAuthProviderTokenImpl requestTokenImpl = removeToken(requestToken);
173 if (requestTokenImpl != null) {
174 onTokenRemoved(requestTokenImpl);
175 }
176
177 String tokenValue = UUID.randomUUID().toString();
178 byte[] secretBytes = new byte[getTokenSecretLengthBytes()];
179 getRandom().nextBytes(secretBytes);
180 String secret = new String(Base64.encodeBase64(secretBytes));
181 OAuthProviderTokenImplovider/token/OAuthProviderTokenImpl.html#OAuthProviderTokenImpl">OAuthProviderTokenImpl token = new OAuthProviderTokenImpl();
182 token.setAccessToken(true);
183 token.setConsumerKey(tokenImpl.getConsumerKey());
184 token.setUserAuthentication(tokenImpl.getUserAuthentication());
185 token.setSecret(secret);
186 token.setValue(tokenValue);
187 token.setTimestamp(System.currentTimeMillis());
188 onTokenCreated(token);
189 storeToken(tokenValue, token);
190 return token;
191 }
192
193
194
195
196
197
198 protected void onTokenRemoved(OAuthProviderTokenImpl token) {
199 for (OAuthTokenLifecycleListener listener : getLifecycleListeners()) {
200 listener.tokenExpired(token);
201 }
202 }
203
204
205
206
207
208
209 protected void onTokenCreated(OAuthProviderTokenImpl token) {
210 for (OAuthTokenLifecycleListener listener : getLifecycleListeners()) {
211 listener.tokenCreated(token);
212 }
213 }
214
215
216
217
218
219
220 public int getTokenSecretLengthBytes() {
221 return tokenSecretLengthBytes;
222 }
223
224
225
226
227
228
229 public void setTokenSecretLengthBytes(int tokenSecretLengthBytes) {
230 this.tokenSecretLengthBytes = tokenSecretLengthBytes;
231 }
232
233
234
235
236
237
238 public Random getRandom() {
239 return random;
240 }
241
242
243
244
245
246
247 public void setRandom(Random random) {
248 this.random = random;
249 }
250
251
252
253
254
255
256 public int getRequestTokenValiditySeconds() {
257 return requestTokenValiditySeconds;
258 }
259
260
261
262
263
264
265 public void setRequestTokenValiditySeconds(int requestTokenValiditySeconds) {
266 this.requestTokenValiditySeconds = requestTokenValiditySeconds;
267 }
268
269
270
271
272
273
274 public int getAccessTokenValiditySeconds() {
275 return accessTokenValiditySeconds;
276 }
277
278
279
280
281
282
283 public void setAccessTokenValiditySeconds(int accessTokenValiditySeconds) {
284 this.accessTokenValiditySeconds = accessTokenValiditySeconds;
285 }
286
287
288
289
290
291
292 public Collection<OAuthTokenLifecycleListener> getLifecycleListeners() {
293 return lifecycleListeners;
294 }
295
296
297
298
299
300
301 @Autowired ( required = false )
302 public void register(OAuthTokenLifecycleListener... lifecycleListeners) {
303 if (lifecycleListeners != null) {
304 this.lifecycleListeners.addAll(Arrays.asList(lifecycleListeners));
305 }
306 }
307 }