/******************************************************************************* * Cloud Foundry * Copyright (c) [2009-2016] Pivotal Software, Inc. All Rights Reserved. * * This product is licensed to you under the Apache License, Version 2.0 (the "License"). * You may not use this product except in compliance with the License. * * This product includes a number of subcomponents with * separate copyright notices and license terms. Your use of these * subcomponents is subject to the terms and conditions of the * subcomponent's license, as noted in the LICENSE file. *******************************************************************************/ package org.cloudfoundry.identity.uaa.integration; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.cookie.BasicClientCookie; import org.cloudfoundry.identity.uaa.ServerRunning; import org.cloudfoundry.identity.uaa.integration.util.IntegrationTestUtils; import org.cloudfoundry.identity.uaa.security.web.CookieBasedCsrfTokenRepository; import org.cloudfoundry.identity.uaa.test.TestAccountSetup; import org.cloudfoundry.identity.uaa.test.UaaTestAccounts; import org.junit.Rule; import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import java.net.URI; import java.util.Arrays; import static org.cloudfoundry.identity.uaa.integration.util.IntegrationTestUtils.getHeaders; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; /** * Tests implicit grant using a direct posting of credentials to the /authorize * endpoint and also with an intermediate * form login. * * @author Dave Syer */ public class ImplicitTokenGrantIntegrationTests { private static final String REDIRECT_URL_PATTERN = "http://localhost:8080/redirect/cf#token_type=.+access_token=.+"; @Rule public ServerRunning serverRunning = ServerRunning.isRunning(); private UaaTestAccounts testAccounts = UaaTestAccounts.standard(serverRunning); @Rule public TestAccountSetup testAccountSetup = TestAccountSetup.standard(serverRunning, testAccounts); private String implicitUrl() { URI uri = serverRunning.buildUri("/oauth/authorize").queryParam("response_type", "token") .queryParam("client_id", "cf") .queryParam("redirect_uri", "http://localhost:8080/redirect/cf") .queryParam("scope", "cloud_controller.read").build(); return uri.toString(); } @Test public void authzViaJsonEndpointFailsWithHttpGet() throws Exception { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); String credentials = String.format("{\"username\":\"%s\",\"password\":\"%s\"}", testAccounts.getUserName(), testAccounts.getPassword()); ResponseEntity<Void> result = serverRunning.getForResponse(implicitUrl() + "&credentials={credentials}", headers, credentials); assertEquals(HttpStatus.UNAUTHORIZED, result.getStatusCode()); } @Test public void authzViaJsonEndpointSucceedsWithCorrectCredentials() throws Exception { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); String credentials = String.format("{ \"username\":\"%s\", \"password\":\"%s\" }", testAccounts.getUserName(), testAccounts.getPassword()); MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>(); formData.add("credentials", credentials); ResponseEntity<Void> result = serverRunning.postForResponse(implicitUrl(), headers, formData); assertNotNull(result.getHeaders().getLocation()); assertTrue(result.getHeaders().getLocation().toString() .matches(REDIRECT_URL_PATTERN)); } @Test public void authzViaJsonEndpointSucceedsWithAcceptForm() throws Exception { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.APPLICATION_FORM_URLENCODED)); String credentials = String.format("{ \"username\":\"%s\", \"password\":\"%s\" }", testAccounts.getUserName(), testAccounts.getPassword()); MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>(); formData.add("credentials", credentials); ResponseEntity<Void> result = serverRunning.postForResponse(implicitUrl(), headers, formData); URI location = result.getHeaders().getLocation(); assertNotNull(location); assertTrue("Wrong location: " + location, location.toString() .matches(REDIRECT_URL_PATTERN)); } @Test public void authzWithIntermediateFormLoginSucceeds() throws Exception { BasicCookieStore cookies = new BasicCookieStore(); ResponseEntity<Void> result = serverRunning.getForResponse(implicitUrl(), getHeaders(cookies)); assertEquals(HttpStatus.FOUND, result.getStatusCode()); String location = result.getHeaders().getLocation().toString(); if (result.getHeaders().containsKey("Set-Cookie")) { for (String cookie : result.getHeaders().get("Set-Cookie")) { int nameLength = cookie.indexOf('='); cookies.addCookie(new BasicClientCookie(cookie.substring(0, nameLength), cookie.substring(nameLength+1))); } } ResponseEntity<String> response = serverRunning.getForString(location, getHeaders(cookies)); if (response.getHeaders().containsKey("Set-Cookie")) { for (String cookie : response.getHeaders().get("Set-Cookie")) { int nameLength = cookie.indexOf('='); cookies.addCookie(new BasicClientCookie(cookie.substring(0, nameLength), cookie.substring(nameLength+1))); } } // should be directed to the login screen... assertTrue(response.getBody().contains("/login.do")); assertTrue(response.getBody().contains("username")); assertTrue(response.getBody().contains("password")); location = "/login.do"; MultiValueMap<String, String> formData = new LinkedMultiValueMap<>(); formData.add("username", testAccounts.getUserName()); formData.add("password", testAccounts.getPassword()); formData.add(CookieBasedCsrfTokenRepository.DEFAULT_CSRF_COOKIE_NAME, IntegrationTestUtils.extractCookieCsrf(response.getBody())); result = serverRunning.postForRedirect(location, getHeaders(cookies), formData); // System.err.println(result.getStatusCode()); // System.err.println(result.getHeaders()); assertNotNull(result.getHeaders().getLocation()); assertTrue(result.getHeaders().getLocation().toString() .matches(REDIRECT_URL_PATTERN)); } }