/support/cas-server-support-oauth/src/test/java/org/apereo/cas/support/oauth/web/OAuth20AccessTokenControllerTests.java

https://github.com/frett/cas · Java · 645 lines · 556 code · 83 blank · 6 comment · 1 complexity · 2547f17eb9ff96ce6a1e7893c859e27a MD5 · raw file

  1. package org.apereo.cas.support.oauth.web;
  2. import org.apereo.cas.CasProtocolConstants;
  3. import org.apereo.cas.authentication.CoreAuthenticationTestUtils;
  4. import org.apereo.cas.authentication.principal.WebApplicationServiceFactory;
  5. import org.apereo.cas.mock.MockTicketGrantingTicket;
  6. import org.apereo.cas.support.oauth.OAuth20Constants;
  7. import org.apereo.cas.support.oauth.OAuth20GrantTypes;
  8. import org.apereo.cas.support.oauth.OAuth20ResponseTypes;
  9. import org.apereo.cas.support.oauth.web.endpoints.OAuth20AccessTokenEndpointController;
  10. import org.apereo.cas.support.oauth.web.endpoints.OAuth20DeviceUserCodeApprovalEndpointController;
  11. import org.apereo.cas.ticket.accesstoken.AccessToken;
  12. import org.apereo.cas.ticket.code.DefaultOAuthCodeFactory;
  13. import org.apereo.cas.ticket.refreshtoken.DefaultRefreshTokenFactory;
  14. import org.apereo.cas.ticket.support.AlwaysExpiresExpirationPolicy;
  15. import org.apereo.cas.util.CollectionUtils;
  16. import lombok.val;
  17. import org.apache.commons.lang3.StringUtils;
  18. import org.apache.http.HttpStatus;
  19. import org.junit.Before;
  20. import org.junit.Test;
  21. import org.springframework.http.HttpMethod;
  22. import org.springframework.mock.web.MockHttpServletRequest;
  23. import org.springframework.mock.web.MockHttpServletResponse;
  24. import org.springframework.mock.web.MockHttpSession;
  25. import java.util.ArrayList;
  26. import java.util.Arrays;
  27. import java.util.HashMap;
  28. import static org.junit.Assert.*;
  29. /**
  30. * This class tests the {@link OAuth20AccessTokenEndpointController} class.
  31. *
  32. * @author Jerome Leleu
  33. * @since 3.5.2
  34. */
  35. public class OAuth20AccessTokenControllerTests extends AbstractOAuth20Tests {
  36. @Before
  37. public void initialize() {
  38. clearAllServices();
  39. }
  40. @Test
  41. public void verifyClientNoClientId() throws Exception {
  42. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  43. mockRequest.setParameter(OAuth20Constants.REDIRECT_URI, REDIRECT_URI);
  44. mockRequest.setParameter(OAuth20Constants.CLIENT_SECRET, CLIENT_SECRET);
  45. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.AUTHORIZATION_CODE.name().toLowerCase());
  46. val principal = createPrincipal();
  47. val service = addRegisteredService(
  48. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  49. val code = addCode(principal, service);
  50. mockRequest.setParameter(OAuth20Constants.CODE, code.getId());
  51. val mockResponse = new MockHttpServletResponse();
  52. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  53. val mv = controller.handleRequest(mockRequest, mockResponse);
  54. assertEquals(HttpStatus.SC_UNAUTHORIZED, mockResponse.getStatus());
  55. assertEquals(OAuth20Constants.INVALID_REQUEST, mv.getModel().get("error"));
  56. }
  57. @Test
  58. public void verifyClientNoRedirectUri() throws Exception {
  59. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  60. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  61. mockRequest.setParameter(OAuth20Constants.CLIENT_SECRET, CLIENT_SECRET);
  62. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.AUTHORIZATION_CODE.name().toLowerCase());
  63. val principal = createPrincipal();
  64. val service = addRegisteredService(
  65. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  66. val code = addCode(principal, service);
  67. mockRequest.setParameter(OAuth20Constants.CODE, code.getId());
  68. val mockResponse = new MockHttpServletResponse();
  69. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  70. val mv = controller.handleRequest(mockRequest, mockResponse);
  71. assertEquals(HttpStatus.SC_BAD_REQUEST, mockResponse.getStatus());
  72. assertEquals(OAuth20Constants.INVALID_REQUEST, mv.getModel().get("error"));
  73. }
  74. @Test
  75. public void verifyClientNoAuthorizationCode() throws Exception {
  76. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  77. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  78. mockRequest.setParameter(OAuth20Constants.REDIRECT_URI, REDIRECT_URI);
  79. mockRequest.setParameter(OAuth20Constants.CLIENT_SECRET, CLIENT_SECRET);
  80. val principal = createPrincipal();
  81. val service = addRegisteredService(
  82. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  83. val code = addCode(principal, service);
  84. mockRequest.setParameter(OAuth20Constants.CODE, code.getId());
  85. val mockResponse = new MockHttpServletResponse();
  86. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  87. val mv = controller.handleRequest(mockRequest, mockResponse);
  88. assertEquals(HttpStatus.SC_BAD_REQUEST, mockResponse.getStatus());
  89. assertEquals(OAuth20Constants.INVALID_REQUEST, mv.getModel().get("error"));
  90. }
  91. @Test
  92. public void verifyClientBadGrantType() throws Exception {
  93. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  94. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  95. mockRequest.setParameter(OAuth20Constants.REDIRECT_URI, REDIRECT_URI);
  96. mockRequest.setParameter(OAuth20Constants.CLIENT_SECRET, CLIENT_SECRET);
  97. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, "badValue");
  98. val principal = createPrincipal();
  99. val service = addRegisteredService(
  100. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  101. val code = addCode(principal, service);
  102. mockRequest.setParameter(OAuth20Constants.CODE, code.getId());
  103. val mockResponse = new MockHttpServletResponse();
  104. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  105. val mv = controller.handleRequest(mockRequest, mockResponse);
  106. assertEquals(HttpStatus.SC_BAD_REQUEST, mockResponse.getStatus());
  107. assertEquals(OAuth20Constants.INVALID_REQUEST, mv.getModel().get("error"));
  108. }
  109. @Test
  110. public void verifyClientDisallowedGrantType() throws Exception {
  111. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  112. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  113. mockRequest.setParameter(OAuth20Constants.REDIRECT_URI, REDIRECT_URI);
  114. mockRequest.setParameter(OAuth20Constants.CLIENT_SECRET, CLIENT_SECRET);
  115. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.PASSWORD.getType());
  116. val principal = createPrincipal();
  117. val service = addRegisteredService(
  118. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  119. val code = addCode(principal, service);
  120. mockRequest.setParameter(OAuth20Constants.CODE, code.getId());
  121. val mockResponse = new MockHttpServletResponse();
  122. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  123. val mv = controller.handleRequest(mockRequest, mockResponse);
  124. assertEquals(HttpStatus.SC_BAD_REQUEST, mockResponse.getStatus());
  125. assertEquals(OAuth20Constants.INVALID_REQUEST, mv.getModel().get("error"));
  126. }
  127. @Test
  128. public void verifyClientNoClientSecret() throws Exception {
  129. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  130. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  131. mockRequest.setParameter(OAuth20Constants.REDIRECT_URI, REDIRECT_URI);
  132. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.AUTHORIZATION_CODE.name().toLowerCase());
  133. val principal = createPrincipal();
  134. val service = addRegisteredService(
  135. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  136. val code = addCode(principal, service);
  137. mockRequest.setParameter(OAuth20Constants.CODE, code.getId());
  138. val mockResponse = new MockHttpServletResponse();
  139. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  140. val mv = controller.handleRequest(mockRequest, mockResponse);
  141. assertEquals(HttpStatus.SC_UNAUTHORIZED, mockResponse.getStatus());
  142. assertEquals(OAuth20Constants.INVALID_REQUEST, mv.getModel().get("error"));
  143. }
  144. @Test
  145. public void verifyClientNoCode() throws Exception {
  146. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  147. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  148. mockRequest.setParameter(OAuth20Constants.REDIRECT_URI, REDIRECT_URI);
  149. mockRequest.setParameter(OAuth20Constants.CLIENT_SECRET, CLIENT_SECRET);
  150. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.AUTHORIZATION_CODE.name().toLowerCase());
  151. val principal = createPrincipal();
  152. val service = addRegisteredService(
  153. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  154. addCode(principal, service);
  155. val mockResponse = new MockHttpServletResponse();
  156. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  157. val mv = controller.handleRequest(mockRequest, mockResponse);
  158. assertEquals(HttpStatus.SC_BAD_REQUEST, mockResponse.getStatus());
  159. assertEquals(OAuth20Constants.INVALID_REQUEST, mv.getModel().get(OAuth20Constants.ERROR));
  160. }
  161. @Test
  162. public void verifyClientNoCasService() throws Exception {
  163. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  164. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  165. mockRequest.setParameter(OAuth20Constants.REDIRECT_URI, REDIRECT_URI);
  166. mockRequest.setParameter(OAuth20Constants.CLIENT_SECRET, CLIENT_SECRET);
  167. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.AUTHORIZATION_CODE.name().toLowerCase());
  168. val principal = createPrincipal();
  169. val registeredService = getRegisteredService(
  170. REDIRECT_URI, CLIENT_SECRET, CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  171. val code = addCode(principal, registeredService);
  172. mockRequest.setParameter(OAuth20Constants.CODE, code.getId());
  173. val mockResponse = new MockHttpServletResponse();
  174. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  175. val mv = controller.handleRequest(mockRequest, mockResponse);
  176. assertEquals(HttpStatus.SC_UNAUTHORIZED, mockResponse.getStatus());
  177. assertEquals(OAuth20Constants.INVALID_REQUEST, mv.getModel().get(OAuth20Constants.ERROR));
  178. }
  179. @Test
  180. public void verifyClientRedirectUriDoesNotStartWithServiceId() throws Exception {
  181. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  182. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  183. mockRequest.setParameter(OAuth20Constants.REDIRECT_URI, OTHER_REDIRECT_URI);
  184. mockRequest.setParameter(OAuth20Constants.CLIENT_SECRET, CLIENT_SECRET);
  185. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.AUTHORIZATION_CODE.name().toLowerCase());
  186. val principal = createPrincipal();
  187. val service = addRegisteredService(
  188. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  189. val code = addCode(principal, service);
  190. mockRequest.setParameter(OAuth20Constants.CODE, code.getId());
  191. val mockResponse = new MockHttpServletResponse();
  192. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  193. val mv = controller.handleRequest(mockRequest, mockResponse);
  194. assertEquals(HttpStatus.SC_BAD_REQUEST, mockResponse.getStatus());
  195. assertEquals(OAuth20Constants.INVALID_REQUEST, mv.getModel().get(OAuth20Constants.ERROR));
  196. }
  197. @Test
  198. public void verifyClientWrongSecret() throws Exception {
  199. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  200. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  201. mockRequest.setParameter(OAuth20Constants.REDIRECT_URI, REDIRECT_URI);
  202. mockRequest.setParameter(OAuth20Constants.CLIENT_SECRET, WRONG_CLIENT_SECRET);
  203. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.AUTHORIZATION_CODE.name().toLowerCase());
  204. val principal = createPrincipal();
  205. val service = addRegisteredService(
  206. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  207. val code = addCode(principal, service);
  208. mockRequest.setParameter(OAuth20Constants.CODE, code.getId());
  209. val mockResponse = new MockHttpServletResponse();
  210. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  211. val mv = controller.handleRequest(mockRequest, mockResponse);
  212. assertEquals(HttpStatus.SC_UNAUTHORIZED, mockResponse.getStatus());
  213. assertEquals(OAuth20Constants.INVALID_REQUEST, mv.getModel().get(OAuth20Constants.ERROR));
  214. }
  215. @Test
  216. public void verifyClientExpiredCode() throws Exception {
  217. val registeredService = getRegisteredService(REDIRECT_URI, CLIENT_SECRET,
  218. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  219. servicesManager.save(registeredService);
  220. val map = new HashMap<String, Object>();
  221. map.put(NAME, VALUE);
  222. val list = Arrays.asList(VALUE, VALUE);
  223. map.put(NAME2, list);
  224. val principal = CoreAuthenticationTestUtils.getPrincipal(ID, map);
  225. val authentication = getAuthentication(principal);
  226. val expiringOAuthCodeFactory = new DefaultOAuthCodeFactory(new AlwaysExpiresExpirationPolicy());
  227. val factory = new WebApplicationServiceFactory();
  228. val service = factory.createService(registeredService.getServiceId());
  229. val code = expiringOAuthCodeFactory.create(service, authentication,
  230. new MockTicketGrantingTicket("casuser"), new ArrayList<>(), null, null);
  231. this.ticketRegistry.addTicket(code);
  232. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  233. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  234. mockRequest.setParameter(OAuth20Constants.REDIRECT_URI, REDIRECT_URI);
  235. mockRequest.setParameter(OAuth20Constants.CLIENT_SECRET, CLIENT_SECRET);
  236. mockRequest.setParameter(OAuth20Constants.CODE, code.getId());
  237. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.AUTHORIZATION_CODE.name().toLowerCase());
  238. servicesManager.save(getRegisteredService(REDIRECT_URI, CLIENT_SECRET,
  239. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE)));
  240. val mockResponse = new MockHttpServletResponse();
  241. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  242. val mv = controller.handleRequest(mockRequest, mockResponse);
  243. assertEquals(HttpStatus.SC_BAD_REQUEST, mockResponse.getStatus());
  244. assertEquals(OAuth20Constants.INVALID_REQUEST, mv.getModel().get(OAuth20Constants.ERROR));
  245. }
  246. @Test
  247. public void verifyClientAuthByParameter() throws Exception {
  248. val service = addRegisteredService(
  249. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  250. internalVerifyClientOK(service, false);
  251. }
  252. @Test
  253. public void verifyDeviceFlowGeneratesCode() throws Exception {
  254. addRegisteredService();
  255. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  256. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  257. mockRequest.setParameter(OAuth20Constants.RESPONSE_TYPE, OAuth20ResponseTypes.DEVICE_CODE.getType());
  258. val mockResponse = new MockHttpServletResponse();
  259. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  260. val mv = controller.handleRequest(mockRequest, mockResponse);
  261. val model = mv.getModel();
  262. assertTrue(model.containsKey(OAuth20Constants.DEVICE_CODE));
  263. assertTrue(model.containsKey(OAuth20Constants.DEVICE_VERIFICATION_URI));
  264. assertTrue(model.containsKey(OAuth20Constants.DEVICE_USER_CODE));
  265. assertTrue(model.containsKey(OAuth20Constants.DEVICE_INTERVAL));
  266. assertTrue(model.containsKey(OAuth20Constants.EXPIRES_IN));
  267. val devCode = model.get(OAuth20Constants.DEVICE_CODE).toString();
  268. val userCode = model.get(OAuth20Constants.DEVICE_USER_CODE).toString();
  269. val devReq = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.DEVICE_AUTHZ_URL);
  270. devReq.setParameter(OAuth20DeviceUserCodeApprovalEndpointController.PARAMETER_USER_CODE, userCode);
  271. val devResp = new MockHttpServletResponse();
  272. val mvDev = deviceController.handlePostRequest(devReq, devResp);
  273. assertTrue(mvDev.getStatus().is2xxSuccessful());
  274. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  275. mockRequest.setParameter(OAuth20Constants.RESPONSE_TYPE, OAuth20ResponseTypes.DEVICE_CODE.getType());
  276. mockRequest.setParameter(OAuth20Constants.CODE, devCode);
  277. val approveResp = new MockHttpServletResponse();
  278. requiresAuthenticationInterceptor.preHandle(mockRequest, approveResp, null);
  279. val mvApproved = controller.handleRequest(mockRequest, approveResp);
  280. assertTrue(mvApproved.getModel().containsKey(OAuth20Constants.ACCESS_TOKEN));
  281. assertTrue(mvApproved.getModel().containsKey(OAuth20Constants.EXPIRES_IN));
  282. assertTrue(mvApproved.getModel().containsKey(OAuth20Constants.TOKEN_TYPE));
  283. }
  284. @Test
  285. public void verifyClientAuthByHeader() throws Exception {
  286. val service = addRegisteredService(
  287. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  288. internalVerifyClientOK(service, false);
  289. }
  290. @Test
  291. public void verifyClientAuthByParameterWithRefreshToken() throws Exception {
  292. val service = addRegisteredService(
  293. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  294. service.setGenerateRefreshToken(true);
  295. internalVerifyClientOK(service, true);
  296. }
  297. @Test
  298. public void verifyClientAuthByHeaderWithRefreshToken() throws Exception {
  299. val service = addRegisteredService(
  300. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  301. service.setGenerateRefreshToken(true);
  302. internalVerifyClientOK(service, true);
  303. }
  304. @Test
  305. public void verifyClientAuthJsonByParameter() throws Exception {
  306. val service = addRegisteredService(
  307. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  308. internalVerifyClientOK(service, false);
  309. }
  310. @Test
  311. public void verifyClientAuthJsonByHeader() throws Exception {
  312. val service = addRegisteredService(
  313. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  314. internalVerifyClientOK(service, false);
  315. }
  316. @Test
  317. public void verifyClientAuthJsonByParameterWithRefreshToken() throws Exception {
  318. val service = addRegisteredService(
  319. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  320. service.setGenerateRefreshToken(true);
  321. internalVerifyClientOK(service, true);
  322. }
  323. @Test
  324. public void verifyClientAuthJsonByHeaderWithRefreshToken() throws Exception {
  325. val service = addRegisteredService(
  326. CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  327. service.setGenerateRefreshToken(true);
  328. internalVerifyClientOK(service, true);
  329. }
  330. @Test
  331. public void ensureOnlyRefreshTokenIsAcceptedForRefreshGrant() throws Exception {
  332. addRegisteredService(true, CollectionUtils.wrapSet(OAuth20GrantTypes.PASSWORD,
  333. OAuth20GrantTypes.REFRESH_TOKEN));
  334. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  335. val mockSession = new MockHttpSession();
  336. mockRequest.setSession(mockSession);
  337. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.PASSWORD.name().toLowerCase());
  338. mockRequest.setParameter(USERNAME, GOOD_USERNAME);
  339. mockRequest.setParameter(PASSWORD, GOOD_PASSWORD);
  340. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  341. var mockResponse = new MockHttpServletResponse();
  342. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  343. var mv = controller.handleRequest(mockRequest, mockResponse);
  344. assertTrue(mv.getModel().containsKey(OAuth20Constants.REFRESH_TOKEN));
  345. assertTrue(mv.getModel().containsKey(OAuth20Constants.ACCESS_TOKEN));
  346. val refreshToken = mv.getModel().get(OAuth20Constants.REFRESH_TOKEN).toString();
  347. val accessToken = mv.getModel().get(OAuth20Constants.ACCESS_TOKEN).toString();
  348. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.REFRESH_TOKEN.name().toLowerCase());
  349. mockRequest.setParameter(OAuth20Constants.CLIENT_SECRET, CLIENT_SECRET);
  350. mockRequest.setParameter(OAuth20Constants.REFRESH_TOKEN, accessToken);
  351. mockResponse = new MockHttpServletResponse();
  352. controller.handleRequest(mockRequest, mockResponse);
  353. assertEquals(HttpStatus.SC_BAD_REQUEST, mockResponse.getStatus());
  354. mockRequest.setParameter(OAuth20Constants.REFRESH_TOKEN, refreshToken);
  355. mockResponse = new MockHttpServletResponse();
  356. mv = controller.handleRequest(mockRequest, mockResponse);
  357. assertEquals(HttpStatus.SC_OK, mockResponse.getStatus());
  358. assertTrue(mv.getModel().containsKey(OAuth20Constants.ACCESS_TOKEN));
  359. }
  360. @Test
  361. public void verifyUserNoClientId() throws Exception {
  362. addRegisteredService(CollectionUtils.wrapSet(OAuth20GrantTypes.PASSWORD));
  363. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  364. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.PASSWORD.name().toLowerCase());
  365. mockRequest.setParameter(USERNAME, GOOD_USERNAME);
  366. mockRequest.setParameter(PASSWORD, GOOD_PASSWORD);
  367. val mockResponse = new MockHttpServletResponse();
  368. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  369. val mv = controller.handleRequest(mockRequest, mockResponse);
  370. assertEquals(HttpStatus.SC_UNAUTHORIZED, mockResponse.getStatus());
  371. assertEquals(OAuth20Constants.INVALID_REQUEST, mv.getModel().get(OAuth20Constants.ERROR));
  372. }
  373. @Test
  374. public void verifyUserNoCasService() throws Exception {
  375. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  376. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  377. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.PASSWORD.name().toLowerCase());
  378. mockRequest.setParameter(USERNAME, GOOD_USERNAME);
  379. mockRequest.setParameter(PASSWORD, GOOD_PASSWORD);
  380. val mockResponse = new MockHttpServletResponse();
  381. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  382. val mv = controller.handleRequest(mockRequest, mockResponse);
  383. assertEquals(HttpStatus.SC_UNAUTHORIZED, mockResponse.getStatus());
  384. assertEquals(OAuth20Constants.INVALID_REQUEST, mv.getModel().get(OAuth20Constants.ERROR));
  385. }
  386. @Test
  387. public void verifyUserBadAuthorizationCode() throws Exception {
  388. addRegisteredService(CollectionUtils.wrapSet(OAuth20GrantTypes.AUTHORIZATION_CODE));
  389. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  390. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  391. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.AUTHORIZATION_CODE.name().toLowerCase());
  392. mockRequest.setParameter(USERNAME, GOOD_USERNAME);
  393. mockRequest.setParameter(PASSWORD, GOOD_PASSWORD);
  394. val mockResponse = new MockHttpServletResponse();
  395. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  396. val mv = controller.handleRequest(mockRequest, mockResponse);
  397. assertEquals(HttpStatus.SC_BAD_REQUEST, mockResponse.getStatus());
  398. assertEquals(OAuth20Constants.INVALID_REQUEST, mv.getModel().get(OAuth20Constants.ERROR));
  399. }
  400. @Test
  401. public void verifyUserBadCredentials() throws Exception {
  402. addRegisteredService(CollectionUtils.wrapSet(OAuth20GrantTypes.PASSWORD));
  403. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  404. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  405. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.PASSWORD.name().toLowerCase());
  406. mockRequest.setParameter(USERNAME, GOOD_USERNAME);
  407. mockRequest.setParameter(PASSWORD, "badPassword");
  408. val mockResponse = new MockHttpServletResponse();
  409. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  410. val mv = controller.handleRequest(mockRequest, mockResponse);
  411. assertEquals(HttpStatus.SC_UNAUTHORIZED, mockResponse.getStatus());
  412. assertEquals(OAuth20Constants.INVALID_REQUEST, mv.getModel().get(OAuth20Constants.ERROR));
  413. }
  414. @Test
  415. public void verifyUserAuth() throws Exception {
  416. addRegisteredService(CollectionUtils.wrapSet(OAuth20GrantTypes.PASSWORD));
  417. internalVerifyUserAuth(false);
  418. }
  419. @Test
  420. public void verifyUserAuthWithRefreshToken() throws Exception {
  421. val registeredService = addRegisteredService(
  422. CollectionUtils.wrapSet(OAuth20GrantTypes.PASSWORD));
  423. registeredService.setGenerateRefreshToken(true);
  424. internalVerifyUserAuth(true);
  425. }
  426. @Test
  427. public void verifyJsonUserAuth() throws Exception {
  428. addRegisteredService(CollectionUtils.wrapSet(OAuth20GrantTypes.PASSWORD));
  429. internalVerifyUserAuth(false);
  430. }
  431. @Test
  432. public void verifyJsonUserAuthWithRefreshToken() throws Exception {
  433. val registeredService = addRegisteredService(
  434. CollectionUtils.wrapSet(OAuth20GrantTypes.PASSWORD));
  435. registeredService.setGenerateRefreshToken(true);
  436. internalVerifyUserAuth(true);
  437. }
  438. private void internalVerifyUserAuth(final boolean refreshToken) throws Exception {
  439. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  440. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  441. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.PASSWORD.name().toLowerCase());
  442. mockRequest.setParameter(USERNAME, GOOD_USERNAME);
  443. mockRequest.setParameter(PASSWORD, GOOD_PASSWORD);
  444. mockRequest.addHeader(CasProtocolConstants.PARAMETER_SERVICE, REDIRECT_URI);
  445. val mockResponse = new MockHttpServletResponse();
  446. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  447. val mv = controller.handleRequest(mockRequest, mockResponse);
  448. assertEquals(200, mockResponse.getStatus());
  449. var accessTokenId = StringUtils.EMPTY;
  450. assertTrue(mv.getModel().containsKey(OAuth20Constants.ACCESS_TOKEN));
  451. if (refreshToken) {
  452. assertTrue(mv.getModel().containsKey(OAuth20Constants.REFRESH_TOKEN));
  453. }
  454. assertTrue(mv.getModel().containsKey(OAuth20Constants.EXPIRES_IN));
  455. accessTokenId = mv.getModel().get(OAuth20Constants.ACCESS_TOKEN).toString();
  456. val accessToken = this.ticketRegistry.getTicket(accessTokenId, AccessToken.class);
  457. assertEquals(GOOD_USERNAME, accessToken.getAuthentication().getPrincipal().getId());
  458. val timeLeft = Integer.parseInt(mv.getModel().get(OAuth20Constants.EXPIRES_IN).toString());
  459. assertTrue(timeLeft >= TIMEOUT - 10 - DELTA);
  460. }
  461. @Test
  462. public void verifyRefreshTokenExpiredToken() throws Exception {
  463. val principal = createPrincipal();
  464. val registeredService = addRegisteredService(
  465. CollectionUtils.wrapSet(OAuth20GrantTypes.REFRESH_TOKEN));
  466. val authentication = getAuthentication(principal);
  467. val factory = new WebApplicationServiceFactory();
  468. val service = factory.createService(registeredService.getServiceId());
  469. val expiringRefreshTokenFactory = new DefaultRefreshTokenFactory(new AlwaysExpiresExpirationPolicy());
  470. val refreshToken = expiringRefreshTokenFactory.create(service, authentication,
  471. new MockTicketGrantingTicket("casuser"), new ArrayList<>());
  472. this.ticketRegistry.addTicket(refreshToken);
  473. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  474. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.REFRESH_TOKEN.name().toLowerCase());
  475. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  476. mockRequest.setParameter(OAuth20Constants.CLIENT_SECRET, CLIENT_SECRET);
  477. mockRequest.setParameter(OAuth20Constants.REFRESH_TOKEN, refreshToken.getId());
  478. val mockResponse = new MockHttpServletResponse();
  479. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  480. val mv = controller.handleRequest(mockRequest, mockResponse);
  481. assertEquals(HttpStatus.SC_BAD_REQUEST, mockResponse.getStatus());
  482. assertEquals(OAuth20Constants.INVALID_REQUEST, mv.getModel().get(OAuth20Constants.ERROR));
  483. }
  484. @Test
  485. public void verifyRefreshTokenBadCredentials() throws Exception {
  486. val principal = createPrincipal();
  487. val service = addRegisteredService(
  488. CollectionUtils.wrapSet(OAuth20GrantTypes.REFRESH_TOKEN));
  489. val refreshToken = addRefreshToken(principal, service);
  490. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  491. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.REFRESH_TOKEN.name().toLowerCase());
  492. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  493. mockRequest.setParameter(OAuth20Constants.CLIENT_SECRET, WRONG_CLIENT_SECRET);
  494. mockRequest.setParameter(OAuth20Constants.REFRESH_TOKEN, refreshToken.getId());
  495. val mockResponse = new MockHttpServletResponse();
  496. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  497. val mv = controller.handleRequest(mockRequest, mockResponse);
  498. assertEquals(HttpStatus.SC_UNAUTHORIZED, mockResponse.getStatus());
  499. assertEquals(OAuth20Constants.INVALID_REQUEST, mv.getModel().get(OAuth20Constants.ERROR));
  500. }
  501. @Test
  502. public void verifyRefreshTokenMissingToken() throws Exception {
  503. addRegisteredService(CollectionUtils.wrapSet(OAuth20GrantTypes.REFRESH_TOKEN));
  504. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  505. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.REFRESH_TOKEN.name().toLowerCase());
  506. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  507. mockRequest.setParameter(OAuth20Constants.CLIENT_SECRET, CLIENT_SECRET);
  508. val mockResponse = new MockHttpServletResponse();
  509. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  510. val mv = controller.handleRequest(mockRequest, mockResponse);
  511. assertEquals(HttpStatus.SC_BAD_REQUEST, mockResponse.getStatus());
  512. assertEquals(OAuth20Constants.INVALID_REQUEST, mv.getModel().get(OAuth20Constants.ERROR));
  513. }
  514. @Test
  515. public void verifyRefreshTokenOKWithExpiredTicketGrantingTicket() throws Exception {
  516. val principal = createPrincipal();
  517. val service = addRegisteredService(
  518. CollectionUtils.wrapSet(OAuth20GrantTypes.REFRESH_TOKEN));
  519. val refreshToken = addRefreshToken(principal, service);
  520. refreshToken.getTicketGrantingTicket().markTicketExpired();
  521. val mockRequest = new MockHttpServletRequest(HttpMethod.GET.name(), CONTEXT + OAuth20Constants.ACCESS_TOKEN_URL);
  522. mockRequest.setParameter(OAuth20Constants.GRANT_TYPE, OAuth20GrantTypes.REFRESH_TOKEN.name().toLowerCase());
  523. mockRequest.setParameter(OAuth20Constants.CLIENT_ID, CLIENT_ID);
  524. mockRequest.setParameter(OAuth20Constants.CLIENT_SECRET, CLIENT_SECRET);
  525. mockRequest.setParameter(OAuth20Constants.REFRESH_TOKEN, refreshToken.getId());
  526. val mockResponse = new MockHttpServletResponse();
  527. requiresAuthenticationInterceptor.preHandle(mockRequest, mockResponse, null);
  528. val mv = controller.handleRequest(mockRequest, mockResponse);
  529. assertEquals(HttpStatus.SC_OK, mockResponse.getStatus());
  530. val accessTokenId = mv.getModel().get(OAuth20Constants.ACCESS_TOKEN).toString();
  531. val accessToken = this.ticketRegistry.getTicket(accessTokenId, AccessToken.class);
  532. assertEquals(principal, accessToken.getAuthentication().getPrincipal());
  533. val timeLeft = Integer.parseInt(mv.getModel().get(OAuth20Constants.EXPIRES_IN).toString());
  534. assertTrue(timeLeft >= TIMEOUT - 10 - DELTA);
  535. }
  536. @Test
  537. public void verifyRefreshTokenOK() throws Exception {
  538. val service = addRegisteredService(
  539. CollectionUtils.wrapSet(OAuth20GrantTypes.REFRESH_TOKEN));
  540. internalVerifyRefreshTokenOk(service);
  541. }
  542. @Test
  543. public void verifyRefreshTokenOKWithRefreshToken() throws Exception {
  544. val service = addRegisteredService(
  545. CollectionUtils.wrapSet(OAuth20GrantTypes.REFRESH_TOKEN));
  546. service.setGenerateRefreshToken(true);
  547. internalVerifyRefreshTokenOk(service);
  548. }
  549. @Test
  550. public void verifyJsonRefreshTokenOK() throws Exception {
  551. val service = addRegisteredService(
  552. CollectionUtils.wrapSet(OAuth20GrantTypes.REFRESH_TOKEN));
  553. internalVerifyRefreshTokenOk(service);
  554. }
  555. @Test
  556. public void verifyJsonRefreshTokenOKWithRefreshToken() throws Exception {
  557. val service = addRegisteredService(
  558. CollectionUtils.wrapSet(OAuth20GrantTypes.REFRESH_TOKEN));
  559. service.setGenerateRefreshToken(true);
  560. internalVerifyRefreshTokenOk(service);
  561. }
  562. }