package org.springframework.security.oauth2.provider; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.IOException; import java.util.Arrays; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.junit.Rule; import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpRequest; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.client.ClientHttpRequestExecution; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.ClientHttpResponse; import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException; import org.springframework.security.oauth2.client.test.BeforeOAuth2Context; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; import org.springframework.security.oauth2.client.test.OAuth2ContextSetup; import org.springframework.security.oauth2.client.token.grant.implicit.ImplicitAccessTokenProvider; import org.springframework.security.oauth2.client.token.grant.implicit.ImplicitResourceDetails; import org.springframework.security.oauth2.common.util.OAuth2Utils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; /** * @author Ryan Heaton * @author Dave Syer */ public class ImplicitProviderTests { @Rule public ServerRunning serverRunning = ServerRunning.isRunning(); @Rule public OAuth2ContextSetup context = OAuth2ContextSetup.standard(serverRunning); private String cookie; private HttpHeaders latestHeaders = null; @BeforeOAuth2Context public void loginAndExtractCookie() { ResponseEntity<String> page = serverRunning.getForString("/sparklr2/login.jsp"); String cookie = page.getHeaders().getFirst("Set-Cookie"); HttpHeaders headers = new HttpHeaders(); headers.set("Cookie", cookie); Matcher matcher = Pattern.compile("(?s).*name=\"_csrf\".*?value=\"([^\"]+).*").matcher(page.getBody()); MultiValueMap<String, String> formData; formData = new LinkedMultiValueMap<String, String>(); formData.add("username", "marissa"); formData.add("password", "koala"); if (matcher.matches()) { formData.add("_csrf", matcher.group(1)); } String location = "/sparklr2/login"; ResponseEntity<Void> result = serverRunning.postForStatus(location, headers, formData); assertEquals(HttpStatus.FOUND, result.getStatusCode()); cookie = result.getHeaders().getFirst("Set-Cookie"); assertNotNull("Expected cookie in " + result.getHeaders(), cookie); this.cookie = cookie; } @Test(expected = UserRedirectRequiredException.class) @OAuth2ContextConfiguration(resource = AutoApproveImplicit.class, initialize = false) public void testRedirectRequiredForAuthentication() throws Exception { context.getAccessToken(); } @Test @OAuth2ContextConfiguration(resource = AutoApproveImplicit.class, initialize = false) public void testPostForAutomaticApprovalToken() throws Exception { final ImplicitAccessTokenProvider implicitProvider = new ImplicitAccessTokenProvider(); implicitProvider.setInterceptors(Arrays .<ClientHttpRequestInterceptor> asList(new ClientHttpRequestInterceptor() { public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { ClientHttpResponse result = execution.execute(request, body); latestHeaders = result.getHeaders(); return result; } })); context.setAccessTokenProvider(implicitProvider); context.getAccessTokenRequest().setCookie(cookie); assertNotNull(context.getAccessToken()); assertTrue("Wrong location header: " + latestHeaders.getLocation().getFragment(), latestHeaders.getLocation().getFragment() .contains("scope=read write trust")); } @Test @OAuth2ContextConfiguration(resource = NonAutoApproveImplicit.class, initialize = false) public void testPostForNonAutomaticApprovalToken() throws Exception { context.getAccessTokenRequest().setCookie(cookie); try { assertNotNull(context.getAccessToken()); fail("Expected UserRedirectRequiredException"); } catch (UserRedirectRequiredException e) { // ignore } // add user approval parameter for the second request context.getAccessTokenRequest().add(OAuth2Utils.USER_OAUTH_APPROVAL, "true"); context.getAccessTokenRequest().add("scope.read", "true"); assertNotNull(context.getAccessToken()); } static class AutoApproveImplicit extends ImplicitResourceDetails { public AutoApproveImplicit(Object target) { super(); setClientId("my-less-trusted-autoapprove-client"); setId(getClientId()); setPreEstablishedRedirectUri("http://anywhere"); ImplicitProviderTests test = (ImplicitProviderTests) target; setAccessTokenUri(test.serverRunning.getUrl("/sparklr2/oauth/authorize")); setUserAuthorizationUri(test.serverRunning.getUrl("/sparklr2/oauth/authorize")); } } static class NonAutoApproveImplicit extends AutoApproveImplicit { public NonAutoApproveImplicit(Object target) { super(target); setClientId("my-less-trusted-client"); } } }