1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.security.oauth2.provider.endpoint;
18
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.assertTrue;
22 import static org.mockito.Matchers.any;
23 import static org.mockito.Matchers.eq;
24 import static org.mockito.Mockito.when;
25
26 import java.security.Principal;
27 import java.util.Arrays;
28 import java.util.Collections;
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.Map;
32
33 import org.junit.Before;
34 import org.junit.Test;
35 import org.junit.runner.RunWith;
36 import org.mockito.ArgumentCaptor;
37 import org.mockito.Mock;
38 import org.mockito.Mockito;
39 import org.mockito.runners.MockitoJUnitRunner;
40 import org.springframework.http.HttpMethod;
41 import org.springframework.http.HttpStatus;
42 import org.springframework.http.ResponseEntity;
43 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
44 import org.springframework.security.core.authority.SimpleGrantedAuthority;
45 import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
46 import org.springframework.security.oauth2.common.OAuth2AccessToken;
47 import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
48 import org.springframework.security.oauth2.common.util.OAuth2Utils;
49 import org.springframework.security.oauth2.provider.ClientDetails;
50 import org.springframework.security.oauth2.provider.ClientDetailsService;
51 import org.springframework.security.oauth2.provider.OAuth2RequestFactory;
52 import org.springframework.security.oauth2.provider.TokenGranter;
53 import org.springframework.security.oauth2.provider.TokenRequest;
54 import org.springframework.security.oauth2.provider.client.BaseClientDetails;
55 import org.springframework.web.HttpRequestMethodNotSupportedException;
56
57
58
59
60
61 @RunWith(MockitoJUnitRunner.class)
62 public class TokenEndpointTests {
63
64 @Mock
65 private TokenGranter tokenGranter;
66
67 @Mock
68 private OAuth2RequestFactory authorizationRequestFactory;
69
70 @Mock
71 private ClientDetailsService clientDetailsService;
72
73 private String clientId = "client";
74 private BaseClientDetails clientDetails = new BaseClientDetails();
75
76 private TokenEndpoint endpoint;
77
78 private Principal clientAuthentication = new UsernamePasswordAuthenticationToken("client", null,
79 Collections.singleton(new SimpleGrantedAuthority("ROLE_CLIENT")));
80
81 private TokenRequest createFromParameters(Map<String, String> parameters) {
82 TokenRequest request = new TokenRequest(parameters, parameters.get(OAuth2Utils.CLIENT_ID),
83 OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.SCOPE)),
84 parameters.get(OAuth2Utils.GRANT_TYPE));
85 return request;
86 }
87
88 @Before
89 public void init() {
90 endpoint = new TokenEndpoint();
91 endpoint.setTokenGranter(tokenGranter);
92 endpoint.setOAuth2RequestFactory(authorizationRequestFactory);
93 endpoint.setClientDetailsService(clientDetailsService);
94 clientDetails.setClientId(clientId);
95 }
96
97 @Test
98 public void testGetAccessTokenWithNoClientId() throws HttpRequestMethodNotSupportedException {
99
100 HashMap<String, String> parameters = new HashMap<String, String>();
101 parameters.put(OAuth2Utils.GRANT_TYPE, "authorization_code");
102
103 OAuth2AccessToken expectedToken = new DefaultOAuth2AccessToken("FOO");
104 when(tokenGranter.grant(eq("authorization_code"), Mockito.any(TokenRequest.class))).thenReturn(
105 expectedToken);
106 @SuppressWarnings("unchecked")
107 Map<String, String> anyMap = Mockito.any(Map.class);
108 when(authorizationRequestFactory.createTokenRequest(anyMap, Mockito.any(ClientDetails.class))).thenReturn(
109 createFromParameters(parameters));
110
111 clientAuthentication = new UsernamePasswordAuthenticationToken(null, null,
112 Collections.singleton(new SimpleGrantedAuthority("ROLE_CLIENT")));
113 ResponseEntity<OAuth2AccessToken> response = endpoint.postAccessToken(clientAuthentication, parameters);
114
115 assertNotNull(response);
116 assertEquals(HttpStatus.OK, response.getStatusCode());
117 OAuth2AccessToken body = response.getBody();
118 assertEquals(body, expectedToken);
119 assertTrue("Wrong body: " + body, body.getTokenType() != null);
120 }
121
122 @Test
123 public void testGetAccessTokenWithScope() throws HttpRequestMethodNotSupportedException {
124
125 when(clientDetailsService.loadClientByClientId(clientId)).thenReturn(clientDetails);
126
127 HashMap<String, String> parameters = new HashMap<String, String>();
128 parameters.put("client_id", clientId);
129 parameters.put("scope", "read");
130 parameters.put("grant_type", "authorization_code");
131 parameters.put("code", "kJAHDFG");
132
133 OAuth2AccessToken expectedToken = new DefaultOAuth2AccessToken("FOO");
134 ArgumentCaptor<TokenRequest> captor = ArgumentCaptor.forClass(TokenRequest.class);
135
136 when(tokenGranter.grant(eq("authorization_code"), captor.capture())).thenReturn(expectedToken);
137 @SuppressWarnings("unchecked")
138 Map<String, String> anyMap = Mockito.any(Map.class);
139 when(authorizationRequestFactory.createTokenRequest(anyMap, eq(clientDetails))).thenReturn(
140 createFromParameters(parameters));
141
142 ResponseEntity<OAuth2AccessToken> response = endpoint.postAccessToken(clientAuthentication, parameters);
143
144 assertNotNull(response);
145 assertEquals(HttpStatus.OK, response.getStatusCode());
146 OAuth2AccessToken body = response.getBody();
147 assertEquals(body, expectedToken);
148 assertTrue("Wrong body: " + body, body.getTokenType() != null);
149 assertTrue("Scope of token request not cleared", captor.getValue().getScope().isEmpty());
150 }
151
152 @Test(expected = HttpRequestMethodNotSupportedException.class)
153 public void testGetAccessTokenWithUnsupportedRequestParameters() throws HttpRequestMethodNotSupportedException {
154 endpoint.getAccessToken(clientAuthentication, new HashMap<String, String>());
155 }
156
157 @Test
158 public void testGetAccessTokenWithSupportedRequestParametersNotPost() throws HttpRequestMethodNotSupportedException {
159 endpoint.setAllowedRequestMethods(new HashSet<HttpMethod>(Arrays.asList(HttpMethod.GET)));
160 HashMap<String, String> parameters = new HashMap<String, String>();
161 parameters.put("client_id", clientId);
162 parameters.put("scope", "read");
163 parameters.put("grant_type", "authorization_code");
164 parameters.put("code", "kJAHDFG");
165
166 OAuth2AccessToken expectedToken = new DefaultOAuth2AccessToken("FOO");
167 when(tokenGranter.grant(eq("authorization_code"), Mockito.any(TokenRequest.class))).thenReturn(
168 expectedToken);
169 @SuppressWarnings("unchecked")
170 Map<String, String> anyMap = Mockito.any(Map.class);
171 when(authorizationRequestFactory.createTokenRequest(anyMap, Mockito.any(ClientDetails.class))).thenReturn(
172 createFromParameters(parameters));
173
174 ResponseEntity<OAuth2AccessToken> response = endpoint.getAccessToken(clientAuthentication, parameters);
175 assertNotNull(response);
176 assertEquals(HttpStatus.OK, response.getStatusCode());
177 OAuth2AccessToken body = response.getBody();
178 assertEquals(body, expectedToken);
179 assertTrue("Wrong body: " + body, body.getTokenType() != null);
180 }
181
182 @Test(expected = InvalidGrantException.class)
183 public void testImplicitGrant() throws HttpRequestMethodNotSupportedException {
184 HashMap<String, String> parameters = new HashMap<String, String>();
185 parameters.put(OAuth2Utils.GRANT_TYPE, "implicit");
186 parameters.put("client_id", clientId);
187 parameters.put("scope", "read");
188 @SuppressWarnings("unchecked")
189 Map<String, String> anyMap = Mockito.any(Map.class);
190 when(authorizationRequestFactory.createTokenRequest(anyMap, eq(clientDetails))).thenReturn(
191 createFromParameters(parameters));
192 when(clientDetailsService.loadClientByClientId(clientId)).thenReturn(clientDetails);
193 endpoint.postAccessToken(clientAuthentication, parameters);
194 }
195
196
197 @Test
198 public void testGetAccessTokenReturnsHeaderContentTypeJson() throws Exception {
199 when(clientDetailsService.loadClientByClientId(clientId)).thenReturn(clientDetails);
200
201 HashMap<String, String> parameters = new HashMap<String, String>();
202 parameters.put("client_id", clientId);
203 parameters.put("scope", "read");
204 parameters.put("grant_type", "authorization_code");
205 parameters.put("code", "kJAHDFG");
206
207 OAuth2AccessToken expectedToken = new DefaultOAuth2AccessToken("FOO");
208
209 when(tokenGranter.grant(eq("authorization_code"), any(TokenRequest.class))).thenReturn(expectedToken);
210
211 when(authorizationRequestFactory.createTokenRequest(any(Map.class), eq(clientDetails))).thenReturn(
212 createFromParameters(parameters));
213
214 ResponseEntity<OAuth2AccessToken> response = endpoint.postAccessToken(clientAuthentication, parameters);
215
216 assertNotNull(response);
217 assertEquals(HttpStatus.OK, response.getStatusCode());
218 assertEquals("application/json;charset=UTF-8", response.getHeaders().get("Content-Type").iterator().next());
219 }
220 }