1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.springframework.security.oauth2.provider.token;
15
16 import static org.junit.Assert.assertEquals;
17 import static org.junit.Assert.assertFalse;
18 import static org.junit.Assert.assertNotNull;
19 import static org.junit.Assert.assertTrue;
20
21 import java.util.Arrays;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.Date;
25 import java.util.LinkedHashSet;
26 import java.util.concurrent.atomic.AtomicBoolean;
27
28 import org.junit.Before;
29 import org.junit.Test;
30 import org.springframework.security.authentication.AbstractAuthenticationToken;
31 import org.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken;
32 import org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken;
33 import org.springframework.security.oauth2.common.OAuth2AccessToken;
34 import org.springframework.security.oauth2.common.OAuth2RefreshToken;
35 import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
36 import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
37 import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
38 import org.springframework.security.oauth2.config.annotation.builders.InMemoryClientDetailsServiceBuilder;
39 import org.springframework.security.oauth2.provider.ClientDetails;
40 import org.springframework.security.oauth2.provider.ClientDetailsService;
41 import org.springframework.security.oauth2.provider.ClientRegistrationException;
42 import org.springframework.security.oauth2.provider.OAuth2Authentication;
43 import org.springframework.security.oauth2.provider.RequestTokenFactory;
44 import org.springframework.security.oauth2.provider.TokenRequest;
45 import org.springframework.security.oauth2.provider.client.BaseClientDetails;
46
47
48
49
50
51 public abstract class AbstractDefaultTokenServicesTests {
52
53 private DefaultTokenServices services;
54
55 private TokenStore tokenStore;
56
57 @Before
58 public void setUp() throws Exception {
59 tokenStore = createTokenStore();
60 services = new DefaultTokenServices();
61 configureTokenServices(services);
62 }
63
64 @Test
65 public void testClientSpecificRefreshTokenExpiry() throws Exception {
66 getTokenServices().setRefreshTokenValiditySeconds(1000);
67 getTokenServices().setClientDetailsService(new ClientDetailsService() {
68 public ClientDetails loadClientByClientId(String clientId) throws OAuth2Exception {
69 BaseClientDetails client = new BaseClientDetails();
70 client.setRefreshTokenValiditySeconds(100);
71 client.setAuthorizedGrantTypes(Arrays.asList("authorization_code", "refresh_token"));
72 return client;
73 }
74 });
75 OAuth2AccessToken accessToken = getTokenServices().createAccessToken(createAuthentication());
76 DefaultExpiringOAuth2RefreshToken refreshToken = (DefaultExpiringOAuth2RefreshToken) accessToken
77 .getRefreshToken();
78 Date expectedExpiryDate = new Date(System.currentTimeMillis() + 102 * 1000L);
79 assertTrue(expectedExpiryDate.after(refreshToken.getExpiration()));
80 }
81
82 @Test(expected = InvalidTokenException.class)
83 public void testClientInvalidated() throws Exception {
84 final AtomicBoolean deleted = new AtomicBoolean();
85 getTokenServices().setClientDetailsService(new ClientDetailsService() {
86 public ClientDetails loadClientByClientId(String clientId) throws OAuth2Exception {
87 if (deleted.get()) {
88 throw new ClientRegistrationException("No such client: " + clientId);
89 }
90 BaseClientDetails client = new BaseClientDetails();
91 client.setRefreshTokenValiditySeconds(100);
92 client.setAuthorizedGrantTypes(Arrays.asList("authorization_code", "refresh_token"));
93 return client;
94 }
95 });
96 OAuth2AccessToken token = getTokenServices().createAccessToken(createAuthentication());
97 deleted.set(true);
98 OAuth2Authentication authentication = getTokenServices().loadAuthentication(token.getValue());
99 assertNotNull(authentication.getOAuth2Request());
100 }
101
102 @Test(expected = InvalidGrantException.class)
103 public void testRefreshedTokenInvalidWithWrongClient() throws Exception {
104 ExpiringOAuth2RefreshToken expectedExpiringRefreshToken = (ExpiringOAuth2RefreshToken) getTokenServices()
105 .createAccessToken(createAuthentication()).getRefreshToken();
106 TokenRequest tokenRequest = new TokenRequest(Collections.singletonMap("client_id", "wrong"), "wrong", null,
107 null);
108 OAuth2AccessToken refreshedAccessToken = getTokenServices()
109 .refreshAccessToken(expectedExpiringRefreshToken.getValue(), tokenRequest);
110 assertEquals("[read]", refreshedAccessToken.getScope().toString());
111 }
112
113 @Test
114 public void testRefreshedTokenHasNarrowedScopes() throws Exception {
115 ExpiringOAuth2RefreshToken expectedExpiringRefreshToken = (ExpiringOAuth2RefreshToken) getTokenServices()
116 .createAccessToken(createAuthentication()).getRefreshToken();
117 TokenRequest tokenRequest = new TokenRequest(Collections.singletonMap("client_id", "id"), "id",
118 Collections.singleton("read"), null);
119 OAuth2AccessToken refreshedAccessToken = getTokenServices()
120 .refreshAccessToken(expectedExpiringRefreshToken.getValue(), tokenRequest);
121 assertEquals("[read]", refreshedAccessToken.getScope().toString());
122 }
123
124 @Test
125 public void testRefreshTokenRequestHasRefreshFlag() throws Exception {
126 ExpiringOAuth2RefreshToken expectedExpiringRefreshToken = (ExpiringOAuth2RefreshToken) getTokenServices()
127 .createAccessToken(createAuthentication()).getRefreshToken();
128 TokenRequest tokenRequest = new TokenRequest(Collections.singletonMap("client_id", "id"), "id",
129 Collections.singleton("read"), null);
130 final AtomicBoolean called = new AtomicBoolean(false);
131 getTokenServices().setTokenEnhancer(new TokenEnhancer() {
132 @Override
133 public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
134 assertTrue(authentication.getOAuth2Request().isRefresh());
135 called.set(true);
136 return accessToken;
137 }
138 });
139 getTokenServices().refreshAccessToken(expectedExpiringRefreshToken.getValue(), tokenRequest);
140 assertTrue(called.get());
141 }
142
143 @Test
144 public void testRefreshTokenNonExpiring() throws Exception {
145 ClientDetailsService clientDetailsService = new InMemoryClientDetailsServiceBuilder().withClient("id")
146 .refreshTokenValiditySeconds(0).authorizedGrantTypes("refresh_token").and().build();
147 DefaultTokenServices tokenServices = getTokenServices();
148 tokenServices.setClientDetailsService(clientDetailsService);
149 OAuth2RefreshToken refreshToken = tokenServices.createAccessToken(createAuthentication())
150 .getRefreshToken();
151 assertNotNull(refreshToken);
152 assertFalse(refreshToken instanceof ExpiringOAuth2RefreshToken);
153 }
154
155 @Test
156 public void testTokenRevoked() throws Exception {
157 OAuth2Authentication authentication = createAuthentication();
158 OAuth2AccessToken original = getTokenServices().createAccessToken(authentication);
159 getTokenStore().removeAccessToken(original);
160 assertEquals(0, getTokenStore().findTokensByClientId(authentication.getOAuth2Request().getClientId()).size());
161 }
162
163 @Test
164 public void testUnlimitedTokenExpiry() throws Exception {
165 getTokenServices().setAccessTokenValiditySeconds(0);
166 OAuth2AccessToken accessToken = getTokenServices().createAccessToken(createAuthentication());
167 assertEquals(0, accessToken.getExpiresIn());
168 assertEquals(null, accessToken.getExpiration());
169 }
170
171 @Test
172 public void testDefaultTokenExpiry() throws Exception {
173 getTokenServices().setAccessTokenValiditySeconds(100);
174 OAuth2AccessToken accessToken = getTokenServices().createAccessToken(createAuthentication());
175 assertTrue(100 >= accessToken.getExpiresIn());
176 }
177
178 @Test
179 public void testClientSpecificTokenExpiry() throws Exception {
180 getTokenServices().setAccessTokenValiditySeconds(1000);
181 getTokenServices().setClientDetailsService(new ClientDetailsService() {
182 public ClientDetails loadClientByClientId(String clientId) throws OAuth2Exception {
183 BaseClientDetails client = new BaseClientDetails();
184 client.setAccessTokenValiditySeconds(100);
185 return client;
186 }
187 });
188 OAuth2AccessToken accessToken = getTokenServices().createAccessToken(createAuthentication());
189 assertTrue(100 >= accessToken.getExpiresIn());
190 }
191
192 @Test
193 public void testRefreshedTokenHasScopes() throws Exception {
194 ExpiringOAuth2RefreshToken expectedExpiringRefreshToken = (ExpiringOAuth2RefreshToken) getTokenServices()
195 .createAccessToken(createAuthentication()).getRefreshToken();
196 TokenRequest tokenRequest = new TokenRequest(Collections.singletonMap("client_id", "id"), "id", null, null);
197 OAuth2AccessToken refreshedAccessToken = getTokenServices()
198 .refreshAccessToken(expectedExpiringRefreshToken.getValue(), tokenRequest);
199 assertEquals("[read, write]", refreshedAccessToken.getScope().toString());
200 }
201
202 @Test
203 public void testRefreshedTokenNotExpiring() throws Exception {
204 getTokenServices().setRefreshTokenValiditySeconds(0);
205 OAuth2RefreshToken expectedExpiringRefreshToken = getTokenServices().createAccessToken(createAuthentication())
206 .getRefreshToken();
207 assertFalse(expectedExpiringRefreshToken instanceof DefaultExpiringOAuth2RefreshToken);
208 }
209
210 @Test
211 public void testRevokedTokenNotAvailable() throws Exception {
212 OAuth2Authentication authentication = createAuthentication();
213 OAuth2AccessToken token = getTokenServices().createAccessToken(authentication);
214 getTokenServices().revokeToken(token.getValue());
215 Collection<OAuth2AccessToken> tokens = getTokenStore().findTokensByClientIdAndUserName(
216 authentication.getOAuth2Request().getClientId(), authentication.getUserAuthentication().getName());
217 assertFalse(tokens.contains(token));
218 assertTrue(tokens.isEmpty());
219 }
220
221 protected void configureTokenServices(DefaultTokenServices services) throws Exception {
222 services.setTokenStore(tokenStore);
223 services.setSupportRefreshToken(true);
224 services.afterPropertiesSet();
225 }
226
227 protected abstract TokenStore createTokenStore();
228
229 protected OAuth2Authentication createAuthentication() {
230 return new OAuth2Authentication(
231 RequestTokenFactory.createOAuth2Request(null, "id", null, false,
232 new LinkedHashSet<String>(Arrays.asList("read", "write")), null, null, null, null),
233 new TestAuthentication("test2", false));
234 }
235
236 protected TokenStore getTokenStore() {
237 return tokenStore;
238 }
239
240 protected DefaultTokenServices getTokenServices() {
241 return services;
242 }
243
244 protected static class TestAuthentication extends AbstractAuthenticationToken {
245
246 private static final long serialVersionUID = 1L;
247
248 private String principal;
249
250 public TestAuthentication(String name, boolean authenticated) {
251 super(null);
252 setAuthenticated(authenticated);
253 this.principal = name;
254 }
255
256 public Object getCredentials() {
257 return null;
258 }
259
260 public Object getPrincipal() {
261 return this.principal;
262 }
263 }
264
265 }