/* * Copyright 2006-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ package org.springframework.security.oauth2.provider.code; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.junit.Test; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; import org.springframework.security.oauth2.common.exceptions.RedirectMismatchException; import org.springframework.security.oauth2.common.util.OAuth2Utils; import org.springframework.security.oauth2.provider.ClientDetails; import org.springframework.security.oauth2.provider.ClientDetailsService; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.OAuth2Request; import org.springframework.security.oauth2.provider.OAuth2RequestFactory; import org.springframework.security.oauth2.provider.RequestTokenFactory; import org.springframework.security.oauth2.provider.TokenRequest; import org.springframework.security.oauth2.provider.client.BaseClientDetails; import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory; import org.springframework.security.oauth2.provider.token.DefaultTokenServices; import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** * @author Dave Syer * */ public class AuthorizationCodeTokenGranterTests { private DefaultTokenServices providerTokenServices = new DefaultTokenServices(); private BaseClientDetails client = new BaseClientDetails("foo", "resource", "scope", "authorization_code", "ROLE_CLIENT"); private ClientDetailsService clientDetailsService = new ClientDetailsService() { public ClientDetails loadClientByClientId(String clientId) throws OAuth2Exception { return client; } }; private AuthorizationCodeServices authorizationCodeServices = new InMemoryAuthorizationCodeServices(); private OAuth2RequestFactory requestFactory = new DefaultOAuth2RequestFactory(clientDetailsService); private Map<String, String> parameters = new HashMap<String, String>(); public AuthorizationCodeTokenGranterTests() { providerTokenServices.setTokenStore(new InMemoryTokenStore()); } @Test public void testAuthorizationCodeGrant() { Authentication userAuthentication = new UsernamePasswordAuthenticationToken("marissa", "koala", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER")); parameters.clear(); parameters.put(OAuth2Utils.CLIENT_ID, "foo"); parameters.put(OAuth2Utils.SCOPE, "scope"); OAuth2Request storedOAuth2Request = RequestTokenFactory.createOAuth2Request(parameters, "foo", true, Collections.singleton("scope")); String code = authorizationCodeServices.createAuthorizationCode(new OAuth2Authentication( storedOAuth2Request, userAuthentication)); parameters.putAll(storedOAuth2Request.getRequestParameters()); parameters.put("code", code); TokenRequest tokenRequest = requestFactory.createTokenRequest(parameters, client); AuthorizationCodeTokenGranter granter = new AuthorizationCodeTokenGranter(providerTokenServices, authorizationCodeServices, clientDetailsService, requestFactory); OAuth2AccessToken token = granter.grant("authorization_code", tokenRequest); assertTrue(providerTokenServices.loadAuthentication(token.getValue()).isAuthenticated()); } @Test public void testAuthorizationParametersPreserved() { parameters.clear(); parameters.put("foo", "bar"); parameters.put(OAuth2Utils.CLIENT_ID, "foo"); parameters.put(OAuth2Utils.SCOPE, "scope"); OAuth2Request storedOAuth2Request = RequestTokenFactory.createOAuth2Request(parameters, "foo", true, Collections.singleton("scope")); Authentication userAuthentication = new UsernamePasswordAuthenticationToken("marissa", "koala", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER")); String code = authorizationCodeServices.createAuthorizationCode(new OAuth2Authentication( storedOAuth2Request, userAuthentication)); parameters.put("code", code); TokenRequest tokenRequest = requestFactory.createTokenRequest(parameters, client); AuthorizationCodeTokenGranter granter = new AuthorizationCodeTokenGranter(providerTokenServices, authorizationCodeServices, clientDetailsService, requestFactory); OAuth2AccessToken token = granter.grant("authorization_code", tokenRequest); OAuth2Request finalRequest = providerTokenServices.loadAuthentication(token.getValue()) .getOAuth2Request(); assertEquals(code, finalRequest.getRequestParameters().get("code")); assertEquals("bar", finalRequest.getRequestParameters().get("foo")); } @Test public void testAuthorizationRequestPreserved() { parameters.clear(); parameters.put(OAuth2Utils.CLIENT_ID, "foo"); parameters.put(OAuth2Utils.SCOPE, "read"); OAuth2Request storedOAuth2Request = RequestTokenFactory.createOAuth2Request(parameters, "foo", null, true, Collections.singleton("read"), Collections.singleton("resource"), null, null, null); Authentication userAuthentication = new UsernamePasswordAuthenticationToken("marissa", "koala", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER")); String code = authorizationCodeServices.createAuthorizationCode(new OAuth2Authentication( storedOAuth2Request, userAuthentication)); parameters.put("code", code); // Ensure even if token request asks for more scope they are not granted parameters.put(OAuth2Utils.SCOPE, "read write"); TokenRequest tokenRequest = requestFactory.createTokenRequest(parameters, client); AuthorizationCodeTokenGranter granter = new AuthorizationCodeTokenGranter(providerTokenServices, authorizationCodeServices, clientDetailsService, requestFactory); OAuth2AccessToken token = granter.grant("authorization_code", tokenRequest); OAuth2Request finalRequest = providerTokenServices.loadAuthentication(token.getValue()) .getOAuth2Request(); assertEquals("[read]", finalRequest.getScope().toString()); assertEquals("[resource]", finalRequest.getResourceIds().toString()); assertTrue(finalRequest.isApproved()); } @Test public void testAuthorizationCodeGrantWithNoClientAuthorities() { parameters.clear(); parameters.put(OAuth2Utils.CLIENT_ID, "foo"); parameters.put(OAuth2Utils.SCOPE, "scope"); OAuth2Request storedOAuth2Request = RequestTokenFactory.createOAuth2Request(parameters, "foo", Collections.<GrantedAuthority> emptySet(), true, Collections.singleton("scope"), null, null, null, null); Authentication userAuthentication = new UsernamePasswordAuthenticationToken("marissa", "koala", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER")); String code = authorizationCodeServices.createAuthorizationCode(new OAuth2Authentication( storedOAuth2Request, userAuthentication)); parameters.put("code", code); TokenRequest tokenRequest = requestFactory.createTokenRequest(parameters, client); AuthorizationCodeTokenGranter granter = new AuthorizationCodeTokenGranter(providerTokenServices, authorizationCodeServices, clientDetailsService, requestFactory); OAuth2AccessToken token = granter.grant("authorization_code", tokenRequest); assertTrue(providerTokenServices.loadAuthentication(token.getValue()).isAuthenticated()); } @Test public void testAuthorizationRedirectMismatch() { Map<String, String> initialParameters = new HashMap<String, String>(); initialParameters.put(OAuth2Utils.REDIRECT_URI, "https://redirectMe"); //AuthorizationRequest initialRequest = createFromParameters(initialParameters); // we fake a valid resolvedRedirectUri because without the client would never come this far //initialRequest.setRedirectUri(initialParameters.get(REDIRECT_URI)); parameters.clear(); parameters.put(OAuth2Utils.REDIRECT_URI, "https://redirectMe"); parameters.put(OAuth2Utils.CLIENT_ID, "foo"); OAuth2Request storedOAuth2Request = RequestTokenFactory.createOAuth2Request(parameters, "foo", null, true, null, null, "https://redirectMe", null, null); Authentication userAuthentication = new UsernamePasswordAuthenticationToken("marissa", "koala", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER")); String code = authorizationCodeServices.createAuthorizationCode(new OAuth2Authentication(storedOAuth2Request, userAuthentication)); Map<String, String> authorizationParameters = new HashMap<String, String>(); authorizationParameters.put("code", code); //AuthorizationRequest oAuth2Request = createFromParameters(initialParameters); //oAuth2Request.setRequestParameters(authorizationParameters); TokenRequest tokenRequest = requestFactory.createTokenRequest(parameters, client); tokenRequest.setRequestParameters(authorizationParameters); AuthorizationCodeTokenGranter granter = new AuthorizationCodeTokenGranter(providerTokenServices, authorizationCodeServices, clientDetailsService, requestFactory); try { granter.getOAuth2Authentication(client, tokenRequest); fail("RedirectMismatchException because of null redirect_uri in authorizationRequest"); } catch (RedirectMismatchException e) { } } }