diff --git a/pom.xml b/pom.xml index 3d5e79f56..b05c742dc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ OAuth for Spring Security Parent Project for OAuth Support for Spring Security pom - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT http://static.springframework.org/spring-security/oauth diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index 4cc3debd2..d5985dc6d 100644 --- a/samples/oauth/sparklr/pom.xml +++ b/samples/oauth/sparklr/pom.xml @@ -5,7 +5,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index 570abf329..283337497 100644 --- a/samples/oauth/tonr/pom.xml +++ b/samples/oauth/tonr/pom.xml @@ -5,7 +5,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index fa285f8af..1f9013dd3 100644 --- a/samples/oauth2/sparklr/pom.xml +++ b/samples/oauth2/sparklr/pom.xml @@ -5,7 +5,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 1131e00b1..50334a463 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -6,7 +6,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index 2c56b940a..96c07851c 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index 7dd4a4c1d..587b63fac 100644 --- a/spring-security-oauth/pom.xml +++ b/spring-security-oauth/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 4949b5ba2..a850142f0 100644 --- a/spring-security-oauth2/pom.xml +++ b/spring-security-oauth2/pom.xml @@ -5,7 +5,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT spring-security-oauth2 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerEndpointsConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerEndpointsConfiguration.java index 2fc3e63c2..160f7eb07 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerEndpointsConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerEndpointsConfiguration.java @@ -20,8 +20,11 @@ import javax.annotation.PostConstruct; import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanFactoryUtils; +import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; @@ -131,8 +134,19 @@ public FrameworkEndpointHandlerMapping oauth2EndpointHandlerMapping() throws Exc } @Bean - public ConsumerTokenServices consumerTokenServices() throws Exception { - return getEndpointsConfigurer().getConsumerTokenServices(); + public FactoryBean consumerTokenServices() throws Exception { + return new AbstractFactoryBean() { + + @Override + public Class getObjectType() { + return ConsumerTokenServices.class; + } + + @Override + protected ConsumerTokenServices createInstance() throws Exception { + return getEndpointsConfigurer().getConsumerTokenServices(); + } + }; } /** @@ -146,13 +160,18 @@ public ConsumerTokenServices consumerTokenServices() throws Exception { * @return an AuthorizationServerTokenServices */ @Bean - public AuthorizationServerTokenServices defaultAuthorizationServerTokenServices() { - return endpoints.getDefaultAuthorizationServerTokenServices(); + public FactoryBean defaultAuthorizationServerTokenServices() { + return new AuthorizationServerTokenServicesFactoryBean(endpoints); } public AuthorizationServerEndpointsConfigurer getEndpointsConfigurer() { if (!endpoints.isTokenServicesOverride()) { - endpoints.tokenServices(defaultAuthorizationServerTokenServices()); + try { + endpoints.tokenServices(endpoints.getDefaultAuthorizationServerTokenServices()); + } + catch (Exception e) { + throw new BeanCreationException("Cannot create token services", e); + } } return endpoints; } @@ -193,6 +212,30 @@ private String extractPath(FrameworkEndpointHandlerMapping mapping, String page) return "forward:" + path; } + protected static class AuthorizationServerTokenServicesFactoryBean + extends AbstractFactoryBean { + + private AuthorizationServerEndpointsConfigurer endpoints; + + protected AuthorizationServerTokenServicesFactoryBean() { + } + + public AuthorizationServerTokenServicesFactoryBean( + AuthorizationServerEndpointsConfigurer endpoints) { + this.endpoints = endpoints; + } + + @Override + public Class getObjectType() { + return AuthorizationServerTokenServices.class; + } + + @Override + protected AuthorizationServerTokenServices createInstance() throws Exception { + return endpoints.getDefaultAuthorizationServerTokenServices(); + } + } + @Component protected static class TokenKeyEndpointRegistrar implements BeanDefinitionRegistryPostProcessor { diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerEndpointsConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerEndpointsConfigurer.java index dc780e878..0529e0849 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerEndpointsConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerEndpointsConfigurer.java @@ -15,15 +15,6 @@ */ package org.springframework.security.oauth2.config.annotation.web.configurers; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - import org.springframework.beans.BeansException; import org.springframework.beans.factory.ObjectFactory; import org.springframework.http.HttpMethod; @@ -36,17 +27,8 @@ import org.springframework.security.oauth2.common.util.ProxyCreator; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; -import org.springframework.security.oauth2.provider.ClientDetailsService; -import org.springframework.security.oauth2.provider.CompositeTokenGranter; -import org.springframework.security.oauth2.provider.OAuth2RequestFactory; -import org.springframework.security.oauth2.provider.OAuth2RequestValidator; -import org.springframework.security.oauth2.provider.TokenGranter; -import org.springframework.security.oauth2.provider.TokenRequest; -import org.springframework.security.oauth2.provider.approval.ApprovalStore; -import org.springframework.security.oauth2.provider.approval.ApprovalStoreUserApprovalHandler; -import org.springframework.security.oauth2.provider.approval.TokenApprovalStore; -import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler; -import org.springframework.security.oauth2.provider.approval.UserApprovalHandler; +import org.springframework.security.oauth2.provider.*; +import org.springframework.security.oauth2.provider.approval.*; import org.springframework.security.oauth2.provider.client.ClientCredentialsTokenGranter; import org.springframework.security.oauth2.provider.client.InMemoryClientDetailsService; import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices; @@ -55,19 +37,13 @@ import org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping; import org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator; import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator; +import org.springframework.security.oauth2.provider.exchange.TokenExchangeTokenGranter; import org.springframework.security.oauth2.provider.implicit.ImplicitTokenGranter; import org.springframework.security.oauth2.provider.password.ResourceOwnerPasswordTokenGranter; import org.springframework.security.oauth2.provider.refresh.RefreshTokenGranter; import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory; import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestValidator; -import org.springframework.security.oauth2.provider.token.AccessTokenConverter; -import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; -import org.springframework.security.oauth2.provider.token.ConsumerTokenServices; -import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter; -import org.springframework.security.oauth2.provider.token.DefaultTokenServices; -import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; -import org.springframework.security.oauth2.provider.token.TokenEnhancer; -import org.springframework.security.oauth2.provider.token.TokenStore; +import org.springframework.security.oauth2.provider.token.*; import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; @@ -76,9 +52,11 @@ import org.springframework.web.context.request.WebRequestInterceptor; import org.springframework.web.servlet.HandlerInterceptor; +import java.util.*; + /** * Configure the properties and enhanced functionality of the Authorization Server endpoints. - * + * * @author Rob Winch * @author Dave Syer * @since 2.0 @@ -242,7 +220,7 @@ public AuthorizationServerEndpointsConfigurer approvalStore(ApprovalStore approv * Explicitly disable the approval store, even if one would normally be added automatically (usually when JWT is not * used). Without an approval store the user can only be asked to approve or deny a grant without any more granular * decisions. - * + * * @return this for fluent builder */ public AuthorizationServerEndpointsConfigurer approvalStoreDisabled() { @@ -277,7 +255,7 @@ public AuthorizationServerEndpointsConfigurer exceptionTranslator(WebResponseExc /** * The AuthenticationManager for the password grant. - * + * * @param authenticationManager an AuthenticationManager, fully initialized * @return this for a fluent style */ @@ -544,8 +522,9 @@ private List getDefaultTokenGranters() { if (authenticationManager != null) { tokenGranters.add(new ResourceOwnerPasswordTokenGranter(authenticationManager, tokenServices, clientDetails, requestFactory)); + tokenGranters.add(new TokenExchangeTokenGranter(authenticationManager, tokenServices, clientDetails, requestFactory)); } - return tokenGranters; + return tokenGranters; } private TokenGranter tokenGranter() { diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/AuthorizationServerBeanDefinitionParser.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/AuthorizationServerBeanDefinitionParser.java index 391d74a8c..b0f6216aa 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/AuthorizationServerBeanDefinitionParser.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/AuthorizationServerBeanDefinitionParser.java @@ -28,6 +28,7 @@ import org.springframework.security.oauth2.provider.code.AuthorizationCodeTokenGranter; import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices; import org.springframework.security.oauth2.provider.endpoint.*; +import org.springframework.security.oauth2.provider.exchange.TokenExchangeTokenGranter; import org.springframework.security.oauth2.provider.implicit.ImplicitTokenGranter; import org.springframework.security.oauth2.provider.password.ResourceOwnerPasswordTokenGranter; import org.springframework.security.oauth2.provider.refresh.RefreshTokenGranter; @@ -209,13 +210,13 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, "password"); if (clientPasswordElement != null && !"true" .equalsIgnoreCase(clientPasswordElement.getAttribute("disabled"))) { - BeanDefinitionBuilder clientPasswordTokenGranter = BeanDefinitionBuilder - .rootBeanDefinition(ResourceOwnerPasswordTokenGranter.class); String authenticationManagerRef = clientPasswordElement .getAttribute("authentication-manager-ref"); if (!StringUtils.hasText(authenticationManagerRef)) { authenticationManagerRef = BeanIds.AUTHENTICATION_MANAGER; } + BeanDefinitionBuilder clientPasswordTokenGranter = BeanDefinitionBuilder + .rootBeanDefinition(ResourceOwnerPasswordTokenGranter.class); clientPasswordTokenGranter .addConstructorArgReference(authenticationManagerRef); clientPasswordTokenGranter.addConstructorArgReference(tokenServicesRef); @@ -223,6 +224,15 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, clientPasswordTokenGranter .addConstructorArgReference(oAuth2RequestFactoryRef); tokenGranters.add(clientPasswordTokenGranter.getBeanDefinition()); + BeanDefinitionBuilder tokenExchangeTokenGranter = BeanDefinitionBuilder + .rootBeanDefinition(TokenExchangeTokenGranter.class); + tokenExchangeTokenGranter + .addConstructorArgReference(authenticationManagerRef); + tokenExchangeTokenGranter.addConstructorArgReference(tokenServicesRef); + tokenExchangeTokenGranter.addConstructorArgReference(clientDetailsRef); + tokenExchangeTokenGranter + .addConstructorArgReference(oAuth2RequestFactoryRef); + tokenGranters.add(tokenExchangeTokenGranter.getBeanDefinition()); } List customGrantElements = DomUtils .getChildElementsByTagName(element, "custom-grant"); diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/exchange/DefaultTokenExchangeAuthenticationProvider.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/exchange/DefaultTokenExchangeAuthenticationProvider.java new file mode 100644 index 000000000..37ba8cfd1 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/exchange/DefaultTokenExchangeAuthenticationProvider.java @@ -0,0 +1,46 @@ +package org.springframework.security.oauth2.provider.exchange; + +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; +import org.springframework.security.core.authority.mapping.NullAuthoritiesMapper; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.util.Assert; + +/** + * {@link AuthenticationProvider} that supports {@link TokenExchangeAuthenticationToken}. + * + * @author Ryan Murfitt + */ +public class DefaultTokenExchangeAuthenticationProvider implements AuthenticationProvider { + + private TokenExchangeService tokenExchangeService; + private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper(); + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + Assert.isInstanceOf(TokenExchangeAuthenticationToken.class, authentication, "Only TokenExchangeAuthenticationToken is supported"); + UserDetails user = this.tokenExchangeService.loadUserDetailsFromToken((TokenExchangeAuthenticationToken) authentication); + return createSuccessAuthentication(user, (TokenExchangeAuthenticationToken) authentication); + } + + private Authentication createSuccessAuthentication(UserDetails user, TokenExchangeAuthenticationToken token) { + TokenExchangeAuthenticationToken result = new TokenExchangeAuthenticationToken(user, token.getPrincipal(), token.getClientDetails(), this.authoritiesMapper.mapAuthorities(user.getAuthorities())); + result.setDetails(token.getDetails()); + return result; + } + + @Override + public boolean supports(Class authentication) { + return TokenExchangeAuthenticationToken.class.isAssignableFrom(authentication); + } + + public void setTokenExchangeService(TokenExchangeService tokenExchangeService) { + this.tokenExchangeService = tokenExchangeService; + } + + public void setAuthoritiesMapper(GrantedAuthoritiesMapper authoritiesMapper) { + this.authoritiesMapper = authoritiesMapper; + } +} diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/exchange/TokenExchangeAuthenticationToken.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/exchange/TokenExchangeAuthenticationToken.java new file mode 100644 index 000000000..300fe0631 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/exchange/TokenExchangeAuthenticationToken.java @@ -0,0 +1,53 @@ +package org.springframework.security.oauth2.provider.exchange; + +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.oauth2.provider.ClientDetails; + +import java.util.Collection; + +/** + * Token that represents a token-exchange authentication request. + * + * Similar to {@link org.springframework.security.authentication.UsernamePasswordAuthenticationToken} where the principal + * represents the 'subject_token', but once authenticated, the principal represents the user, and the credentials represents + * the 'subject_token'. + * + * @author Ryan Murfitt + */ +public class TokenExchangeAuthenticationToken extends AbstractAuthenticationToken { + + private final Object principal; + private final ClientDetails clientDetails; + private final Object credentials; + + TokenExchangeAuthenticationToken(Object principal, ClientDetails clientDetails) { + super(null); + this.principal = principal; + this.credentials = null; + this.clientDetails = clientDetails; + this.setAuthenticated(false); + } + + TokenExchangeAuthenticationToken(Object principal, Object credentials, ClientDetails clientDetails, Collection authorities) { + super(authorities); + this.principal = principal; + this.credentials = credentials; + this.clientDetails = clientDetails; + this.setAuthenticated(true); + } + + @Override + public Object getCredentials() { + return credentials; + } + + @Override + public Object getPrincipal() { + return principal; + } + + public ClientDetails getClientDetails() { + return clientDetails; + } +} diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/exchange/TokenExchangeService.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/exchange/TokenExchangeService.java new file mode 100644 index 000000000..16dda8707 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/exchange/TokenExchangeService.java @@ -0,0 +1,16 @@ +package org.springframework.security.oauth2.provider.exchange; + +import org.springframework.security.authentication.AccountStatusException; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; + +/** + * {@link TokenExchangeService} deals with validating the supplied {@link TokenExchangeAuthenticationToken} which details the + * token-exchange request, and returning the user associated with it. + * + * @author Ryan Murfitt + */ +public interface TokenExchangeService { + + UserDetails loadUserDetailsFromToken(TokenExchangeAuthenticationToken tokenAuth) throws AccountStatusException, InvalidTokenException; +} diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/exchange/TokenExchangeTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/exchange/TokenExchangeTokenGranter.java new file mode 100644 index 000000000..66e951391 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/exchange/TokenExchangeTokenGranter.java @@ -0,0 +1,79 @@ +/* + * Copyright 2002-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.exchange; + +import org.springframework.security.authentication.AccountStatusException; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.common.exceptions.InvalidGrantException; +import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; +import org.springframework.security.oauth2.provider.*; +import org.springframework.security.oauth2.provider.token.AbstractTokenGranter; +import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Supports the proposed token-exchange grant flow from draft-ietf-oauth-token-exchange + * + * @author Ryan Murfitt + */ +public class TokenExchangeTokenGranter extends AbstractTokenGranter { + + private static final String GRANT_TYPE = "token-exchange"; + private static final String SUBJECT_TOKEN_CLAIM = "subject_token"; + + private final AuthenticationManager authenticationManager; + + public TokenExchangeTokenGranter(AuthenticationManager authenticationManager, + AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) { + this(authenticationManager, tokenServices, clientDetailsService, requestFactory, GRANT_TYPE); + } + + protected TokenExchangeTokenGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices, + ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) { + super(tokenServices, clientDetailsService, requestFactory, grantType); + this.authenticationManager = authenticationManager; + } + + @Override + protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) { + + Map parameters = new LinkedHashMap(tokenRequest.getRequestParameters()); + String subjectToken = parameters.get(SUBJECT_TOKEN_CLAIM); + + TokenExchangeAuthenticationToken tokenAuth = new TokenExchangeAuthenticationToken(subjectToken, client); + tokenAuth.setDetails(parameters); + Authentication userAuth; + try { + userAuth = authenticationManager.authenticate(tokenAuth); + } catch (AccountStatusException ase) { + //covers expired, locked, disabled cases (mentioned in section 5.2, draft 31) + throw new InvalidGrantException(ase.getMessage()); + } catch (InvalidTokenException e) { + // If the supplied subject token is invalid + throw new InvalidGrantException(e.getMessage()); + } + if (userAuth == null || !userAuth.isAuthenticated()) { + throw new InvalidGrantException("Could not authenticate user"); + } + + OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest); + return new OAuth2Authentication(storedOAuth2Request, userAuth); + } +} diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkAttributes.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkAttributes.java new file mode 100644 index 000000000..642dcc430 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkAttributes.java @@ -0,0 +1,62 @@ +/* + * Copyright 2012-2017 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.token.store.jwk; + +/** + * Shared attribute values used by {@link JwkTokenStore} and associated collaborators. + * + * @author Joe Grandja + */ +final class JwkAttributes { + + /** + * The "kid" (key ID) parameter used in a JWT header and in a JWK. + */ + static final String KEY_ID = "kid"; + + /** + * The "kty" (key type) parameter identifies the cryptographic algorithm family + * used by a JWK, for example, "RSA" or "EC". + */ + static final String KEY_TYPE = "kty"; + + /** + * The "alg" (algorithm) parameter used in a JWT header and in a JWK. + */ + static final String ALGORITHM = "alg"; + + /** + * The "use" (public key use) parameter identifies the intended use of the public key. + * For example, whether a public key is used for encrypting data or verifying the signature on data. + */ + static final String PUBLIC_KEY_USE = "use"; + + /** + * The "n" (modulus) parameter contains the modulus value for a RSA public key. + */ + static final String RSA_PUBLIC_KEY_MODULUS = "n"; + + /** + * The "e" (exponent) parameter contains the exponent value for a RSA public key. + */ + static final String RSA_PUBLIC_KEY_EXPONENT = "e"; + + /** + * A JWK Set is a JSON object that has a "keys" member + * and its value is an array (set) of JWKs. + */ + static final String KEYS = "keys"; +} \ No newline at end of file diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinition.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinition.java new file mode 100644 index 000000000..2768ca3f1 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinition.java @@ -0,0 +1,196 @@ +/* + * Copyright 2012-2017 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.token.store.jwk; + +/** + * The base representation of a JSON Web Key (JWK). + * + * @see JSON Web Key (JWK) + * + * @author Joe Grandja + */ +abstract class JwkDefinition { + private final String keyId; + private final KeyType keyType; + private final PublicKeyUse publicKeyUse; + private final CryptoAlgorithm algorithm; + + /** + * Creates an instance with the common attributes of a JWK. + * + * @param keyId the Key ID + * @param keyType the Key Type + * @param publicKeyUse the intended use of the Public Key + * @param algorithm the algorithm intended to be used + */ + protected JwkDefinition(String keyId, + KeyType keyType, + PublicKeyUse publicKeyUse, + CryptoAlgorithm algorithm) { + this.keyId = keyId; + this.keyType = keyType; + this.publicKeyUse = publicKeyUse; + this.algorithm = algorithm; + } + + /** + * @return the Key ID ("kid") + */ + String getKeyId() { + return this.keyId; + } + + /** + * @return the Key Type ("kty") + */ + KeyType getKeyType() { + return this.keyType; + } + + /** + * @return the intended use of the Public Key ("use") + */ + PublicKeyUse getPublicKeyUse() { + return this.publicKeyUse; + } + + /** + * + * @return the algorithm intended to be used ("alg") + */ + CryptoAlgorithm getAlgorithm() { + return this.algorithm; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || this.getClass() != obj.getClass()) { + return false; + } + + JwkDefinition that = (JwkDefinition) obj; + if (!this.getKeyId().equals(that.getKeyId())) { + return false; + } + + return this.getKeyType().equals(that.getKeyType()); + } + + @Override + public int hashCode() { + int result = this.getKeyId().hashCode(); + result = 31 * result + this.getKeyType().hashCode(); + return result; + } + + /** + * The defined Key Type ("kty") values. + */ + enum KeyType { + RSA("RSA"), + EC("EC"), + OCT("oct"); + + private final String value; + + KeyType(String value) { + this.value = value; + } + + String value() { + return this.value; + } + + static KeyType fromValue(String value) { + KeyType result = null; + for (KeyType keyType : values()) { + if (keyType.value().equals(value)) { + result = keyType; + break; + } + } + return result; + } + } + + /** + * The defined Public Key Use ("use") values. + */ + enum PublicKeyUse { + SIG("sig"), + ENC("enc"); + + private final String value; + + PublicKeyUse(String value) { + this.value = value; + } + + String value() { + return this.value; + } + + static PublicKeyUse fromValue(String value) { + PublicKeyUse result = null; + for (PublicKeyUse publicKeyUse : values()) { + if (publicKeyUse.value().equals(value)) { + result = publicKeyUse; + break; + } + } + return result; + } + } + + /** + * The defined Algorithm ("alg") values. + */ + enum CryptoAlgorithm { + RS256("SHA256withRSA", "RS256"), + RS384("SHA384withRSA", "RS384"), + RS512("SHA512withRSA", "RS512"); + + private final String standardName; // JCA Standard Name + private final String headerParamValue; + + CryptoAlgorithm(String standardName, String headerParamValue) { + this.standardName = standardName; + this.headerParamValue = headerParamValue; + } + + String standardName() { + return this.standardName; + } + + String headerParamValue() { + return this.headerParamValue; + } + + static CryptoAlgorithm fromHeaderParamValue(String headerParamValue) { + CryptoAlgorithm result = null; + for (CryptoAlgorithm algorithm : values()) { + if (algorithm.headerParamValue().equals(headerParamValue)) { + result = algorithm; + break; + } + } + return result; + } + } +} \ No newline at end of file diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionSource.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionSource.java new file mode 100644 index 000000000..de643ff03 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionSource.java @@ -0,0 +1,180 @@ +/* + * Copyright 2012-2017 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.token.store.jwk; + +import org.springframework.security.jwt.codec.Codecs; +import org.springframework.security.jwt.crypto.sign.RsaVerifier; +import org.springframework.security.jwt.crypto.sign.SignatureVerifier; + +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.KeyFactory; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.RSAPublicKeySpec; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * A source for JSON Web Key(s) (JWK) that is solely responsible for fetching (and caching) + * the JWK Set (a set of JWKs) from the URL supplied to the constructor. + * + * @see JwkSetConverter + * @see JwkDefinition + * @see SignatureVerifier + * @see JWK Set Format + * + * @author Joe Grandja + */ +class JwkDefinitionSource { + private final URL jwkSetUrl; + private final Map jwkDefinitions = new ConcurrentHashMap(); + private static final JwkSetConverter jwkSetConverter = new JwkSetConverter(); + + /** + * Creates a new instance using the provided URL as the location for the JWK Set. + * + * @param jwkSetUrl the JWK Set URL + */ + JwkDefinitionSource(String jwkSetUrl) { + try { + this.jwkSetUrl = new URL(jwkSetUrl); + } catch (MalformedURLException ex) { + throw new IllegalArgumentException("Invalid JWK Set URL: " + ex.getMessage(), ex); + } + } + + /** + * Returns the JWK definition matching the provided keyId ("kid"). + * + * @param keyId the Key ID ("kid") + * @return the matching {@link JwkDefinition} or null if not found + */ + JwkDefinition getDefinition(String keyId) { + JwkDefinition result = null; + JwkDefinitionHolder jwkDefinitionHolder = this.jwkDefinitions.get(keyId); + if (jwkDefinitionHolder != null) { + result = jwkDefinitionHolder.getJwkDefinition(); + } + return result; + } + + /** + * Returns the JWK definition matching the provided keyId ("kid"). + * If the JWK definition is not available in the internal cache then {@link #loadJwkDefinitions(URL)} + * will be called (to re-load the cache) and then followed-up with a second attempt to locate the JWK definition. + * + * @param keyId the Key ID ("kid") + * @return the matching {@link JwkDefinition} or null if not found + */ + JwkDefinition getDefinitionLoadIfNecessary(String keyId) { + JwkDefinition result = this.getDefinition(keyId); + if (result != null) { + return result; + } + this.jwkDefinitions.clear(); + this.jwkDefinitions.putAll(loadJwkDefinitions(this.jwkSetUrl)); + return this.getDefinition(keyId); + } + + /** + * Returns the {@link SignatureVerifier} matching the provided keyId ("kid"). + * + * @param keyId the Key ID ("kid") + * @return the matching {@link SignatureVerifier} or null if not found + */ + SignatureVerifier getVerifier(String keyId) { + SignatureVerifier result = null; + JwkDefinition jwkDefinition = this.getDefinitionLoadIfNecessary(keyId); + if (jwkDefinition != null) { + result = this.jwkDefinitions.get(keyId).getSignatureVerifier(); + } + return result; + } + + /** + * Fetches the JWK Set from the provided URL and + * returns a Map keyed by the JWK keyId ("kid") + * and mapped to an association of the {@link JwkDefinition} and {@link SignatureVerifier}. + * Uses a {@link JwkSetConverter} to convert the JWK Set URL source to a set of {@link JwkDefinition}(s) + * followed by the instantiation of a {@link SignatureVerifier} which is associated to it's {@link JwkDefinition}. + * + * @param jwkSetUrl the JWK Set URL + * @return a Map keyed by the JWK keyId and mapped to an association of {@link JwkDefinition} and {@link SignatureVerifier} + * @see JwkSetConverter + */ + static Map loadJwkDefinitions(URL jwkSetUrl) { + InputStream jwkSetSource; + try { + jwkSetSource = jwkSetUrl.openStream(); + } catch (IOException ex) { + throw new JwkException("An I/O error occurred while reading from the JWK Set source: " + ex.getMessage(), ex); + } + + Set jwkDefinitionSet = jwkSetConverter.convert(jwkSetSource); + + Map jwkDefinitions = new LinkedHashMap(); + + for (JwkDefinition jwkDefinition : jwkDefinitionSet) { + if (JwkDefinition.KeyType.RSA.equals(jwkDefinition.getKeyType())) { + jwkDefinitions.put(jwkDefinition.getKeyId(), + new JwkDefinitionHolder(jwkDefinition, createRsaVerifier((RsaJwkDefinition) jwkDefinition))); + } + } + + return jwkDefinitions; + } + + private static RsaVerifier createRsaVerifier(RsaJwkDefinition rsaDefinition) { + RsaVerifier result; + try { + BigInteger modulus = new BigInteger(Codecs.b64UrlDecode(rsaDefinition.getModulus())); + BigInteger exponent = new BigInteger(Codecs.b64UrlDecode(rsaDefinition.getExponent())); + + RSAPublicKey rsaPublicKey = (RSAPublicKey) KeyFactory.getInstance("RSA") + .generatePublic(new RSAPublicKeySpec(modulus, exponent)); + + result = new RsaVerifier(rsaPublicKey, rsaDefinition.getAlgorithm().standardName()); + + } catch (Exception ex) { + throw new JwkException("An error occurred while creating a RSA Public Key Verifier for " + + rsaDefinition.getKeyId() + " : " + ex.getMessage(), ex); + } + return result; + } + + static class JwkDefinitionHolder { + private final JwkDefinition jwkDefinition; + private final SignatureVerifier signatureVerifier; + + private JwkDefinitionHolder(JwkDefinition jwkDefinition, SignatureVerifier signatureVerifier) { + this.jwkDefinition = jwkDefinition; + this.signatureVerifier = signatureVerifier; + } + + private JwkDefinition getJwkDefinition() { + return jwkDefinition; + } + + private SignatureVerifier getSignatureVerifier() { + return signatureVerifier; + } + } +} \ No newline at end of file diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkException.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkException.java new file mode 100644 index 000000000..1d3211dfb --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkException.java @@ -0,0 +1,59 @@ +/* + * Copyright 2012-2017 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.token.store.jwk; + +import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; + +/** + * General exception for JSON Web Key (JWK) related errors. + * + * @author Joe Grandja + */ +public class JwkException extends OAuth2Exception { + private static final String SERVER_ERROR_ERROR_CODE = "server_error"; + private String errorCode = SERVER_ERROR_ERROR_CODE; + private int httpStatus = 500; + + public JwkException(String message) { + super(message); + } + + public JwkException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Returns the error used in the OAuth2 Error Response + * sent back to the caller. The default is "server_error". + * + * @return the error used in the OAuth2 Error Response + */ + @Override + public String getOAuth2ErrorCode() { + return this.errorCode; + } + + /** + * Returns the Http Status used in the OAuth2 Error Response + * sent back to the caller. The default is 500. + * + * @return the Http Status set on the OAuth2 Error Response + */ + @Override + public int getHttpErrorCode() { + return this.httpStatus; + } +} \ No newline at end of file diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkSetConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkSetConverter.java new file mode 100644 index 000000000..e0284261c --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkSetConverter.java @@ -0,0 +1,178 @@ +/* + * Copyright 2012-2017 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.token.store.jwk; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import org.springframework.core.convert.converter.Converter; +import org.springframework.util.StringUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import static org.springframework.security.oauth2.provider.token.store.jwk.JwkAttributes.*; + +/** + * A {@link Converter} that converts the supplied InputStream to a Set of {@link JwkDefinition}(s). + * The source of the InputStream must be a JWK Set representation which is a JSON object + * that has a "keys" member and its value is an array of JWKs. + *
+ *
+ * + * NOTE: The Key Type ("kty") currently supported by this {@link Converter} is {@link JwkDefinition.KeyType#RSA}. + *
+ *
+ * + * @see JwkDefinition + * @see JWK Set Format + * + * @author Joe Grandja + */ +class JwkSetConverter implements Converter> { + private final JsonFactory factory = new JsonFactory(); + + /** + * Converts the supplied InputStream to a Set of {@link JwkDefinition}(s). + * + * @param jwkSetSource the source for the JWK Set + * @return a Set of {@link JwkDefinition}(s) + * @throws JwkException if the JWK Set JSON object is invalid + */ + @Override + public Set convert(InputStream jwkSetSource) { + Set jwkDefinitions; + JsonParser parser = null; + + try { + parser = this.factory.createParser(jwkSetSource); + + if (parser.nextToken() != JsonToken.START_OBJECT) { + throw new JwkException("Invalid JWK Set Object."); + } + if (parser.nextToken() != JsonToken.FIELD_NAME) { + throw new JwkException("Invalid JWK Set Object."); + } + if (!parser.getCurrentName().equals(KEYS)) { + throw new JwkException("Invalid JWK Set Object. The JWK Set MUST have a " + KEYS + " attribute."); + } + if (parser.nextToken() != JsonToken.START_ARRAY) { + throw new JwkException("Invalid JWK Set Object. The JWK Set MUST have an array of JWK(s)."); + } + + jwkDefinitions = new LinkedHashSet(); + Map attributes = new HashMap(); + + while (parser.nextToken() == JsonToken.START_OBJECT) { + while (parser.nextToken() == JsonToken.FIELD_NAME) { + String attributeName = parser.getCurrentName(); + parser.nextToken(); + String attributeValue = parser.getValueAsString(); + attributes.put(attributeName, attributeValue); + } + JwkDefinition jwkDefinition = this.createJwkDefinition(attributes); + if (!jwkDefinitions.add(jwkDefinition)) { + throw new JwkException("Duplicate JWK found in Set: " + + jwkDefinition.getKeyId() + " (" + KEY_ID + ")"); + } + attributes.clear(); + } + + } catch (IOException ex) { + throw new JwkException("An I/O error occurred while reading the JWK Set: " + ex.getMessage(), ex); + } finally { + try { + if (parser != null) parser.close(); + } catch (IOException ex) { } + } + + return jwkDefinitions; + } + + /** + * Creates a {@link JwkDefinition} based on the supplied attributes. + * + * @param attributes the attributes used to create the {@link JwkDefinition} + * @return a {@link JwkDefinition} + * @throws JwkException if the Key Type ("kty") attribute value is not {@link JwkDefinition.KeyType#RSA} + */ + private JwkDefinition createJwkDefinition(Map attributes) { + JwkDefinition.KeyType keyType = + JwkDefinition.KeyType.fromValue(attributes.get(KEY_TYPE)); + + if (!JwkDefinition.KeyType.RSA.equals(keyType)) { + throw new JwkException((keyType != null ? keyType.value() : "unknown") + + " (" + KEY_TYPE + ") is currently not supported." + + " Valid values for '" + KEY_TYPE + "' are: " + JwkDefinition.KeyType.RSA.value()); + } + + return this.createRsaJwkDefinition(attributes); + } + + /** + * Creates a {@link RsaJwkDefinition} based on the supplied attributes. + * + * @param attributes the attributes used to create the {@link RsaJwkDefinition} + * @return a {@link JwkDefinition} representation of a RSA Key + * @throws JwkException if at least one attribute value is missing or invalid for a RSA Key + */ + private JwkDefinition createRsaJwkDefinition(Map attributes) { + // kid + String keyId = attributes.get(KEY_ID); + if (!StringUtils.hasText(keyId)) { + throw new JwkException(KEY_ID + " is a required attribute for a JWK."); + } + + // use + JwkDefinition.PublicKeyUse publicKeyUse = + JwkDefinition.PublicKeyUse.fromValue(attributes.get(PUBLIC_KEY_USE)); + if (!JwkDefinition.PublicKeyUse.SIG.equals(publicKeyUse)) { + throw new JwkException((publicKeyUse != null ? publicKeyUse.value() : "unknown") + + " (" + PUBLIC_KEY_USE + ") is currently not supported."); + } + + // alg + JwkDefinition.CryptoAlgorithm algorithm = + JwkDefinition.CryptoAlgorithm.fromHeaderParamValue(attributes.get(ALGORITHM)); + if (!JwkDefinition.CryptoAlgorithm.RS256.equals(algorithm) && + !JwkDefinition.CryptoAlgorithm.RS384.equals(algorithm) && + !JwkDefinition.CryptoAlgorithm.RS512.equals(algorithm)) { + throw new JwkException((algorithm != null ? algorithm.standardName() : "unknown") + + " (" + ALGORITHM + ") is currently not supported."); + } + + // n + String modulus = attributes.get(RSA_PUBLIC_KEY_MODULUS); + if (!StringUtils.hasText(modulus)) { + throw new JwkException(RSA_PUBLIC_KEY_MODULUS + " is a required attribute for a RSA JWK."); + } + + // e + String exponent = attributes.get(RSA_PUBLIC_KEY_EXPONENT); + if (!StringUtils.hasText(exponent)) { + throw new JwkException(RSA_PUBLIC_KEY_EXPONENT + " is a required attribute for a RSA JWK."); + } + + RsaJwkDefinition jwkDefinition = new RsaJwkDefinition( + keyId, publicKeyUse, algorithm, modulus, exponent); + + return jwkDefinition; + } +} \ No newline at end of file diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkTokenStore.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkTokenStore.java new file mode 100644 index 000000000..85706ba4a --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkTokenStore.java @@ -0,0 +1,250 @@ +/* + * Copyright 2012-2017 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.token.store.jwk; + +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.OAuth2RefreshToken; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.security.oauth2.provider.token.TokenStore; +import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; +import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; +import org.springframework.util.Assert; + +import java.util.Collection; + +/** + * A {@link TokenStore} implementation that provides support for verifying the + * JSON Web Signature (JWS) for a JSON Web Token (JWT) using a JSON Web Key (JWK). + *
+ *
+ * + * This {@link TokenStore} implementation is exclusively meant to be used by a Resource Server as + * it's sole responsibility is to decode a JWT and verify it's signature (JWS) using the corresponding JWK. + *
+ *
+ * + * NOTE: + * There are a few operations defined by {@link TokenStore} that are not applicable for a Resource Server. + * In these cases, the method implementation will explicitly throw a + * {@link JwkException} reporting "This operation is not supported". + *
+ *
+ * + * The unsupported operations are as follows: + *
    + *
  • {@link #storeAccessToken(OAuth2AccessToken, OAuth2Authentication)}
  • + *
  • {@link #removeAccessToken(OAuth2AccessToken)}
  • + *
  • {@link #storeRefreshToken(OAuth2RefreshToken, OAuth2Authentication)}
  • + *
  • {@link #readRefreshToken(String)}
  • + *
  • {@link #readAuthenticationForRefreshToken(OAuth2RefreshToken)}
  • + *
  • {@link #removeRefreshToken(OAuth2RefreshToken)}
  • + *
  • {@link #removeAccessTokenUsingRefreshToken(OAuth2RefreshToken)}
  • + *
  • {@link #getAccessToken(OAuth2Authentication)}
  • + *
  • {@link #findTokensByClientIdAndUserName(String, String)}
  • + *
  • {@link #findTokensByClientId(String)}
  • + *
+ *
+ * + * This implementation delegates to an internal instance of a {@link JwtTokenStore} which uses a + * specialized extension of {@link JwtAccessTokenConverter}. + * This specialized {@link JwtAccessTokenConverter} is capable of fetching (and caching) + * the JWK Set (a set of JWKs) from the URL supplied to the constructor of this implementation. + *
+ *
+ * + * The {@link JwtAccessTokenConverter} will verify the JWS in the following step sequence: + *
+ *
+ *
    + *
  1. Extract the "kid" parameter from the JWT header.
  2. + *
  3. Find the matching JWK with the corresponding "kid" attribute.
  4. + *
  5. Obtain the SignatureVerifier associated with the JWK and verify the signature.
  6. + *
+ *
+ * NOTE: The algorithms currently supported by this implementation are: RS256, RS384 and RS512. + *
+ *
+ * + * @see JwtTokenStore + * @see JSON Web Key (JWK) + * @see JSON Web Token (JWT) + * @see JSON Web Signature (JWS) + * + * @author Joe Grandja + */ +public final class JwkTokenStore implements TokenStore { + private final JwtTokenStore delegate; + + /** + * Creates a new instance using the provided URL as the location for the JWK Set. + * + * @param jwkSetUrl the JWK Set URL + */ + public JwkTokenStore(String jwkSetUrl) { + Assert.hasText(jwkSetUrl, "jwkSetUrl cannot be empty"); + JwkDefinitionSource jwkDefinitionSource = new JwkDefinitionSource(jwkSetUrl); + JwkVerifyingJwtAccessTokenConverter accessTokenConverter = + new JwkVerifyingJwtAccessTokenConverter(jwkDefinitionSource); + this.delegate = new JwtTokenStore(accessTokenConverter); + } + + /** + * Delegates to the internal instance {@link JwtTokenStore#readAuthentication(OAuth2AccessToken)}. + * + * @param token the access token + * @return the {@link OAuth2Authentication} representation of the access token + */ + @Override + public OAuth2Authentication readAuthentication(OAuth2AccessToken token) { + return this.delegate.readAuthentication(token); + } + + /** + * Delegates to the internal instance {@link JwtTokenStore#readAuthentication(String)}. + * + * @param tokenValue the access token value + * @return the {@link OAuth2Authentication} representation of the access token + */ + @Override + public OAuth2Authentication readAuthentication(String tokenValue) { + return this.delegate.readAuthentication(tokenValue); + } + + /** + * This operation is not applicable for a Resource Server + * and if called, will throw a {@link JwkException}. + * + * @throws JwkException reporting this operation is not supported + */ + @Override + public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) { + throw this.operationNotSupported(); + } + + /** + * Delegates to the internal instance {@link JwtTokenStore#readAccessToken(String)}. + * + * @param tokenValue the access token value + * @return the {@link OAuth2AccessToken} representation of the access token value + */ + @Override + public OAuth2AccessToken readAccessToken(String tokenValue) { + return this.delegate.readAccessToken(tokenValue); + } + + /** + * This operation is not applicable for a Resource Server + * and if called, will throw a {@link JwkException}. + * + * @throws JwkException reporting this operation is not supported + */ + @Override + public void removeAccessToken(OAuth2AccessToken token) { + throw this.operationNotSupported(); + } + + /** + * This operation is not applicable for a Resource Server + * and if called, will throw a {@link JwkException}. + * + * @throws JwkException reporting this operation is not supported + */ + @Override + public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) { + throw this.operationNotSupported(); + } + + /** + * This operation is not applicable for a Resource Server + * and if called, will throw a {@link JwkException}. + * + * @throws JwkException reporting this operation is not supported + */ + @Override + public OAuth2RefreshToken readRefreshToken(String tokenValue) { + throw this.operationNotSupported(); + } + + /** + * This operation is not applicable for a Resource Server + * and if called, will throw a {@link JwkException}. + * + * @throws JwkException reporting this operation is not supported + */ + @Override + public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) { + throw this.operationNotSupported(); + } + + /** + * This operation is not applicable for a Resource Server + * and if called, will throw a {@link JwkException}. + * + * @throws JwkException reporting this operation is not supported + */ + @Override + public void removeRefreshToken(OAuth2RefreshToken token) { + throw this.operationNotSupported(); + } + + /** + * This operation is not applicable for a Resource Server + * and if called, will throw a {@link JwkException}. + * + * @throws JwkException reporting this operation is not supported + */ + @Override + public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) { + throw this.operationNotSupported(); + } + + /** + * This operation is not applicable for a Resource Server + * and if called, will throw a {@link JwkException}. + * + * @throws JwkException reporting this operation is not supported + */ + @Override + public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) { + throw this.operationNotSupported(); + } + + /** + * This operation is not applicable for a Resource Server + * and if called, will throw a {@link JwkException}. + * + * @throws JwkException reporting this operation is not supported + */ + @Override + public Collection findTokensByClientIdAndUserName(String clientId, String userName) { + throw this.operationNotSupported(); + } + + /** + * This operation is not applicable for a Resource Server + * and if called, will throw a {@link JwkException}. + * + * @throws JwkException reporting this operation is not supported + */ + @Override + public Collection findTokensByClientId(String clientId) { + throw this.operationNotSupported(); + } + + private JwkException operationNotSupported() { + return new JwkException("This operation is not supported."); + } +} \ No newline at end of file diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkVerifyingJwtAccessTokenConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkVerifyingJwtAccessTokenConverter.java new file mode 100644 index 000000000..431ade84a --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkVerifyingJwtAccessTokenConverter.java @@ -0,0 +1,142 @@ +/* + * Copyright 2012-2017 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.token.store.jwk; + +import org.springframework.security.jwt.Jwt; +import org.springframework.security.jwt.JwtHelper; +import org.springframework.security.jwt.crypto.sign.SignatureVerifier; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; +import org.springframework.security.oauth2.common.util.JsonParser; +import org.springframework.security.oauth2.common.util.JsonParserFactory; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; + +import java.util.Map; + +import static org.springframework.security.oauth2.provider.token.store.jwk.JwkAttributes.ALGORITHM; +import static org.springframework.security.oauth2.provider.token.store.jwk.JwkAttributes.KEY_ID; + +/** + * A specialized extension of {@link JwtAccessTokenConverter} that is responsible for verifying + * the JSON Web Signature (JWS) for a JSON Web Token (JWT) using the corresponding JSON Web Key (JWK). + * This implementation is associated with a {@link JwkDefinitionSource} for looking up + * the matching {@link JwkDefinition} using the value of the JWT header parameter "kid". + *
+ *
+ * + * The JWS is verified in the following step sequence: + *
+ *
+ *
    + *
  1. Extract the "kid" parameter from the JWT header.
  2. + *
  3. Find the matching {@link JwkDefinition} from the {@link JwkDefinitionSource} with the corresponding "kid" attribute.
  4. + *
  5. Obtain the {@link SignatureVerifier} associated with the {@link JwkDefinition} via the {@link JwkDefinitionSource} and verify the signature.
  6. + *
+ *
+ * NOTE: The algorithms currently supported by this implementation are: RS256, RS384 and RS512. + *
+ *
+ * + * NOTE: This {@link JwtAccessTokenConverter} does not support signing JWTs (JWS) and therefore + * the {@link #encode(OAuth2AccessToken, OAuth2Authentication)} method implementation, if called, + * will explicitly throw a {@link JwkException} reporting "JWT signing (JWS) is not supported.". + *
+ *
+ * + * @see JwtAccessTokenConverter + * @see JwtHeaderConverter + * @see JwkDefinitionSource + * @see JwkDefinition + * @see SignatureVerifier + * @see JSON Web Key (JWK) + * @see JSON Web Token (JWT) + * @see JSON Web Signature (JWS) + * + * @author Joe Grandja + */ +class JwkVerifyingJwtAccessTokenConverter extends JwtAccessTokenConverter { + private final JwkDefinitionSource jwkDefinitionSource; + private final JwtHeaderConverter jwtHeaderConverter = new JwtHeaderConverter(); + private final JsonParser jsonParser = JsonParserFactory.create(); + + /** + * Creates a new instance using the provided {@link JwkDefinitionSource} + * as the primary source for looking up {@link JwkDefinition}(s). + * + * @param jwkDefinitionSource the source for {@link JwkDefinition}(s) + */ + JwkVerifyingJwtAccessTokenConverter(JwkDefinitionSource jwkDefinitionSource) { + this.jwkDefinitionSource = jwkDefinitionSource; + } + + /** + * Decodes and validates the supplied JWT followed by signature verification + * before returning the Claims from the JWT Payload. + * + * @param token the JSON Web Token + * @return a Map of the JWT Claims + * @throws JwkException if the JWT is invalid or if the JWS could not be verified + */ + @Override + protected Map decode(String token) { + Map headers = this.jwtHeaderConverter.convert(token); + + // Validate "kid" header + String keyIdHeader = headers.get(KEY_ID); + if (keyIdHeader == null) { + throw new InvalidTokenException("Invalid JWT/JWS: " + KEY_ID + " is a required JOSE Header"); + } + JwkDefinition jwkDefinition = this.jwkDefinitionSource.getDefinitionLoadIfNecessary(keyIdHeader); + if (jwkDefinition == null) { + throw new InvalidTokenException("Invalid JOSE Header " + KEY_ID + " (" + keyIdHeader + ")"); + } + + // Validate "alg" header + String algorithmHeader = headers.get(ALGORITHM); + if (algorithmHeader == null) { + throw new InvalidTokenException("Invalid JWT/JWS: " + ALGORITHM + " is a required JOSE Header"); + } + if (!algorithmHeader.equals(jwkDefinition.getAlgorithm().headerParamValue())) { + throw new InvalidTokenException("Invalid JOSE Header " + ALGORITHM + " (" + algorithmHeader + ")" + + " does not match algorithm associated to JWK with " + KEY_ID + " (" + keyIdHeader + ")"); + } + + // Verify signature + SignatureVerifier verifier = this.jwkDefinitionSource.getVerifier(keyIdHeader); + Jwt jwt = JwtHelper.decode(token); + jwt.verifySignature(verifier); + + Map claims = this.jsonParser.parseMap(jwt.getClaims()); + if (claims.containsKey(EXP) && claims.get(EXP) instanceof Integer) { + Integer expiryInt = (Integer) claims.get(EXP); + claims.put(EXP, new Long(expiryInt)); + } + + return claims; + } + + /** + * This operation (JWT signing) is not supported and if called, + * will throw a {@link JwkException}. + * + * @throws JwkException + */ + @Override + protected String encode(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { + throw new JwkException("JWT signing (JWS) is not supported."); + } +} \ No newline at end of file diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwtHeaderConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwtHeaderConverter.java new file mode 100644 index 000000000..62981f33b --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwtHeaderConverter.java @@ -0,0 +1,81 @@ +/* + * Copyright 2012-2017 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.token.store.jwk; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import org.springframework.core.convert.converter.Converter; +import org.springframework.security.jwt.codec.Codecs; +import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * A {@link Converter} that converts the supplied String representation of a JWT + * to a Map of JWT Header Parameters. + * + * @see JSON Web Token (JWT) + * + * @author Joe Grandja + */ +class JwtHeaderConverter implements Converter> { + private final JsonFactory factory = new JsonFactory(); + + /** + * Converts the supplied JSON Web Token to a Map of JWT Header Parameters. + * + * @param token the JSON Web Token + * @return a Map of JWT Header Parameters + * @throws JwkException if the JWT is invalid + */ + @Override + public Map convert(String token) { + Map headers; + + int headerEndIndex = token.indexOf('.'); + if (headerEndIndex == -1) { + throw new InvalidTokenException("Invalid JWT. Missing JOSE Header."); + } + byte[] decodedHeader = Codecs.b64UrlDecode(token.substring(0, headerEndIndex)); + + JsonParser parser = null; + + try { + parser = this.factory.createParser(decodedHeader); + headers = new HashMap(); + if (parser.nextToken() == JsonToken.START_OBJECT) { + while (parser.nextToken() == JsonToken.FIELD_NAME) { + String headerName = parser.getCurrentName(); + parser.nextToken(); + String headerValue = parser.getValueAsString(); + headers.put(headerName, headerValue); + } + } + + } catch (IOException ex) { + throw new InvalidTokenException("An I/O error occurred while reading the JWT: " + ex.getMessage(), ex); + } finally { + try { + if (parser != null) parser.close(); + } catch (IOException ex) { } + } + + return headers; + } +} \ No newline at end of file diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/RsaJwkDefinition.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/RsaJwkDefinition.java new file mode 100644 index 000000000..41655c7af --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/RsaJwkDefinition.java @@ -0,0 +1,63 @@ +/* + * Copyright 2012-2017 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.token.store.jwk; + +/** + * A JSON Web Key (JWK) representation of a RSA key. + * + * @see JSON Web Key (JWK) + * @see JSON Web Algorithms (JWA) + * + * @author Joe Grandja + */ +final class RsaJwkDefinition extends JwkDefinition { + private final String modulus; + private final String exponent; + + /** + * Creates an instance of a RSA JSON Web Key (JWK). + * + * @param keyId the Key ID + * @param publicKeyUse the intended use of the Public Key + * @param algorithm the algorithm intended to be used + * @param modulus the modulus value for the Public Key + * @param exponent the exponent value for the Public Key + */ + RsaJwkDefinition(String keyId, + PublicKeyUse publicKeyUse, + CryptoAlgorithm algorithm, + String modulus, + String exponent) { + + super(keyId, KeyType.RSA, publicKeyUse, algorithm); + this.modulus = modulus; + this.exponent = exponent; + } + + /** + * @return the modulus value for the Public Key + */ + String getModulus() { + return this.modulus; + } + + /** + * @return the exponent value for the Public Key + */ + String getExponent() { + return this.exponent; + } +} \ No newline at end of file diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/TokenServicesMultipleBeansTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/TokenServicesMultipleBeansTests.java new file mode 100644 index 000000000..d38593d54 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/TokenServicesMultipleBeansTests.java @@ -0,0 +1,69 @@ +/* + * Copyright 2015-2016 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.config.annotation; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.oauth2.config.annotation.TokenServicesMultipleBeansTests.BrokenOAuthApplication; +import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; +import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; +import org.springframework.security.oauth2.provider.token.ConsumerTokenServices; +import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +/** + * @author Dave Syer + * + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes=BrokenOAuthApplication.class) +@WebAppConfiguration +public class TokenServicesMultipleBeansTests { + + @Autowired(required=false) + private ResourceServerTokenServices tokenServices; + + @Autowired + private AuthorizationServerTokenServices authServerTokenServices; + + @Autowired + private ConsumerTokenServices consumerTokenServices; + + @Test + public void test() { + assertNull(tokenServices); + assertNotNull(authServerTokenServices); + assertNotNull(consumerTokenServices); + } + + @Configuration + @EnableAuthorizationServer + @EnableResourceServer + @EnableWebSecurity + protected static class BrokenOAuthApplication extends AuthorizationServerConfigurerAdapter { + } +} diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/exchange/DefaultTokenExchangeAuthenticationProviderTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/exchange/DefaultTokenExchangeAuthenticationProviderTests.java new file mode 100644 index 000000000..26f572ead --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/exchange/DefaultTokenExchangeAuthenticationProviderTests.java @@ -0,0 +1,75 @@ +package org.springframework.security.oauth2.provider.exchange; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collections; + +import static org.mockito.Mockito.*; + +import static org.junit.Assert.*; + +/** + * @author Ryan Murfitt + */ +@RunWith(MockitoJUnitRunner.class) +public class DefaultTokenExchangeAuthenticationProviderTests { + + @Mock + private TokenExchangeService tokenExchangeService; + + @InjectMocks + private DefaultTokenExchangeAuthenticationProvider provider = new DefaultTokenExchangeAuthenticationProvider(); + + @Rule + public final ExpectedException exception = ExpectedException.none(); + + @Test + public void authenticateIncorrectTokenType() { + UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken( + "rod", "KOala"); + exception.expect(IllegalArgumentException.class); + exception.expectMessage("Only TokenExchangeAuthenticationToken is supported"); + + provider.authenticate(token); + + verifyZeroInteractions(this.tokenExchangeService); + } + + @Test + public void authenticateSuccess() { + TokenExchangeAuthenticationToken token = new TokenExchangeAuthenticationToken( + "token", null); + UserDetails user = new User("bob", "password", Collections.emptyList()); + + when(tokenExchangeService.loadUserDetailsFromToken(token)).thenReturn(user); + + Authentication result = provider.authenticate(token); + + assertTrue(result instanceof TokenExchangeAuthenticationToken); + assertTrue(result.isAuthenticated()); + assertSame(result.getPrincipal(), user); + assertSame(result.getCredentials(), token.getPrincipal()); + } + + @Test + public void supportsIncorrectTokenType() { + assertFalse(provider.supports(UsernamePasswordAuthenticationToken.class)); + } + + @Test + public void supportsSuccess() { + assertTrue(provider.supports(TokenExchangeAuthenticationToken.class)); + } + +} \ No newline at end of file diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/exchange/TokenExchangeTokenGranterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/exchange/TokenExchangeTokenGranterTests.java new file mode 100644 index 000000000..3ff11ad04 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/exchange/TokenExchangeTokenGranterTests.java @@ -0,0 +1,111 @@ +package org.springframework.security.oauth2.provider.exchange; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.LockedException; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.exceptions.InvalidClientException; +import org.springframework.security.oauth2.common.exceptions.InvalidGrantException; +import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; +import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; +import org.springframework.security.oauth2.provider.*; +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 java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; + +/** + * @author Ryan Murfitt + */ +@RunWith(MockitoJUnitRunner.class) +public class TokenExchangeTokenGranterTests { + + private Authentication validUser = new UsernamePasswordAuthenticationToken("foo", "bar", + Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"))); + + private BaseClientDetails client = new BaseClientDetails("foo", "resource", "scope", "token-exchange", "ROLE_USER"); + + @Mock + private AuthenticationManager authenticationManager; + + private DefaultTokenServices providerTokenServices = new DefaultTokenServices(); + + private ClientDetailsService clientDetailsService = new ClientDetailsService() { + public ClientDetails loadClientByClientId(String clientId) throws OAuth2Exception { + return client; + } + }; + + private OAuth2RequestFactory requestFactory = new DefaultOAuth2RequestFactory(clientDetailsService); + + private TokenExchangeTokenGranter granter; + + private TokenRequest tokenRequest; + + @Before + public void setup() { + when(this.authenticationManager.authenticate(any(TokenExchangeAuthenticationToken.class))).thenReturn(this.validUser); + + String clientId = "client"; + BaseClientDetails clientDetails = new BaseClientDetails(); + clientDetails.setClientId(clientId); + + providerTokenServices.setTokenStore(new InMemoryTokenStore()); + Map parameters = new HashMap(); + parameters.put("subject_token", "token123"); + parameters.put("subject_type", "bearer"); + + granter = new TokenExchangeTokenGranter(authenticationManager, + providerTokenServices, clientDetailsService, requestFactory); + + tokenRequest = requestFactory.createTokenRequest(parameters, clientDetails); + } + + @Test + public void testSuccessfulGrant() { + OAuth2AccessToken token = granter.grant("token-exchange", tokenRequest); + OAuth2Authentication authentication = providerTokenServices.loadAuthentication(token.getValue()); + assertTrue(authentication.isAuthenticated()); + } + + @Test(expected = InvalidClientException.class) + public void testGrantTypeNotSupported() { + client.setAuthorizedGrantTypes(Collections.singleton("client_credentials")); + granter.grant("token-exchange", tokenRequest); + } + + @Test(expected = InvalidGrantException.class) + public void testInvalidToken() { + when(this.authenticationManager.authenticate(any(TokenExchangeAuthenticationToken.class))).thenThrow(new InvalidTokenException("invalid token")); + granter.grant("token-exchange", tokenRequest); + } + + @Test(expected = InvalidGrantException.class) + public void testAccountLocked() { + when(this.authenticationManager.authenticate(any(TokenExchangeAuthenticationToken.class))).thenThrow(new LockedException("locked")); + granter.grant("token-exchange", tokenRequest); + } + + @Test(expected = InvalidGrantException.class) + public void testUnauthenticated() { + validUser = new UsernamePasswordAuthenticationToken("foo", "bar"); + when(this.authenticationManager.authenticate(any(TokenExchangeAuthenticationToken.class))).thenReturn(this.validUser); + granter.grant("token-exchange", tokenRequest); + } +} \ No newline at end of file diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionSourceTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionSourceTest.java new file mode 100644 index 000000000..75a545379 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionSourceTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 2012-2017 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.token.store.jwk; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.net.URL; +import java.util.Collections; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; +import static org.powermock.api.mockito.PowerMockito.*; + + +/** + * @author Joe Grandja + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest(JwkDefinitionSource.class) +public class JwkDefinitionSourceTest { + private static final String DEFAULT_JWK_SET_URL = "https://identity.server1.io/token_keys"; + + @Test(expected = IllegalArgumentException.class) + public void constructorWhenInvalidJwkSetUrlThenThrowIllegalArgumentException() throws Exception { + new JwkDefinitionSource(DEFAULT_JWK_SET_URL.substring(1)); + } + + @Test + public void getDefinitionLoadIfNecessaryWhenKeyIdNotFoundThenLoadJwkDefinitions() throws Exception { + JwkDefinitionSource jwkDefinitionSource = spy(new JwkDefinitionSource(DEFAULT_JWK_SET_URL)); + mockStatic(JwkDefinitionSource.class); + when(JwkDefinitionSource.loadJwkDefinitions(any(URL.class))).thenReturn(Collections.emptyMap()); + jwkDefinitionSource.getDefinitionLoadIfNecessary("invalid-key-id"); + verifyStatic(); + } +} \ No newline at end of file diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionTest.java new file mode 100644 index 000000000..a6ad3d2b2 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2012-2017 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.token.store.jwk; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Joe Grandja + */ +public class JwkDefinitionTest { + + @Test + public void constructorWhenArgumentsPassedThenAttributesAreCorrectlySet() throws Exception { + String keyId = "key-id-1"; + JwkDefinition.KeyType keyType = JwkDefinition.KeyType.RSA; + JwkDefinition.PublicKeyUse publicKeyUse = JwkDefinition.PublicKeyUse.SIG; + JwkDefinition.CryptoAlgorithm algorithm = JwkDefinition.CryptoAlgorithm.RS512; + + JwkDefinition jwkDefinition = new JwkDefinition(keyId, keyType, publicKeyUse, algorithm) { }; + + assertEquals(keyId, jwkDefinition.getKeyId()); + assertEquals(keyType, jwkDefinition.getKeyType()); + assertEquals(publicKeyUse, jwkDefinition.getPublicKeyUse()); + assertEquals(algorithm, jwkDefinition.getAlgorithm()); + } + + @Test + public void cryptoAlgorithmWhenAttributesAccessedThenCorrectValuesReturned() { + assertEquals("RS256", JwkDefinition.CryptoAlgorithm.RS256.headerParamValue()); + assertEquals("SHA256withRSA", JwkDefinition.CryptoAlgorithm.RS256.standardName()); + assertEquals("RS384", JwkDefinition.CryptoAlgorithm.RS384.headerParamValue()); + assertEquals("SHA384withRSA", JwkDefinition.CryptoAlgorithm.RS384.standardName()); + assertEquals("RS512", JwkDefinition.CryptoAlgorithm.RS512.headerParamValue()); + assertEquals("SHA512withRSA", JwkDefinition.CryptoAlgorithm.RS512.standardName()); + } +} \ No newline at end of file diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkSetConverterTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkSetConverterTest.java new file mode 100644 index 000000000..233385aeb --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkSetConverterTest.java @@ -0,0 +1,284 @@ +/* + * Copyright 2012-2017 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.token.store.jwk; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import static org.junit.Assert.*; +import static org.springframework.security.oauth2.provider.token.store.jwk.JwkAttributes.KEYS; + +/** + * @author Joe Grandja + */ +public class JwkSetConverterTest { + private final JwkSetConverter converter = new JwkSetConverter(); + private final ObjectMapper objectMapper = new ObjectMapper(); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + + @Test + public void convertWhenJwkSetStreamIsNullThenThrowJwkException() throws Exception { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("Invalid JWK Set Object."); + this.converter.convert(null); + } + + @Test + public void convertWhenJwkSetStreamIsEmptyThenThrowJwkException() throws Exception { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("Invalid JWK Set Object."); + this.converter.convert(new ByteArrayInputStream(new byte[0])); + } + + @Test + public void convertWhenJwkSetStreamNotAnObjectThenThrowJwkException() throws Exception { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("Invalid JWK Set Object."); + this.converter.convert(new ByteArrayInputStream("".getBytes())); + } + + @Test + public void convertWhenJwkSetStreamHasMissingKeysAttributeThenThrowJwkException() throws Exception { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("Invalid JWK Set Object."); + Map jwkSetObject = new HashMap(); + this.converter.convert(this.asInputStream(jwkSetObject)); + } + + @Test + public void convertWhenJwkSetStreamHasInvalidKeysAttributeThenThrowJwkException() throws Exception { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("Invalid JWK Set Object. The JWK Set MUST have a keys attribute."); + Map jwkSetObject = new HashMap(); + jwkSetObject.put(KEYS + "-invalid", new Map[0]); + this.converter.convert(this.asInputStream(jwkSetObject)); + } + + @Test + public void convertWhenJwkSetStreamHasInvalidJwkElementsThenThrowJwkException() throws Exception { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("Invalid JWK Set Object. The JWK Set MUST have an array of JWK(s)."); + Map jwkSetObject = new HashMap(); + jwkSetObject.put(JwkAttributes.KEYS, ""); + this.converter.convert(this.asInputStream(jwkSetObject)); + } + + @Test + public void convertWhenJwkSetStreamHasEmptyJwkElementsThenReturnEmptyJwkSet() throws Exception { + Map jwkSetObject = new HashMap(); + jwkSetObject.put(JwkAttributes.KEYS, new Map[0]); + Set jwkSet = this.converter.convert(this.asInputStream(jwkSetObject)); + assertTrue("JWK Set NOT empty", jwkSet.isEmpty()); + } + + @Test + public void convertWhenJwkSetStreamHasEmptyJwkElementThenThrowJwkException() throws Exception { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("unknown (kty) is currently not supported."); + Map jwkSetObject = new HashMap(); + Map jwkObject = new HashMap(); + jwkSetObject.put(JwkAttributes.KEYS, new Map[] {jwkObject}); + this.converter.convert(this.asInputStream(jwkSetObject)); + } + + @Test + public void convertWhenJwkSetStreamHasJwkElementWithECKeyTypeThenThrowJwkException() throws Exception { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("EC (kty) is currently not supported."); + Map jwkSetObject = new HashMap(); + Map jwkObject = this.createJwkObject(JwkDefinition.KeyType.EC); + jwkSetObject.put(JwkAttributes.KEYS, new Map[] {jwkObject}); + this.converter.convert(this.asInputStream(jwkSetObject)); + } + + @Test + public void convertWhenJwkSetStreamHasJwkElementWithOCTKeyTypeThenThrowJwkException() throws Exception { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("oct (kty) is currently not supported."); + Map jwkSetObject = new HashMap(); + Map jwkObject = this.createJwkObject(JwkDefinition.KeyType.OCT); + jwkSetObject.put(JwkAttributes.KEYS, new Map[] {jwkObject}); + this.converter.convert(this.asInputStream(jwkSetObject)); + } + + @Test + public void convertWhenJwkSetStreamHasJwkElementWithMissingKeyIdAttributeThenThrowJwkException() throws Exception { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("kid is a required attribute for a JWK."); + Map jwkSetObject = new HashMap(); + Map jwkObject = this.createJwkObject(JwkDefinition.KeyType.RSA, null); + jwkSetObject.put(JwkAttributes.KEYS, new Map[] {jwkObject}); + this.converter.convert(this.asInputStream(jwkSetObject)); + } + + @Test + public void convertWhenJwkSetStreamHasJwkElementWithMissingPublicKeyUseAttributeThenThrowJwkException() throws Exception { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("unknown (use) is currently not supported."); + Map jwkSetObject = new HashMap(); + Map jwkObject = this.createJwkObject(JwkDefinition.KeyType.RSA, "key-id-1"); + jwkSetObject.put(JwkAttributes.KEYS, new Map[] {jwkObject}); + this.converter.convert(this.asInputStream(jwkSetObject)); + } + + @Test + public void convertWhenJwkSetStreamHasJwkElementWithENCPublicKeyUseAttributeThenThrowJwkException() throws Exception { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("enc (use) is currently not supported."); + Map jwkSetObject = new HashMap(); + Map jwkObject = this.createJwkObject(JwkDefinition.KeyType.RSA, "key-id-1", JwkDefinition.PublicKeyUse.ENC); + jwkSetObject.put(JwkAttributes.KEYS, new Map[] {jwkObject}); + this.converter.convert(this.asInputStream(jwkSetObject)); + } + + @Test + public void convertWhenJwkSetStreamHasJwkElementWithMissingAlgorithmAttributeThenThrowJwkException() throws Exception { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("unknown (alg) is currently not supported."); + Map jwkSetObject = new HashMap(); + Map jwkObject = this.createJwkObject(JwkDefinition.KeyType.RSA, "key-id-1", JwkDefinition.PublicKeyUse.SIG); + jwkSetObject.put(JwkAttributes.KEYS, new Map[] {jwkObject}); + this.converter.convert(this.asInputStream(jwkSetObject)); + } + + @Test + public void convertWhenJwkSetStreamHasJwkElementWithMissingRSAModulusAttributeThenThrowJwkException() throws Exception { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("n is a required attribute for a RSA JWK."); + Map jwkSetObject = new HashMap(); + Map jwkObject = this.createJwkObject(JwkDefinition.KeyType.RSA, "key-id-1", + JwkDefinition.PublicKeyUse.SIG, JwkDefinition.CryptoAlgorithm.RS256); + jwkSetObject.put(JwkAttributes.KEYS, new Map[] {jwkObject}); + this.converter.convert(this.asInputStream(jwkSetObject)); + } + + @Test + public void convertWhenJwkSetStreamHasJwkElementWithMissingRSAExponentAttributeThenThrowJwkException() throws Exception { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("e is a required attribute for a RSA JWK."); + Map jwkSetObject = new HashMap(); + Map jwkObject = this.createJwkObject(JwkDefinition.KeyType.RSA, "key-id-1", + JwkDefinition.PublicKeyUse.SIG, JwkDefinition.CryptoAlgorithm.RS256, "AMh-pGAj9vX2gwFDyrXot1f2YfHgh8h0Qx6w9IqLL"); + jwkSetObject.put(JwkAttributes.KEYS, new Map[] {jwkObject}); + this.converter.convert(this.asInputStream(jwkSetObject)); + } + + @Test + public void convertWhenJwkSetStreamIsValidThenReturnJwkSet() throws Exception { + Map jwkSetObject = new HashMap(); + Map jwkObject = this.createJwkObject(JwkDefinition.KeyType.RSA, "key-id-1", + JwkDefinition.PublicKeyUse.SIG, JwkDefinition.CryptoAlgorithm.RS256, "AMh-pGAj9vX2gwFDyrXot1f2YfHgh8h0Qx6w9IqLL", "AQAB"); + jwkSetObject.put(JwkAttributes.KEYS, new Map[] {jwkObject}); + Set jwkSet = this.converter.convert(this.asInputStream(jwkSetObject)); + assertNotNull(jwkSet); + assertEquals("JWK Set NOT size=1", 1, jwkSet.size()); + + Map jwkObject2 = this.createJwkObject(JwkDefinition.KeyType.RSA, "key-id-2", + JwkDefinition.PublicKeyUse.SIG, JwkDefinition.CryptoAlgorithm.RS512, "AMh-pGAj9vX2gwFDyrXot1f2YfHgh8h0Qx6w9IqLL", "AQAB"); + jwkSetObject.put(JwkAttributes.KEYS, new Map[] {jwkObject, jwkObject2}); + jwkSet = this.converter.convert(this.asInputStream(jwkSetObject)); + assertNotNull(jwkSet); + assertEquals("JWK Set NOT size=2", 2, jwkSet.size()); + } + + @Test + public void convertWhenJwkSetStreamHasDuplicateJwkElementsThenThrowJwkException() throws Exception { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("Duplicate JWK found in Set: key-id-1 (kid)"); + Map jwkSetObject = new HashMap(); + Map jwkObject = this.createJwkObject(JwkDefinition.KeyType.RSA, "key-id-1", + JwkDefinition.PublicKeyUse.SIG, JwkDefinition.CryptoAlgorithm.RS256, "AMh-pGAj9vX2gwFDyrXot1f2YfHgh8h0Qx6w9IqLL", "AQAB"); + jwkSetObject.put(JwkAttributes.KEYS, new Map[] {jwkObject, jwkObject}); + this.converter.convert(this.asInputStream(jwkSetObject)); + } + + private Map createJwkObject(JwkDefinition.KeyType keyType) { + return this.createJwkObject(keyType, null); + } + + private Map createJwkObject(JwkDefinition.KeyType keyType, String keyId) { + return this.createJwkObject(keyType, keyId, null); + } + + private Map createJwkObject(JwkDefinition.KeyType keyType, + String keyId, + JwkDefinition.PublicKeyUse publicKeyUse) { + + return this.createJwkObject(keyType, keyId, publicKeyUse, null); + } + + private Map createJwkObject(JwkDefinition.KeyType keyType, + String keyId, + JwkDefinition.PublicKeyUse publicKeyUse, + JwkDefinition.CryptoAlgorithm algorithm) { + + return this.createJwkObject(keyType, keyId, publicKeyUse, algorithm, null); + } + + private Map createJwkObject(JwkDefinition.KeyType keyType, + String keyId, + JwkDefinition.PublicKeyUse publicKeyUse, + JwkDefinition.CryptoAlgorithm algorithm, + String rsaModulus) { + + return this.createJwkObject(keyType, keyId, publicKeyUse, algorithm, rsaModulus, null); + } + + private Map createJwkObject(JwkDefinition.KeyType keyType, + String keyId, + JwkDefinition.PublicKeyUse publicKeyUse, + JwkDefinition.CryptoAlgorithm algorithm, + String rsaModulus, + String rsaExponent) { + + Map jwkObject = new HashMap(); + jwkObject.put(JwkAttributes.KEY_TYPE, keyType.value()); + if (keyId != null) { + jwkObject.put(JwkAttributes.KEY_ID, keyId); + } + if (publicKeyUse != null) { + jwkObject.put(JwkAttributes.PUBLIC_KEY_USE, publicKeyUse.value()); + } + if (algorithm != null) { + jwkObject.put(JwkAttributes.ALGORITHM, algorithm.headerParamValue()); + } + if (rsaModulus != null) { + jwkObject.put(JwkAttributes.RSA_PUBLIC_KEY_MODULUS, rsaModulus); + } + if (rsaExponent != null) { + jwkObject.put(JwkAttributes.RSA_PUBLIC_KEY_EXPONENT, rsaExponent); + } + return jwkObject; + } + + private InputStream asInputStream(Map content) throws Exception { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + this.objectMapper.writeValue(out, content); + return new ByteArrayInputStream(out.toByteArray()); + } +} \ No newline at end of file diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkTokenStoreTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkTokenStoreTest.java new file mode 100644 index 000000000..28ea3b528 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkTokenStoreTest.java @@ -0,0 +1,153 @@ +/* + * Copyright 2012-2017 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.token.store.jwk; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; +import org.springframework.util.ReflectionUtils; + +import java.lang.reflect.Field; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.*; +import static org.powermock.api.mockito.PowerMockito.spy; + + +/** + * @author Joe Grandja + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest(JwkTokenStore.class) +public class JwkTokenStoreTest { + private JwkTokenStore jwkTokenStore = new JwkTokenStore("https://identity.server1.io/token_keys"); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void readAuthenticationUsingOAuth2AccessTokenWhenCalledThenDelegateCalled() throws Exception { + JwkTokenStore spy = spy(this.jwkTokenStore); + JwtTokenStore delegate = mock(JwtTokenStore.class); + when(delegate.readAuthentication(any(OAuth2AccessToken.class))).thenReturn(null); + + Field field = ReflectionUtils.findField(spy.getClass(), "delegate"); + field.setAccessible(true); + ReflectionUtils.setField(field, spy, delegate); + + spy.readAuthentication(mock(OAuth2AccessToken.class)); + verify(delegate).readAuthentication(any(OAuth2AccessToken.class)); + } + + @Test + public void readAuthenticationUsingAccessTokenStringWhenCalledThenDelegateCalled() throws Exception { + JwkTokenStore spy = spy(this.jwkTokenStore); + JwtTokenStore delegate = mock(JwtTokenStore.class); + when(delegate.readAuthentication(anyString())).thenReturn(null); + + Field field = ReflectionUtils.findField(spy.getClass(), "delegate"); + field.setAccessible(true); + ReflectionUtils.setField(field, spy, delegate); + + spy.readAuthentication(anyString()); + verify(delegate).readAuthentication(anyString()); + } + + @Test + public void readAccessTokenWhenCalledThenDelegateCalled() throws Exception { + JwkTokenStore spy = spy(this.jwkTokenStore); + JwtTokenStore delegate = mock(JwtTokenStore.class); + when(delegate.readAccessToken(anyString())).thenReturn(null); + + Field field = ReflectionUtils.findField(spy.getClass(), "delegate"); + field.setAccessible(true); + ReflectionUtils.setField(field, spy, delegate); + + spy.readAccessToken(anyString()); + verify(delegate).readAccessToken(anyString()); + } + + @Test + public void storeAccessTokenWhenCalledThenThrowJwkException() throws Exception { + this.setUpExpectedJwkException(); + this.jwkTokenStore.storeAccessToken(null, null); + } + + @Test + public void removeAccessTokenWhenCalledThenThrowJwkException() throws Exception { + this.setUpExpectedJwkException(); + this.jwkTokenStore.removeAccessToken(null); + } + + @Test + public void storeRefreshTokenWhenCalledThenThrowJwkException() throws Exception { + this.setUpExpectedJwkException(); + this.jwkTokenStore.storeRefreshToken(null, null); + } + + @Test + public void readRefreshTokenWhenCalledThenThrowJwkException() throws Exception { + this.setUpExpectedJwkException(); + this.jwkTokenStore.readRefreshToken(null); + } + + @Test + public void readAuthenticationForRefreshTokenWhenCalledThenThrowJwkException() throws Exception { + this.setUpExpectedJwkException(); + this.jwkTokenStore.readAuthenticationForRefreshToken(null); + } + + @Test + public void removeRefreshTokenWhenCalledThenThrowJwkException() throws Exception { + this.setUpExpectedJwkException(); + this.jwkTokenStore.removeRefreshToken(null); + } + + @Test + public void removeAccessTokenUsingRefreshTokenWhenCalledThenThrowJwkException() throws Exception { + this.setUpExpectedJwkException(); + this.jwkTokenStore.removeAccessTokenUsingRefreshToken(null); + } + + @Test + public void getAccessTokenWhenCalledThenThrowJwkException() throws Exception { + this.setUpExpectedJwkException(); + this.jwkTokenStore.getAccessToken(null); + } + + @Test + public void findTokensByClientIdAndUserNameWhenCalledThenThrowJwkException() throws Exception { + this.setUpExpectedJwkException(); + this.jwkTokenStore.findTokensByClientIdAndUserName(null, null); + } + + @Test + public void findTokensByClientIdWhenCalledThenThrowJwkException() throws Exception { + this.setUpExpectedJwkException(); + this.jwkTokenStore.findTokensByClientId(null); + } + + private void setUpExpectedJwkException() { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("This operation is not supported."); + } +} \ No newline at end of file diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkVerifyingJwtAccessTokenConverterTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkVerifyingJwtAccessTokenConverterTest.java new file mode 100644 index 000000000..3c830838e --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkVerifyingJwtAccessTokenConverterTest.java @@ -0,0 +1,109 @@ +/* + * Copyright 2012-2017 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.token.store.jwk; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.springframework.security.oauth2.provider.token.store.jwk.JwtTestUtil.createJwt; +import static org.springframework.security.oauth2.provider.token.store.jwk.JwtTestUtil.createJwtHeader; + +/** + * @author Joe Grandja + */ +public class JwkVerifyingJwtAccessTokenConverterTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void encodeWhenCalledThenThrowJwkException() throws Exception { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("JWT signing (JWS) is not supported."); + JwkVerifyingJwtAccessTokenConverter accessTokenConverter = + new JwkVerifyingJwtAccessTokenConverter(mock(JwkDefinitionSource.class)); + accessTokenConverter.encode(null, null); + } + + @Test + public void decodeWhenKeyIdHeaderMissingThenThrowJwkException() throws Exception { + this.thrown.expect(InvalidTokenException.class); + this.thrown.expectMessage("Invalid JWT/JWS: kid is a required JOSE Header"); + JwkVerifyingJwtAccessTokenConverter accessTokenConverter = + new JwkVerifyingJwtAccessTokenConverter(mock(JwkDefinitionSource.class)); + String jwt = createJwt(createJwtHeader(null, JwkDefinition.CryptoAlgorithm.RS256)); + accessTokenConverter.decode(jwt); + } + + @Test + public void decodeWhenKeyIdHeaderInvalidThenThrowJwkException() throws Exception { + this.thrown.expect(InvalidTokenException.class); + this.thrown.expectMessage("Invalid JOSE Header kid (invalid-key-id)"); + JwkDefinition jwkDefinition = this.createRSAJwkDefinition("key-id-1", JwkDefinition.CryptoAlgorithm.RS256); + JwkDefinitionSource jwkDefinitionSource = mock(JwkDefinitionSource.class); + when(jwkDefinitionSource.getDefinitionLoadIfNecessary("key-id-1")).thenReturn(jwkDefinition); + JwkVerifyingJwtAccessTokenConverter accessTokenConverter = + new JwkVerifyingJwtAccessTokenConverter(jwkDefinitionSource); + String jwt = createJwt(createJwtHeader("invalid-key-id", JwkDefinition.CryptoAlgorithm.RS256)); + accessTokenConverter.decode(jwt); + } + + @Test + public void decodeWhenAlgorithmHeaderMissingThenThrowJwkException() throws Exception { + this.thrown.expect(InvalidTokenException.class); + this.thrown.expectMessage("Invalid JWT/JWS: alg is a required JOSE Header"); + JwkDefinition jwkDefinition = this.createRSAJwkDefinition("key-id-1", JwkDefinition.CryptoAlgorithm.RS256); + JwkDefinitionSource jwkDefinitionSource = mock(JwkDefinitionSource.class); + when(jwkDefinitionSource.getDefinitionLoadIfNecessary("key-id-1")).thenReturn(jwkDefinition); + JwkVerifyingJwtAccessTokenConverter accessTokenConverter = + new JwkVerifyingJwtAccessTokenConverter(jwkDefinitionSource); + String jwt = createJwt(createJwtHeader("key-id-1", null)); + accessTokenConverter.decode(jwt); + } + + @Test + public void decodeWhenAlgorithmHeaderDoesNotMatchJwkAlgorithmThenThrowJwkException() throws Exception { + this.thrown.expect(InvalidTokenException.class); + this.thrown.expectMessage("Invalid JOSE Header alg (RS512) " + + "does not match algorithm associated to JWK with kid (key-id-1)"); + JwkDefinition jwkDefinition = this.createRSAJwkDefinition("key-id-1", JwkDefinition.CryptoAlgorithm.RS256); + JwkDefinitionSource jwkDefinitionSource = mock(JwkDefinitionSource.class); + when(jwkDefinitionSource.getDefinitionLoadIfNecessary("key-id-1")).thenReturn(jwkDefinition); + JwkVerifyingJwtAccessTokenConverter accessTokenConverter = + new JwkVerifyingJwtAccessTokenConverter(jwkDefinitionSource); + String jwt = createJwt(createJwtHeader("key-id-1", JwkDefinition.CryptoAlgorithm.RS512)); + accessTokenConverter.decode(jwt); + } + + private JwkDefinition createRSAJwkDefinition(String keyId, JwkDefinition.CryptoAlgorithm algorithm) { + return createRSAJwkDefinition(JwkDefinition.KeyType.RSA, keyId, + JwkDefinition.PublicKeyUse.SIG, algorithm, "AMh-pGAj9vX2gwFDyrXot1f2YfHgh8h0Qx6w9IqLL", "AQAB"); + } + + private JwkDefinition createRSAJwkDefinition(JwkDefinition.KeyType keyType, + String keyId, + JwkDefinition.PublicKeyUse publicKeyUse, + JwkDefinition.CryptoAlgorithm algorithm, + String modulus, + String exponent) { + + return new RsaJwkDefinition(keyId, publicKeyUse, algorithm, modulus, exponent); + } +} \ No newline at end of file diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwtHeaderConverterTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwtHeaderConverterTest.java new file mode 100644 index 000000000..a7689d5c3 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwtHeaderConverterTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2012-2017 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.token.store.jwk; + + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; + +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.springframework.security.oauth2.provider.token.store.jwk.JwtTestUtil.createJwt; + +/** + * @author Joe Grandja + */ +public class JwtHeaderConverterTest { + private final JwtHeaderConverter converter = new JwtHeaderConverter(); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + + @Test + public void convertWhenJwtTokenIsNullThenThrowNullPointerException() throws Exception { + this.thrown.expect(NullPointerException.class); + this.converter.convert(null); + } + + @Test + public void convertWhenJwtTokenInvalidThenThrowJwkException() throws Exception { + this.thrown.expect(InvalidTokenException.class); + this.thrown.expectMessage("Invalid JWT. Missing JOSE Header."); + this.converter.convert(""); + } + + @Test + public void convertWhenJwtTokenValidThenReturnJwtHeaders() throws Exception { + Map jwtHeaders = this.converter.convert(createJwt()); + assertEquals("key-id-1", jwtHeaders.get(JwkAttributes.KEY_ID)); + assertEquals(JwkDefinition.CryptoAlgorithm.RS256.headerParamValue(), jwtHeaders.get(JwkAttributes.ALGORITHM)); + } +} \ No newline at end of file diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwtTestUtil.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwtTestUtil.java new file mode 100644 index 000000000..5aab5d5e9 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwtTestUtil.java @@ -0,0 +1,86 @@ +/* + * Copyright 2012-2017 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.token.store.jwk; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.security.jwt.codec.Codecs; + +import java.io.ByteArrayOutputStream; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Joe Grandja + */ +class JwtTestUtil { + private static final ObjectMapper objectMapper = new ObjectMapper(); + + static String createJwt() throws Exception { + return createJwt(createDefaultJwtHeader()); + } + + static String createJwt(byte[] jwtHeader) throws Exception { + return createJwt(jwtHeader, createDefaultJwtPayload()); + } + + static String createJwt(byte[] jwtHeader, byte[] jwtPayload) throws Exception { + byte[] encodedJwtHeader = Codecs.b64UrlEncode(jwtHeader); + byte[] encodedJwtPayload = Codecs.b64UrlEncode(jwtPayload); + byte[] period = Codecs.utf8Encode("."); + return new String(join(encodedJwtHeader, period, encodedJwtPayload)); + } + + static byte[] createDefaultJwtHeader() throws Exception { + return createJwtHeader("key-id-1", JwkDefinition.CryptoAlgorithm.RS256); + } + + static byte[] createJwtHeader(String keyId, JwkDefinition.CryptoAlgorithm algorithm) throws Exception { + Map jwtHeader = new HashMap(); + if (keyId != null) { + jwtHeader.put(JwkAttributes.KEY_ID, keyId); + } + if (algorithm != null) { + jwtHeader.put(JwkAttributes.ALGORITHM, algorithm.headerParamValue()); + } + ByteArrayOutputStream out = new ByteArrayOutputStream(); + objectMapper.writeValue(out, jwtHeader); + return out.toByteArray(); + } + + static byte[] createDefaultJwtPayload() throws Exception { + Map jwtPayload = new HashMap(); + jwtPayload.put("claim-name-1", "claim-value-1"); + jwtPayload.put("claim-name-2", "claim-value-2"); + jwtPayload.put("claim-name-3", "claim-value-3"); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + objectMapper.writeValue(out, jwtPayload); + return out.toByteArray(); + } + + private static byte[] join(byte[]... byteArrays) { + int size = 0; + for (byte[] bytes : byteArrays) { + size += bytes.length; + } + byte[] result = new byte[size]; + int index = 0; + for (byte[] bytes : byteArrays) { + System.arraycopy(bytes, 0, result, index, bytes.length); + index += bytes.length; + } + return result; + } +} \ No newline at end of file diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/RsaJwkDefinitionTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/RsaJwkDefinitionTest.java new file mode 100644 index 000000000..72ca34d3c --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/RsaJwkDefinitionTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2012-2017 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.token.store.jwk; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author Joe Grandja + */ +public class RsaJwkDefinitionTest { + + @Test + public void constructorWhenArgumentsPassedThenAttributesAreCorrectlySet() throws Exception { + String keyId = "key-id-1"; + JwkDefinition.PublicKeyUse publicKeyUse = JwkDefinition.PublicKeyUse.ENC; + JwkDefinition.CryptoAlgorithm algorithm = JwkDefinition.CryptoAlgorithm.RS384; + String modulus = "AMh-pGAj9vX2gwFDyrXot1f2YfHgh8h0Qx6w9IqLL"; + String exponent = "AQAB"; + + RsaJwkDefinition rsaJwkDefinition = new RsaJwkDefinition( + keyId, publicKeyUse, algorithm, modulus, exponent); + + assertEquals(keyId, rsaJwkDefinition.getKeyId()); + assertEquals(JwkDefinition.KeyType.RSA, rsaJwkDefinition.getKeyType()); + assertEquals(publicKeyUse, rsaJwkDefinition.getPublicKeyUse()); + assertEquals(algorithm, rsaJwkDefinition.getAlgorithm()); + assertEquals(modulus, rsaJwkDefinition.getModulus()); + assertEquals(exponent, rsaJwkDefinition.getExponent()); + } +} \ No newline at end of file diff --git a/tests/annotation/approval/pom.xml b/tests/annotation/approval/pom.xml index 2dc67ad4d..d1110a48a 100644 --- a/tests/annotation/approval/pom.xml +++ b/tests/annotation/approval/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/approval/src/main/java/demo/Application.java b/tests/annotation/approval/src/main/java/demo/Application.java index 101b9bfb8..82281f84a 100644 --- a/tests/annotation/approval/src/main/java/demo/Application.java +++ b/tests/annotation/approval/src/main/java/demo/Application.java @@ -2,9 +2,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; @@ -19,9 +18,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -@Configuration -@ComponentScan -@EnableAutoConfiguration +@SpringBootApplication @EnableResourceServer @RestController public class Application { diff --git a/tests/annotation/approval/src/main/resources/application.yml b/tests/annotation/approval/src/main/resources/application.yml index e52b05d1f..99c539833 100644 --- a/tests/annotation/approval/src/main/resources/application.yml +++ b/tests/annotation/approval/src/main/resources/application.yml @@ -6,3 +6,6 @@ management: security: user: password: password + oauth2: + resource: + filter-order: 3 diff --git a/tests/annotation/approval/src/test/java/demo/ApplicationTests.java b/tests/annotation/approval/src/test/java/demo/ApplicationTests.java index 15eca8da6..39d23f056 100644 --- a/tests/annotation/approval/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/approval/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,12 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.boot.test.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = Application.class) -@WebAppConfiguration -@IntegrationTest("server.port=0") +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) public class ApplicationTests { @Test diff --git a/tests/annotation/approval/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/approval/src/test/java/demo/AuthorizationCodeProviderTests.java index 3bc5e7dac..7b60325b0 100755 --- a/tests/annotation/approval/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/approval/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -14,14 +14,11 @@ import static org.junit.Assert.assertTrue; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractAuthorizationCodeProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) public class AuthorizationCodeProviderTests extends AbstractAuthorizationCodeProviderTests { protected void verifyAuthorizationPage(String page) { diff --git a/tests/annotation/approval/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/annotation/approval/src/test/java/demo/ClientCredentialsProviderTests.java index af8190074..857ff7fa0 100644 --- a/tests/annotation/approval/src/test/java/demo/ClientCredentialsProviderTests.java +++ b/tests/annotation/approval/src/test/java/demo/ClientCredentialsProviderTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractClientCredentialsProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { diff --git a/tests/annotation/approval/src/test/java/demo/ImplicitProviderTests.java b/tests/annotation/approval/src/test/java/demo/ImplicitProviderTests.java index 7a8958187..0e34ccc7d 100644 --- a/tests/annotation/approval/src/test/java/demo/ImplicitProviderTests.java +++ b/tests/annotation/approval/src/test/java/demo/ImplicitProviderTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractImplicitProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ImplicitProviderTests extends AbstractImplicitProviderTests { } diff --git a/tests/annotation/approval/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/approval/src/test/java/demo/ProtectedResourceTests.java index c752cbe12..302b30f96 100644 --- a/tests/annotation/approval/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/approval/src/test/java/demo/ProtectedResourceTests.java @@ -13,15 +13,12 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractProtectedResourceTests; /** * @author Dave Syer * */ -@SpringApplicationConfiguration(classes = Application.class) public class ProtectedResourceTests extends AbstractProtectedResourceTests { } diff --git a/tests/annotation/approval/src/test/java/demo/RefreshTokenSupportTests.java b/tests/annotation/approval/src/test/java/demo/RefreshTokenSupportTests.java index 4ed370eea..417bac867 100644 --- a/tests/annotation/approval/src/test/java/demo/RefreshTokenSupportTests.java +++ b/tests/annotation/approval/src/test/java/demo/RefreshTokenSupportTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractRefreshTokenSupportTests; /** * @author Ryan Heaton * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class RefreshTokenSupportTests extends AbstractRefreshTokenSupportTests { } diff --git a/tests/annotation/approval/src/test/java/demo/ResourceOwnerPasswordProviderTests.java b/tests/annotation/approval/src/test/java/demo/ResourceOwnerPasswordProviderTests.java index aa5786098..5682e05a6 100644 --- a/tests/annotation/approval/src/test/java/demo/ResourceOwnerPasswordProviderTests.java +++ b/tests/annotation/approval/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractResourceOwnerPasswordProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ResourceOwnerPasswordProviderTests extends AbstractResourceOwnerPasswordProviderTests { } diff --git a/tests/annotation/client/pom.xml b/tests/annotation/client/pom.xml index 555854c6d..d2aebd623 100644 --- a/tests/annotation/client/pom.xml +++ b/tests/annotation/client/pom.xml @@ -11,7 +11,7 @@ org.demo spring-oauth2-tests-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/client/src/main/resources/application.yml b/tests/annotation/client/src/main/resources/application.yml index 72f3eb459..e223ea3ad 100644 --- a/tests/annotation/client/src/main/resources/application.yml +++ b/tests/annotation/client/src/main/resources/application.yml @@ -8,3 +8,6 @@ server: security: basic: enabled: false + oauth2: + resource: + filter-order: 3 diff --git a/tests/annotation/client/src/test/java/client/ApplicationTests.java b/tests/annotation/client/src/test/java/client/ApplicationTests.java index 8c5aef34a..971e2b4a0 100644 --- a/tests/annotation/client/src/test/java/client/ApplicationTests.java +++ b/tests/annotation/client/src/test/java/client/ApplicationTests.java @@ -2,15 +2,12 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.boot.test.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = ClientApplication.class) -@WebAppConfiguration -@IntegrationTest("server.port=0") +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT, classes=ClientApplication.class) public class ApplicationTests { @Test diff --git a/tests/annotation/client/src/test/java/client/ClientServerInteractionTests.java b/tests/annotation/client/src/test/java/client/ClientServerInteractionTests.java index 64db5054c..f078ff6e3 100644 --- a/tests/annotation/client/src/test/java/client/ClientServerInteractionTests.java +++ b/tests/annotation/client/src/test/java/client/ClientServerInteractionTests.java @@ -6,7 +6,8 @@ import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext; import org.springframework.security.oauth2.client.OAuth2RestOperations; import org.springframework.security.oauth2.client.OAuth2RestTemplate; @@ -19,7 +20,8 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = { ClientApplication.class, CombinedApplication.class }) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, classes = { + ClientApplication.class, CombinedApplication.class }) @ActiveProfiles("combined") public class ClientServerInteractionTests extends AbstractIntegrationTests { @@ -27,7 +29,7 @@ public class ClientServerInteractionTests extends AbstractIntegrationTests { private AuthorizationCodeResourceDetails resource; private OAuth2RestOperations template; - + @Before public void init() { template = new OAuth2RestTemplate(resource, new DefaultOAuth2ClientContext()); diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml index 6491f1938..dc24d1048 100644 --- a/tests/annotation/common/pom.xml +++ b/tests/annotation/common/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT @@ -53,15 +53,6 @@ demo.Application - - - - org.springframework.boot - spring-boot-maven-plugin - - - - spring-snapshots diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java index b35341615..023566427 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java @@ -31,7 +31,9 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.context.embedded.LocalServerPort; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.core.io.ClassPathResource; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.converter.HttpMessageConverter; @@ -53,12 +55,10 @@ import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringJUnit4ClassRunner.class) -@WebAppConfiguration -@IntegrationTest("server.port=0") +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) public abstract class AbstractIntegrationTests { public static final String JAVAX_NET_SSL_TRUST_STORE_PASSWORD = "javax.net.ssl.trustStorePassword"; @@ -84,7 +84,7 @@ public abstract class AbstractIntegrationTests { } } - @Value("${local.server.port}") + @LocalServerPort private int port; @Rule diff --git a/tests/annotation/common/src/main/java/sparklr/common/HttpTestUtils.java b/tests/annotation/common/src/main/java/sparklr/common/HttpTestUtils.java index 8e765c04c..1a0456552 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/HttpTestUtils.java +++ b/tests/annotation/common/src/main/java/sparklr/common/HttpTestUtils.java @@ -9,7 +9,7 @@ import org.junit.rules.MethodRule; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; -import org.springframework.boot.test.TestRestTemplate; +import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -234,7 +234,7 @@ public RestOperations getRestTemplate() { } public RestOperations createRestTemplate() { - RestTemplate client = new TestRestTemplate(); + RestTemplate client = new TestRestTemplate().getRestTemplate(); return client; } diff --git a/tests/annotation/custom-authentication/pom.xml b/tests/annotation/custom-authentication/pom.xml index f2f8cb481..38884d6b4 100644 --- a/tests/annotation/custom-authentication/pom.xml +++ b/tests/annotation/custom-authentication/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/custom-authentication/src/main/java/demo/Application.java b/tests/annotation/custom-authentication/src/main/java/demo/Application.java index 8566b7eb1..b45985dc4 100644 --- a/tests/annotation/custom-authentication/src/main/java/demo/Application.java +++ b/tests/annotation/custom-authentication/src/main/java/demo/Application.java @@ -2,7 +2,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; import org.springframework.security.authentication.AuthenticationManager; @@ -19,8 +19,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -@Configuration -@EnableAutoConfiguration +@SpringBootApplication @EnableResourceServer @RestController public class Application { diff --git a/tests/annotation/custom-authentication/src/main/resources/application.yml b/tests/annotation/custom-authentication/src/main/resources/application.yml index ccf06f8ba..8f7a77341 100644 --- a/tests/annotation/custom-authentication/src/main/resources/application.yml +++ b/tests/annotation/custom-authentication/src/main/resources/application.yml @@ -6,6 +6,9 @@ management: security: user: password: password + oauth2: + resource: + filter-order: 3 logging: level: # org.springframework.security: DEBUG \ No newline at end of file diff --git a/tests/annotation/custom-authentication/src/test/java/demo/ApplicationTests.java b/tests/annotation/custom-authentication/src/test/java/demo/ApplicationTests.java index 15eca8da6..1f2353d99 100644 --- a/tests/annotation/custom-authentication/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/custom-authentication/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,11 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.boot.test.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = Application.class) -@WebAppConfiguration -@IntegrationTest("server.port=0") +@RunWith(SpringRunner.class) +@SpringBootTest public class ApplicationTests { @Test diff --git a/tests/annotation/custom-authentication/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/annotation/custom-authentication/src/test/java/demo/ClientCredentialsProviderTests.java index f4dd6da46..f0734bc81 100644 --- a/tests/annotation/custom-authentication/src/test/java/demo/ClientCredentialsProviderTests.java +++ b/tests/annotation/custom-authentication/src/test/java/demo/ClientCredentialsProviderTests.java @@ -9,7 +9,6 @@ import org.junit.Before; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; @@ -30,7 +29,6 @@ * * @author michaeltecourt */ -@SpringApplicationConfiguration(classes = Application.class) public class ClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { protected URI tokenUri; diff --git a/tests/annotation/custom-grant/pom.xml b/tests/annotation/custom-grant/pom.xml index 3ef3ac2de..648084bea 100644 --- a/tests/annotation/custom-grant/pom.xml +++ b/tests/annotation/custom-grant/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/custom-grant/src/main/java/demo/Application.java b/tests/annotation/custom-grant/src/main/java/demo/Application.java index 7dd777944..df08bbfe9 100644 --- a/tests/annotation/custom-grant/src/main/java/demo/Application.java +++ b/tests/annotation/custom-grant/src/main/java/demo/Application.java @@ -6,7 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; import org.springframework.security.authentication.AuthenticationManager; @@ -24,8 +24,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; -@Configuration -@EnableAutoConfiguration +@SpringBootApplication @EnableResourceServer @RestController public class Application { diff --git a/tests/annotation/custom-grant/src/main/resources/application.yml b/tests/annotation/custom-grant/src/main/resources/application.yml index ccf06f8ba..8f7a77341 100644 --- a/tests/annotation/custom-grant/src/main/resources/application.yml +++ b/tests/annotation/custom-grant/src/main/resources/application.yml @@ -6,6 +6,9 @@ management: security: user: password: password + oauth2: + resource: + filter-order: 3 logging: level: # org.springframework.security: DEBUG \ No newline at end of file diff --git a/tests/annotation/custom-grant/src/test/java/demo/ApplicationTests.java b/tests/annotation/custom-grant/src/test/java/demo/ApplicationTests.java index 15eca8da6..34f49b849 100644 --- a/tests/annotation/custom-grant/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/custom-grant/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,11 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.boot.test.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = Application.class) -@WebAppConfiguration -@IntegrationTest("server.port=0") +@RunWith(SpringRunner.class) +@SpringBootTest public class ApplicationTests { @Test diff --git a/tests/annotation/custom-grant/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/custom-grant/src/test/java/demo/AuthorizationCodeProviderTests.java index 49a38d4ab..34cdef81b 100755 --- a/tests/annotation/custom-grant/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/custom-grant/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -17,7 +17,6 @@ import static org.junit.Assert.assertTrue; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; @@ -28,7 +27,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) public class AuthorizationCodeProviderTests extends AbstractAuthorizationCodeProviderTests { @Test diff --git a/tests/annotation/custom-grant/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/annotation/custom-grant/src/test/java/demo/ClientCredentialsProviderTests.java index af8190074..857ff7fa0 100644 --- a/tests/annotation/custom-grant/src/test/java/demo/ClientCredentialsProviderTests.java +++ b/tests/annotation/custom-grant/src/test/java/demo/ClientCredentialsProviderTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractClientCredentialsProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { diff --git a/tests/annotation/custom-grant/src/test/java/demo/CustomProviderTests.java b/tests/annotation/custom-grant/src/test/java/demo/CustomProviderTests.java index 219553795..bd6897227 100644 --- a/tests/annotation/custom-grant/src/test/java/demo/CustomProviderTests.java +++ b/tests/annotation/custom-grant/src/test/java/demo/CustomProviderTests.java @@ -1,11 +1,10 @@ package demo; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import java.util.Map; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -17,7 +16,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) public class CustomProviderTests extends AbstractIntegrationTests { @Test diff --git a/tests/annotation/custom-grant/src/test/java/demo/ImplicitProviderTests.java b/tests/annotation/custom-grant/src/test/java/demo/ImplicitProviderTests.java index 92379335a..0945dffce 100644 --- a/tests/annotation/custom-grant/src/test/java/demo/ImplicitProviderTests.java +++ b/tests/annotation/custom-grant/src/test/java/demo/ImplicitProviderTests.java @@ -13,8 +13,7 @@ import java.util.concurrent.Future; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.boot.test.TestRestTemplate; +import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; @@ -25,7 +24,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) public class ImplicitProviderTests extends AbstractImplicitProviderTests { @Test diff --git a/tests/annotation/custom-grant/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/custom-grant/src/test/java/demo/ProtectedResourceTests.java index c752cbe12..302b30f96 100644 --- a/tests/annotation/custom-grant/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/custom-grant/src/test/java/demo/ProtectedResourceTests.java @@ -13,15 +13,12 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractProtectedResourceTests; /** * @author Dave Syer * */ -@SpringApplicationConfiguration(classes = Application.class) public class ProtectedResourceTests extends AbstractProtectedResourceTests { } diff --git a/tests/annotation/custom-grant/src/test/java/demo/RefreshTokenSupportTests.java b/tests/annotation/custom-grant/src/test/java/demo/RefreshTokenSupportTests.java index 4ed370eea..417bac867 100644 --- a/tests/annotation/custom-grant/src/test/java/demo/RefreshTokenSupportTests.java +++ b/tests/annotation/custom-grant/src/test/java/demo/RefreshTokenSupportTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractRefreshTokenSupportTests; /** * @author Ryan Heaton * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class RefreshTokenSupportTests extends AbstractRefreshTokenSupportTests { } diff --git a/tests/annotation/custom-grant/src/test/java/demo/ResourceOwnerPasswordProviderTests.java b/tests/annotation/custom-grant/src/test/java/demo/ResourceOwnerPasswordProviderTests.java index aa5786098..5682e05a6 100644 --- a/tests/annotation/custom-grant/src/test/java/demo/ResourceOwnerPasswordProviderTests.java +++ b/tests/annotation/custom-grant/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractResourceOwnerPasswordProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ResourceOwnerPasswordProviderTests extends AbstractResourceOwnerPasswordProviderTests { } diff --git a/tests/annotation/form/pom.xml b/tests/annotation/form/pom.xml index 311156648..0170024a6 100644 --- a/tests/annotation/form/pom.xml +++ b/tests/annotation/form/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/form/src/main/java/demo/Application.java b/tests/annotation/form/src/main/java/demo/Application.java index 696029d71..cba6c9f6f 100644 --- a/tests/annotation/form/src/main/java/demo/Application.java +++ b/tests/annotation/form/src/main/java/demo/Application.java @@ -2,8 +2,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.context.annotation.ComponentScan; +import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; @@ -15,9 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -@Configuration -@ComponentScan -@EnableAutoConfiguration +@SpringBootApplication @EnableResourceServer @RestController public class Application { diff --git a/tests/annotation/form/src/main/resources/application.yml b/tests/annotation/form/src/main/resources/application.yml index dbb4d4d3e..57c6bd9cc 100644 --- a/tests/annotation/form/src/main/resources/application.yml +++ b/tests/annotation/form/src/main/resources/application.yml @@ -6,6 +6,9 @@ management: security: user: password: password + oauth2: + resource: + filter-order: 3 logging: level: org.springframework.security: WARN diff --git a/tests/annotation/form/src/test/java/demo/ApplicationTests.java b/tests/annotation/form/src/test/java/demo/ApplicationTests.java index 15eca8da6..34f49b849 100644 --- a/tests/annotation/form/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/form/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,11 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.boot.test.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = Application.class) -@WebAppConfiguration -@IntegrationTest("server.port=0") +@RunWith(SpringRunner.class) +@SpringBootTest public class ApplicationTests { @Test diff --git a/tests/annotation/form/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/form/src/test/java/demo/AuthorizationCodeProviderTests.java index 632098bf1..2ef50fde6 100755 --- a/tests/annotation/form/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/form/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -12,14 +12,11 @@ */ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractAuthorizationCodeProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) public class AuthorizationCodeProviderTests extends AbstractAuthorizationCodeProviderTests { } diff --git a/tests/annotation/form/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/annotation/form/src/test/java/demo/ClientCredentialsProviderTests.java index 3d9ccf4f6..d70b43c90 100644 --- a/tests/annotation/form/src/test/java/demo/ClientCredentialsProviderTests.java +++ b/tests/annotation/form/src/test/java/demo/ClientCredentialsProviderTests.java @@ -8,7 +8,6 @@ import java.io.IOException; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.client.ClientHttpResponse; @@ -24,7 +23,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { private HttpHeaders responseHeaders; diff --git a/tests/annotation/form/src/test/java/demo/ImplicitProviderTests.java b/tests/annotation/form/src/test/java/demo/ImplicitProviderTests.java index 7a8958187..0e34ccc7d 100644 --- a/tests/annotation/form/src/test/java/demo/ImplicitProviderTests.java +++ b/tests/annotation/form/src/test/java/demo/ImplicitProviderTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractImplicitProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ImplicitProviderTests extends AbstractImplicitProviderTests { } diff --git a/tests/annotation/form/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/form/src/test/java/demo/ProtectedResourceTests.java index c752cbe12..302b30f96 100644 --- a/tests/annotation/form/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/form/src/test/java/demo/ProtectedResourceTests.java @@ -13,15 +13,12 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractProtectedResourceTests; /** * @author Dave Syer * */ -@SpringApplicationConfiguration(classes = Application.class) public class ProtectedResourceTests extends AbstractProtectedResourceTests { } diff --git a/tests/annotation/form/src/test/java/demo/RefreshTokenSupportTests.java b/tests/annotation/form/src/test/java/demo/RefreshTokenSupportTests.java index 4ed370eea..417bac867 100644 --- a/tests/annotation/form/src/test/java/demo/RefreshTokenSupportTests.java +++ b/tests/annotation/form/src/test/java/demo/RefreshTokenSupportTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractRefreshTokenSupportTests; /** * @author Ryan Heaton * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class RefreshTokenSupportTests extends AbstractRefreshTokenSupportTests { } diff --git a/tests/annotation/form/src/test/java/demo/ResourceOwnerPasswordProviderTests.java b/tests/annotation/form/src/test/java/demo/ResourceOwnerPasswordProviderTests.java index 6eaa554eb..7fe135878 100644 --- a/tests/annotation/form/src/test/java/demo/ResourceOwnerPasswordProviderTests.java +++ b/tests/annotation/form/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -1,6 +1,5 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails; import org.springframework.security.oauth2.client.test.BeforeOAuth2Context; import org.springframework.security.oauth2.common.AuthenticationScheme; @@ -10,7 +9,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) public class ResourceOwnerPasswordProviderTests extends AbstractResourceOwnerPasswordProviderTests { diff --git a/tests/annotation/jaxb/pom.xml b/tests/annotation/jaxb/pom.xml index 05fc8f4cd..6b76b5c08 100644 --- a/tests/annotation/jaxb/pom.xml +++ b/tests/annotation/jaxb/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/jaxb/src/main/java/demo/Application.java b/tests/annotation/jaxb/src/main/java/demo/Application.java index 956c80ffd..a9ec20e09 100644 --- a/tests/annotation/jaxb/src/main/java/demo/Application.java +++ b/tests/annotation/jaxb/src/main/java/demo/Application.java @@ -5,8 +5,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.context.annotation.ComponentScan; +import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.security.authentication.AuthenticationManager; @@ -28,9 +27,7 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -@Configuration -@ComponentScan -@EnableAutoConfiguration +@SpringBootApplication @EnableResourceServer @RestController public class Application extends WebMvcConfigurerAdapter { diff --git a/tests/annotation/jaxb/src/main/resources/application.yml b/tests/annotation/jaxb/src/main/resources/application.yml index a9c0149f0..c88891b00 100644 --- a/tests/annotation/jaxb/src/main/resources/application.yml +++ b/tests/annotation/jaxb/src/main/resources/application.yml @@ -6,3 +6,6 @@ management: security: user: password: password + oauth2: + resource: + filter-order: 3 diff --git a/tests/annotation/jaxb/src/test/java/demo/ApplicationTests.java b/tests/annotation/jaxb/src/test/java/demo/ApplicationTests.java index 15eca8da6..34f49b849 100644 --- a/tests/annotation/jaxb/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/jaxb/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,11 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.boot.test.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = Application.class) -@WebAppConfiguration -@IntegrationTest("server.port=0") +@RunWith(SpringRunner.class) +@SpringBootTest public class ApplicationTests { @Test diff --git a/tests/annotation/jaxb/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/jaxb/src/test/java/demo/AuthorizationCodeProviderTests.java index 7d8889a6c..0333fa789 100755 --- a/tests/annotation/jaxb/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/jaxb/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -18,7 +18,6 @@ import java.util.Collection; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageConverter; @@ -28,7 +27,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) public class AuthorizationCodeProviderTests extends AbstractAuthorizationCodeProviderTests { @Test diff --git a/tests/annotation/jaxb/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/annotation/jaxb/src/test/java/demo/ClientCredentialsProviderTests.java index ef9ade0cd..b24e666c8 100644 --- a/tests/annotation/jaxb/src/test/java/demo/ClientCredentialsProviderTests.java +++ b/tests/annotation/jaxb/src/test/java/demo/ClientCredentialsProviderTests.java @@ -3,7 +3,6 @@ import java.util.Collection; import java.util.List; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.converter.HttpMessageConverter; @@ -12,7 +11,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { @Override diff --git a/tests/annotation/jaxb/src/test/java/demo/ImplicitProviderTests.java b/tests/annotation/jaxb/src/test/java/demo/ImplicitProviderTests.java index 874e9ca09..d5bbfd381 100644 --- a/tests/annotation/jaxb/src/test/java/demo/ImplicitProviderTests.java +++ b/tests/annotation/jaxb/src/test/java/demo/ImplicitProviderTests.java @@ -13,8 +13,7 @@ import java.util.concurrent.Future; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.boot.test.TestRestTemplate; +import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageConverter; @@ -26,7 +25,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) public class ImplicitProviderTests extends AbstractImplicitProviderTests { @Test diff --git a/tests/annotation/jaxb/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/jaxb/src/test/java/demo/ProtectedResourceTests.java index d47fb4893..0a539c5f4 100644 --- a/tests/annotation/jaxb/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/jaxb/src/test/java/demo/ProtectedResourceTests.java @@ -15,7 +15,6 @@ import java.util.Collection; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.converter.HttpMessageConverter; import sparklr.common.AbstractProtectedResourceTests; @@ -24,7 +23,6 @@ * @author Dave Syer * */ -@SpringApplicationConfiguration(classes = Application.class) public class ProtectedResourceTests extends AbstractProtectedResourceTests { @Override diff --git a/tests/annotation/jaxb/src/test/java/demo/RefreshTokenSupportTests.java b/tests/annotation/jaxb/src/test/java/demo/RefreshTokenSupportTests.java index adcaa1326..06804a151 100644 --- a/tests/annotation/jaxb/src/test/java/demo/RefreshTokenSupportTests.java +++ b/tests/annotation/jaxb/src/test/java/demo/RefreshTokenSupportTests.java @@ -2,7 +2,6 @@ import java.util.Collection; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.converter.HttpMessageConverter; import sparklr.common.AbstractRefreshTokenSupportTests; @@ -11,7 +10,6 @@ * @author Ryan Heaton * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class RefreshTokenSupportTests extends AbstractRefreshTokenSupportTests { @Override diff --git a/tests/annotation/jaxb/src/test/java/demo/ResourceOwnerPasswordProviderTests.java b/tests/annotation/jaxb/src/test/java/demo/ResourceOwnerPasswordProviderTests.java index c41de197c..c69f87d8a 100644 --- a/tests/annotation/jaxb/src/test/java/demo/ResourceOwnerPasswordProviderTests.java +++ b/tests/annotation/jaxb/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -2,7 +2,6 @@ import java.util.Collection; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.converter.HttpMessageConverter; import sparklr.common.AbstractResourceOwnerPasswordProviderTests; @@ -10,7 +9,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ResourceOwnerPasswordProviderTests extends AbstractResourceOwnerPasswordProviderTests { @Override diff --git a/tests/annotation/jdbc/pom.xml b/tests/annotation/jdbc/pom.xml index b38274a78..2035871b8 100644 --- a/tests/annotation/jdbc/pom.xml +++ b/tests/annotation/jdbc/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/jdbc/src/main/java/demo/Application.java b/tests/annotation/jdbc/src/main/java/demo/Application.java index 36f243d80..300e4f250 100644 --- a/tests/annotation/jdbc/src/main/java/demo/Application.java +++ b/tests/annotation/jdbc/src/main/java/demo/Application.java @@ -129,7 +129,7 @@ public void configure(ClientDetailsServiceConfigurer clients) throws Exception { public void init(AuthenticationManagerBuilder auth) throws Exception { // @formatter:off auth.jdbcAuthentication().dataSource(dataSource).withUser("dave") - .password("secret").roles("USER"); + .password("secret").roles("USER", "ACTUATOR"); // @formatter:on } diff --git a/tests/annotation/jdbc/src/main/resources/application.yml b/tests/annotation/jdbc/src/main/resources/application.yml index da08708a2..d83b7e17a 100644 --- a/tests/annotation/jdbc/src/main/resources/application.yml +++ b/tests/annotation/jdbc/src/main/resources/application.yml @@ -3,6 +3,10 @@ spring: name: jdbc management: context_path: /admin +security: + oauth2: + resource: + filter-order: 3 logging: level: # org.springframework.security: DEBUG diff --git a/tests/annotation/jdbc/src/test/java/demo/ApplicationTests.java b/tests/annotation/jdbc/src/test/java/demo/ApplicationTests.java index ac31a7866..20748d419 100644 --- a/tests/annotation/jdbc/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/jdbc/src/test/java/demo/ApplicationTests.java @@ -3,22 +3,17 @@ import static org.junit.Assert.assertTrue; import org.junit.Test; -import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.security.oauth2.provider.ClientDetailsService; import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.context.ContextConfiguration; -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = Application.class) -@WebAppConfiguration -@IntegrationTest("server.port=0") -public class ApplicationTests { +import sparklr.common.AbstractIntegrationTests; + +@ContextConfiguration(classes=Application.class) +public class ApplicationTests extends AbstractIntegrationTests { @Autowired private TokenStore tokenStore; diff --git a/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java index 40787edad..5882b7cd3 100755 --- a/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -15,14 +15,14 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.ContextConfiguration; import sparklr.common.AbstractAuthorizationCodeProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) +@ContextConfiguration(classes=Application.class) public class AuthorizationCodeProviderTests extends AbstractAuthorizationCodeProviderTests { protected String getPassword() { diff --git a/tests/annotation/jdbc/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/annotation/jdbc/src/test/java/demo/ClientCredentialsProviderTests.java index af8190074..e23fe4f49 100644 --- a/tests/annotation/jdbc/src/test/java/demo/ClientCredentialsProviderTests.java +++ b/tests/annotation/jdbc/src/test/java/demo/ClientCredentialsProviderTests.java @@ -1,13 +1,13 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.ContextConfiguration; import sparklr.common.AbstractClientCredentialsProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) +@ContextConfiguration(classes=Application.class) public class ClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { diff --git a/tests/annotation/jdbc/src/test/java/demo/ImplicitProviderTests.java b/tests/annotation/jdbc/src/test/java/demo/ImplicitProviderTests.java index 89b5a1ef8..225c53741 100644 --- a/tests/annotation/jdbc/src/test/java/demo/ImplicitProviderTests.java +++ b/tests/annotation/jdbc/src/test/java/demo/ImplicitProviderTests.java @@ -1,13 +1,13 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.ContextConfiguration; import sparklr.common.AbstractImplicitProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) +@ContextConfiguration(classes=Application.class) public class ImplicitProviderTests extends AbstractImplicitProviderTests { protected String getPassword() { diff --git a/tests/annotation/jdbc/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/jdbc/src/test/java/demo/ProtectedResourceTests.java index c752cbe12..0e2acc8d9 100644 --- a/tests/annotation/jdbc/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/jdbc/src/test/java/demo/ProtectedResourceTests.java @@ -13,7 +13,7 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.ContextConfiguration; import sparklr.common.AbstractProtectedResourceTests; @@ -21,7 +21,7 @@ * @author Dave Syer * */ -@SpringApplicationConfiguration(classes = Application.class) +@ContextConfiguration(classes=Application.class) public class ProtectedResourceTests extends AbstractProtectedResourceTests { } diff --git a/tests/annotation/jdbc/src/test/java/demo/RefreshTokenSupportTests.java b/tests/annotation/jdbc/src/test/java/demo/RefreshTokenSupportTests.java index 299e66005..9d2a59ca6 100644 --- a/tests/annotation/jdbc/src/test/java/demo/RefreshTokenSupportTests.java +++ b/tests/annotation/jdbc/src/test/java/demo/RefreshTokenSupportTests.java @@ -1,6 +1,6 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.ContextConfiguration; import sparklr.common.AbstractRefreshTokenSupportTests; @@ -8,7 +8,7 @@ * @author Ryan Heaton * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) +@ContextConfiguration(classes=Application.class) public class RefreshTokenSupportTests extends AbstractRefreshTokenSupportTests { protected String getPassword() { return "secret"; diff --git a/tests/annotation/jdbc/src/test/java/demo/ResourceOwnerPasswordProviderTests.java b/tests/annotation/jdbc/src/test/java/demo/ResourceOwnerPasswordProviderTests.java index 65c784f57..408aeae50 100644 --- a/tests/annotation/jdbc/src/test/java/demo/ResourceOwnerPasswordProviderTests.java +++ b/tests/annotation/jdbc/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -4,16 +4,16 @@ import static org.junit.Assert.assertTrue; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; +import org.springframework.test.context.ContextConfiguration; import sparklr.common.AbstractResourceOwnerPasswordProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) +@ContextConfiguration(classes=Application.class) public class ResourceOwnerPasswordProviderTests extends AbstractResourceOwnerPasswordProviderTests { protected String getPassword() { diff --git a/tests/annotation/jpa/pom.xml b/tests/annotation/jpa/pom.xml index b82319fc0..e973072a1 100644 --- a/tests/annotation/jpa/pom.xml +++ b/tests/annotation/jpa/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/jpa/src/main/java/demo/Application.java b/tests/annotation/jpa/src/main/java/demo/Application.java index 5cb7f67a1..20b5aecbc 100644 --- a/tests/annotation/jpa/src/main/java/demo/Application.java +++ b/tests/annotation/jpa/src/main/java/demo/Application.java @@ -95,7 +95,7 @@ public void configure(ClientDetailsServiceConfigurer clients) throws Exception { @Autowired public void authenticationManager(AuthenticationManagerBuilder builder, UserRepository repository) throws Exception { if (repository.count()==0) { - repository.save(new User("user", "password", Arrays.asList(new Role("USER")))); + repository.save(new User("user", "password", Arrays.asList(new Role("USER"), new Role("ACTUATOR")))); } builder.userDetailsService(userDetailsService(repository)); } diff --git a/tests/annotation/jpa/src/main/resources/application.yml b/tests/annotation/jpa/src/main/resources/application.yml index faea2bd5a..85e3c2c52 100644 --- a/tests/annotation/jpa/src/main/resources/application.yml +++ b/tests/annotation/jpa/src/main/resources/application.yml @@ -6,6 +6,9 @@ management: security: user: password: password + oauth2: + resource: + filter-order: 3 logging: level: # org.springframework.security: DEBUG diff --git a/tests/annotation/jpa/src/test/java/demo/ApplicationTests.java b/tests/annotation/jpa/src/test/java/demo/ApplicationTests.java index 15eca8da6..34f49b849 100644 --- a/tests/annotation/jpa/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/jpa/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,11 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.boot.test.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = Application.class) -@WebAppConfiguration -@IntegrationTest("server.port=0") +@RunWith(SpringRunner.class) +@SpringBootTest public class ApplicationTests { @Test diff --git a/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderCookieTests.java b/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderCookieTests.java index 7b614e004..e9083e3f3 100644 --- a/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderCookieTests.java +++ b/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderCookieTests.java @@ -16,7 +16,6 @@ import static org.junit.Assert.assertNotNull; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; @@ -27,7 +26,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) public class AuthorizationCodeProviderCookieTests extends AbstractEmptyAuthorizationCodeProviderTests { @Test diff --git a/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderTests.java index 49a38d4ab..34cdef81b 100755 --- a/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -17,7 +17,6 @@ import static org.junit.Assert.assertTrue; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; @@ -28,7 +27,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) public class AuthorizationCodeProviderTests extends AbstractAuthorizationCodeProviderTests { @Test diff --git a/tests/annotation/jpa/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/annotation/jpa/src/test/java/demo/ClientCredentialsProviderTests.java index af8190074..857ff7fa0 100644 --- a/tests/annotation/jpa/src/test/java/demo/ClientCredentialsProviderTests.java +++ b/tests/annotation/jpa/src/test/java/demo/ClientCredentialsProviderTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractClientCredentialsProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { diff --git a/tests/annotation/jpa/src/test/java/demo/ImplicitProviderTests.java b/tests/annotation/jpa/src/test/java/demo/ImplicitProviderTests.java index 06ebe766b..ef7c254ce 100644 --- a/tests/annotation/jpa/src/test/java/demo/ImplicitProviderTests.java +++ b/tests/annotation/jpa/src/test/java/demo/ImplicitProviderTests.java @@ -14,8 +14,7 @@ import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.boot.test.TestRestTemplate; +import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; @@ -26,7 +25,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) public class ImplicitProviderTests extends AbstractImplicitProviderTests { @BeforeClass diff --git a/tests/annotation/jpa/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/jpa/src/test/java/demo/ProtectedResourceTests.java index c752cbe12..302b30f96 100644 --- a/tests/annotation/jpa/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/jpa/src/test/java/demo/ProtectedResourceTests.java @@ -13,15 +13,12 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractProtectedResourceTests; /** * @author Dave Syer * */ -@SpringApplicationConfiguration(classes = Application.class) public class ProtectedResourceTests extends AbstractProtectedResourceTests { } diff --git a/tests/annotation/jpa/src/test/java/demo/RefreshTokenSupportTests.java b/tests/annotation/jpa/src/test/java/demo/RefreshTokenSupportTests.java index 4ed370eea..417bac867 100644 --- a/tests/annotation/jpa/src/test/java/demo/RefreshTokenSupportTests.java +++ b/tests/annotation/jpa/src/test/java/demo/RefreshTokenSupportTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractRefreshTokenSupportTests; /** * @author Ryan Heaton * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class RefreshTokenSupportTests extends AbstractRefreshTokenSupportTests { } diff --git a/tests/annotation/jpa/src/test/java/demo/ResourceOwnerPasswordProviderTests.java b/tests/annotation/jpa/src/test/java/demo/ResourceOwnerPasswordProviderTests.java index 28a8e9f84..31a0f75b8 100644 --- a/tests/annotation/jpa/src/test/java/demo/ResourceOwnerPasswordProviderTests.java +++ b/tests/annotation/jpa/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -3,8 +3,7 @@ import static org.junit.Assert.assertEquals; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.boot.test.TestRestTemplate; +import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; @@ -14,7 +13,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ResourceOwnerPasswordProviderTests extends AbstractResourceOwnerPasswordProviderTests { @Test diff --git a/tests/annotation/jwt/pom.xml b/tests/annotation/jwt/pom.xml index 6d92b9026..46c3a4609 100644 --- a/tests/annotation/jwt/pom.xml +++ b/tests/annotation/jwt/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/jwt/src/main/java/demo/Application.java b/tests/annotation/jwt/src/main/java/demo/Application.java index 5d5c71d5f..0aebd4b1f 100644 --- a/tests/annotation/jwt/src/main/java/demo/Application.java +++ b/tests/annotation/jwt/src/main/java/demo/Application.java @@ -2,9 +2,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; @@ -17,9 +16,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -@Configuration -@ComponentScan -@EnableAutoConfiguration +@SpringBootApplication @EnableResourceServer @RestController public class Application { diff --git a/tests/annotation/jwt/src/main/resources/application.yml b/tests/annotation/jwt/src/main/resources/application.yml index ccf06f8ba..8f7a77341 100644 --- a/tests/annotation/jwt/src/main/resources/application.yml +++ b/tests/annotation/jwt/src/main/resources/application.yml @@ -6,6 +6,9 @@ management: security: user: password: password + oauth2: + resource: + filter-order: 3 logging: level: # org.springframework.security: DEBUG \ No newline at end of file diff --git a/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java b/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java index 82a5ffee6..1bb5192c6 100644 --- a/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java @@ -6,30 +6,25 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.boot.test.TestRestTemplate; +import org.springframework.boot.context.embedded.LocalServerPort; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpStatus; -import org.springframework.security.oauth2.provider.token.DefaultTokenServices; +import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.util.ReflectionTestUtils; -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = Application.class) -@WebAppConfiguration -@IntegrationTest("server.port=0") +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) public class ApplicationTests { - @Value("${local.server.port}") + @LocalServerPort private int port; @Autowired - @Qualifier("defaultAuthorizationServerTokenServices") - private DefaultTokenServices tokenServices; + private AuthorizationServerTokenServices tokenServices; @Test public void tokenStoreIsJwt() { diff --git a/tests/annotation/jwt/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/jwt/src/test/java/demo/AuthorizationCodeProviderTests.java index 632098bf1..2ef50fde6 100755 --- a/tests/annotation/jwt/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/jwt/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -12,14 +12,11 @@ */ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractAuthorizationCodeProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) public class AuthorizationCodeProviderTests extends AbstractAuthorizationCodeProviderTests { } diff --git a/tests/annotation/jwt/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/annotation/jwt/src/test/java/demo/ClientCredentialsProviderTests.java index f26763279..26ee5e7cf 100644 --- a/tests/annotation/jwt/src/test/java/demo/ClientCredentialsProviderTests.java +++ b/tests/annotation/jwt/src/test/java/demo/ClientCredentialsProviderTests.java @@ -6,8 +6,7 @@ import java.util.Map; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.boot.test.TestRestTemplate; +import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -23,7 +22,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) public class ClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { /** diff --git a/tests/annotation/jwt/src/test/java/demo/ImplicitProviderTests.java b/tests/annotation/jwt/src/test/java/demo/ImplicitProviderTests.java index 7a8958187..0e34ccc7d 100644 --- a/tests/annotation/jwt/src/test/java/demo/ImplicitProviderTests.java +++ b/tests/annotation/jwt/src/test/java/demo/ImplicitProviderTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractImplicitProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ImplicitProviderTests extends AbstractImplicitProviderTests { } diff --git a/tests/annotation/jwt/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/jwt/src/test/java/demo/ProtectedResourceTests.java index c752cbe12..302b30f96 100644 --- a/tests/annotation/jwt/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/jwt/src/test/java/demo/ProtectedResourceTests.java @@ -13,15 +13,12 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractProtectedResourceTests; /** * @author Dave Syer * */ -@SpringApplicationConfiguration(classes = Application.class) public class ProtectedResourceTests extends AbstractProtectedResourceTests { } diff --git a/tests/annotation/jwt/src/test/java/demo/RefreshTokenSupportTests.java b/tests/annotation/jwt/src/test/java/demo/RefreshTokenSupportTests.java index 295fbdabf..28349045f 100644 --- a/tests/annotation/jwt/src/test/java/demo/RefreshTokenSupportTests.java +++ b/tests/annotation/jwt/src/test/java/demo/RefreshTokenSupportTests.java @@ -3,11 +3,9 @@ import static org.junit.Assert.assertEquals; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.security.oauth2.common.OAuth2AccessToken; -import org.springframework.security.oauth2.provider.token.DefaultTokenServices; +import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; import org.springframework.test.util.ReflectionTestUtils; @@ -17,12 +15,10 @@ * @author Ryan Heaton * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class RefreshTokenSupportTests extends AbstractRefreshTokenSupportTests { @Autowired - @Qualifier("defaultAuthorizationServerTokenServices") - private DefaultTokenServices services; + private AuthorizationServerTokenServices services; protected void verifyAccessTokens(OAuth2AccessToken oldAccessToken, OAuth2AccessToken newAccessToken) { // make sure the new access token can be used. diff --git a/tests/annotation/jwt/src/test/java/demo/ResourceOwnerPasswordProviderTests.java b/tests/annotation/jwt/src/test/java/demo/ResourceOwnerPasswordProviderTests.java index d233098a2..4625d154e 100644 --- a/tests/annotation/jwt/src/test/java/demo/ResourceOwnerPasswordProviderTests.java +++ b/tests/annotation/jwt/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -6,8 +6,7 @@ import java.util.Map; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.boot.test.TestRestTemplate; +import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -24,7 +23,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ResourceOwnerPasswordProviderTests extends AbstractResourceOwnerPasswordProviderTests { @Test diff --git a/tests/annotation/mappings/pom.xml b/tests/annotation/mappings/pom.xml index 8346ed914..eff643328 100644 --- a/tests/annotation/mappings/pom.xml +++ b/tests/annotation/mappings/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/mappings/src/main/resources/application.yml b/tests/annotation/mappings/src/main/resources/application.yml index 3b09181d7..5f71e88df 100644 --- a/tests/annotation/mappings/src/main/resources/application.yml +++ b/tests/annotation/mappings/src/main/resources/application.yml @@ -6,6 +6,9 @@ management: security: user: password: password + oauth2: + resource: + filter-order: 3 logging: level: # org.springframework.security: DEBUG diff --git a/tests/annotation/mappings/src/test/java/demo/ApplicationTests.java b/tests/annotation/mappings/src/test/java/demo/ApplicationTests.java index 15eca8da6..34f49b849 100644 --- a/tests/annotation/mappings/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/mappings/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,11 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.boot.test.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = Application.class) -@WebAppConfiguration -@IntegrationTest("server.port=0") +@RunWith(SpringRunner.class) +@SpringBootTest public class ApplicationTests { @Test diff --git a/tests/annotation/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java index 04f4e3c31..5fba9cfe0 100755 --- a/tests/annotation/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -19,7 +19,6 @@ import java.util.Arrays; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails; import org.springframework.security.oauth2.common.exceptions.InsufficientScopeException; @@ -29,7 +28,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) public class AuthorizationCodeProviderTests extends AbstractAuthorizationCodeProviderTests { @Test diff --git a/tests/annotation/mappings/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/annotation/mappings/src/test/java/demo/ClientCredentialsProviderTests.java index 8c5a6ceac..3765b268e 100644 --- a/tests/annotation/mappings/src/test/java/demo/ClientCredentialsProviderTests.java +++ b/tests/annotation/mappings/src/test/java/demo/ClientCredentialsProviderTests.java @@ -6,8 +6,7 @@ import java.util.Map; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.boot.test.TestRestTemplate; +import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -23,7 +22,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { /** diff --git a/tests/annotation/mappings/src/test/java/demo/ImplicitProviderTests.java b/tests/annotation/mappings/src/test/java/demo/ImplicitProviderTests.java index 7a8958187..0e34ccc7d 100644 --- a/tests/annotation/mappings/src/test/java/demo/ImplicitProviderTests.java +++ b/tests/annotation/mappings/src/test/java/demo/ImplicitProviderTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractImplicitProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ImplicitProviderTests extends AbstractImplicitProviderTests { } diff --git a/tests/annotation/mappings/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/mappings/src/test/java/demo/ProtectedResourceTests.java index 743d9158b..4f5e357cc 100644 --- a/tests/annotation/mappings/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/mappings/src/test/java/demo/ProtectedResourceTests.java @@ -17,7 +17,6 @@ import static org.junit.Assert.assertTrue; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -27,7 +26,6 @@ * @author Dave Syer * */ -@SpringApplicationConfiguration(classes = Application.class) public class ProtectedResourceTests extends AbstractProtectedResourceTests { @Test diff --git a/tests/annotation/mappings/src/test/java/demo/RefreshTokenSupportTests.java b/tests/annotation/mappings/src/test/java/demo/RefreshTokenSupportTests.java index 4ed370eea..417bac867 100644 --- a/tests/annotation/mappings/src/test/java/demo/RefreshTokenSupportTests.java +++ b/tests/annotation/mappings/src/test/java/demo/RefreshTokenSupportTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractRefreshTokenSupportTests; /** * @author Ryan Heaton * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class RefreshTokenSupportTests extends AbstractRefreshTokenSupportTests { } diff --git a/tests/annotation/mappings/src/test/java/demo/ResourceOwnerPasswordProviderTests.java b/tests/annotation/mappings/src/test/java/demo/ResourceOwnerPasswordProviderTests.java index aa5786098..5682e05a6 100644 --- a/tests/annotation/mappings/src/test/java/demo/ResourceOwnerPasswordProviderTests.java +++ b/tests/annotation/mappings/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractResourceOwnerPasswordProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ResourceOwnerPasswordProviderTests extends AbstractResourceOwnerPasswordProviderTests { } diff --git a/tests/annotation/mappings/src/test/java/demo/ServletPathClientCredentialsProviderTests.java b/tests/annotation/mappings/src/test/java/demo/ServletPathClientCredentialsProviderTests.java index e5344a065..967c864ef 100644 --- a/tests/annotation/mappings/src/test/java/demo/ServletPathClientCredentialsProviderTests.java +++ b/tests/annotation/mappings/src/test/java/demo/ServletPathClientCredentialsProviderTests.java @@ -5,21 +5,18 @@ import java.util.Map; import org.junit.Test; -import org.springframework.boot.test.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.boot.test.TestRestTemplate; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; import sparklr.common.AbstractClientCredentialsProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) -@IntegrationTest({"server.servlet_path:/server", "server.port=0"}) -@DirtiesContext +@SpringBootTest(classes=Application.class, properties="server.servlet_path:/server", webEnvironment=WebEnvironment.RANDOM_PORT) public class ServletPathClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { @Test diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index e2634b7c1..554119314 100644 --- a/tests/annotation/multi/pom.xml +++ b/tests/annotation/multi/pom.xml @@ -9,7 +9,7 @@ org.demo spring-oauth2-tests-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/multi/src/main/java/demo/Application.java b/tests/annotation/multi/src/main/java/demo/Application.java index a740fd5d6..e7e26ebda 100644 --- a/tests/annotation/multi/src/main/java/demo/Application.java +++ b/tests/annotation/multi/src/main/java/demo/Application.java @@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.oauth2.OAuth2AutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; @@ -21,7 +22,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -@SpringBootApplication +// TODO: remove the exclusion when Spring Boot 1.5.2 is out +@SpringBootApplication(exclude=OAuth2AutoConfiguration.class) @RestController public class Application { diff --git a/tests/annotation/multi/src/test/java/demo/ApplicationTests.java b/tests/annotation/multi/src/test/java/demo/ApplicationTests.java index 15eca8da6..34f49b849 100644 --- a/tests/annotation/multi/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/multi/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,11 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.boot.test.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = Application.class) -@WebAppConfiguration -@IntegrationTest("server.port=0") +@RunWith(SpringRunner.class) +@SpringBootTest public class ApplicationTests { @Test diff --git a/tests/annotation/multi/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/multi/src/test/java/demo/AuthorizationCodeProviderTests.java index 632098bf1..2ef50fde6 100755 --- a/tests/annotation/multi/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/multi/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -12,14 +12,11 @@ */ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractAuthorizationCodeProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) public class AuthorizationCodeProviderTests extends AbstractAuthorizationCodeProviderTests { } diff --git a/tests/annotation/multi/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/annotation/multi/src/test/java/demo/ClientCredentialsProviderTests.java index af8190074..857ff7fa0 100644 --- a/tests/annotation/multi/src/test/java/demo/ClientCredentialsProviderTests.java +++ b/tests/annotation/multi/src/test/java/demo/ClientCredentialsProviderTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractClientCredentialsProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { diff --git a/tests/annotation/multi/src/test/java/demo/ImplicitProviderTests.java b/tests/annotation/multi/src/test/java/demo/ImplicitProviderTests.java index 7a8958187..0e34ccc7d 100644 --- a/tests/annotation/multi/src/test/java/demo/ImplicitProviderTests.java +++ b/tests/annotation/multi/src/test/java/demo/ImplicitProviderTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractImplicitProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ImplicitProviderTests extends AbstractImplicitProviderTests { } diff --git a/tests/annotation/multi/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/multi/src/test/java/demo/ProtectedResourceTests.java index aa30f20f6..bf1dfd35f 100644 --- a/tests/annotation/multi/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/multi/src/test/java/demo/ProtectedResourceTests.java @@ -17,7 +17,6 @@ import static org.junit.Assert.assertTrue; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -27,7 +26,6 @@ * @author Dave Syer * */ -@SpringApplicationConfiguration(classes = Application.class) public class ProtectedResourceTests extends AbstractProtectedResourceTests { @Test diff --git a/tests/annotation/multi/src/test/java/demo/RefreshTokenSupportTests.java b/tests/annotation/multi/src/test/java/demo/RefreshTokenSupportTests.java index 4ed370eea..417bac867 100644 --- a/tests/annotation/multi/src/test/java/demo/RefreshTokenSupportTests.java +++ b/tests/annotation/multi/src/test/java/demo/RefreshTokenSupportTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractRefreshTokenSupportTests; /** * @author Ryan Heaton * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class RefreshTokenSupportTests extends AbstractRefreshTokenSupportTests { } diff --git a/tests/annotation/multi/src/test/java/demo/ResourceOwnerPasswordProviderTests.java b/tests/annotation/multi/src/test/java/demo/ResourceOwnerPasswordProviderTests.java index 886c48e28..8a82b64dd 100644 --- a/tests/annotation/multi/src/test/java/demo/ResourceOwnerPasswordProviderTests.java +++ b/tests/annotation/multi/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -5,7 +5,6 @@ import java.util.Arrays; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; @@ -14,7 +13,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ResourceOwnerPasswordProviderTests extends AbstractResourceOwnerPasswordProviderTests { @Test diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 411d5a2bf..065a54434 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT pom @@ -30,7 +30,7 @@ org.springframework.boot spring-boot-starter-parent - 1.3.5.RELEASE + 1.5.1.RELEASE @@ -39,7 +39,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT jackson-mapper-asl @@ -50,7 +50,7 @@ org.springframework.security spring-security-jwt - 1.0.3.RELEASE + 1.0.7.RELEASE diff --git a/tests/annotation/resource/pom.xml b/tests/annotation/resource/pom.xml index 6d3b500f1..df34736a2 100644 --- a/tests/annotation/resource/pom.xml +++ b/tests/annotation/resource/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/resource/src/main/java/demo/Application.java b/tests/annotation/resource/src/main/java/demo/Application.java index 2758734b1..55498e567 100644 --- a/tests/annotation/resource/src/main/java/demo/Application.java +++ b/tests/annotation/resource/src/main/java/demo/Application.java @@ -1,19 +1,15 @@ package demo; import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -@Configuration -@ComponentScan -@EnableAutoConfiguration +@SpringBootApplication @EnableResourceServer @RestController public class Application { diff --git a/tests/annotation/resource/src/main/resources/application.yml b/tests/annotation/resource/src/main/resources/application.yml index a9c0149f0..c88891b00 100644 --- a/tests/annotation/resource/src/main/resources/application.yml +++ b/tests/annotation/resource/src/main/resources/application.yml @@ -6,3 +6,6 @@ management: security: user: password: password + oauth2: + resource: + filter-order: 3 diff --git a/tests/annotation/resource/src/test/java/demo/ApplicationTests.java b/tests/annotation/resource/src/test/java/demo/ApplicationTests.java index 15eca8da6..34f49b849 100644 --- a/tests/annotation/resource/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/resource/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,11 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.boot.test.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = Application.class) -@WebAppConfiguration -@IntegrationTest("server.port=0") +@RunWith(SpringRunner.class) +@SpringBootTest public class ApplicationTests { @Test diff --git a/tests/annotation/resource/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/resource/src/test/java/demo/ProtectedResourceTests.java index c752cbe12..302b30f96 100644 --- a/tests/annotation/resource/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/resource/src/test/java/demo/ProtectedResourceTests.java @@ -13,15 +13,12 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractProtectedResourceTests; /** * @author Dave Syer * */ -@SpringApplicationConfiguration(classes = Application.class) public class ProtectedResourceTests extends AbstractProtectedResourceTests { } diff --git a/tests/annotation/ssl/pom.xml b/tests/annotation/ssl/pom.xml index 13dbe9cd3..9a6a8a01a 100644 --- a/tests/annotation/ssl/pom.xml +++ b/tests/annotation/ssl/pom.xml @@ -11,7 +11,7 @@ org.demo spring-oauth2-tests-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/vanilla/pom.xml b/tests/annotation/vanilla/pom.xml index 590597180..7b31b952a 100644 --- a/tests/annotation/vanilla/pom.xml +++ b/tests/annotation/vanilla/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/vanilla/src/main/resources/application.yml b/tests/annotation/vanilla/src/main/resources/application.yml index 5414a20b3..21a0bac83 100644 --- a/tests/annotation/vanilla/src/main/resources/application.yml +++ b/tests/annotation/vanilla/src/main/resources/application.yml @@ -6,6 +6,9 @@ management: security: user: password: password + oauth2: + resource: + filter-order: 3 logging: level: org.springframework.security: WARN \ No newline at end of file diff --git a/tests/annotation/vanilla/src/test/java/demo/ApplicationTests.java b/tests/annotation/vanilla/src/test/java/demo/ApplicationTests.java index 15eca8da6..6a1f865e8 100644 --- a/tests/annotation/vanilla/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,12 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.springframework.boot.test.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = Application.class) -@WebAppConfiguration -@IntegrationTest("server.port=0") +@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) public class ApplicationTests { @Test diff --git a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java index 7b614e004..e9083e3f3 100644 --- a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java @@ -16,7 +16,6 @@ import static org.junit.Assert.assertNotNull; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; @@ -27,7 +26,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) public class AuthorizationCodeProviderCookieTests extends AbstractEmptyAuthorizationCodeProviderTests { @Test diff --git a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java index 49a38d4ab..34cdef81b 100755 --- a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -17,7 +17,6 @@ import static org.junit.Assert.assertTrue; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; @@ -28,7 +27,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) public class AuthorizationCodeProviderTests extends AbstractAuthorizationCodeProviderTests { @Test diff --git a/tests/annotation/vanilla/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/annotation/vanilla/src/test/java/demo/ClientCredentialsProviderTests.java index af8190074..857ff7fa0 100644 --- a/tests/annotation/vanilla/src/test/java/demo/ClientCredentialsProviderTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/ClientCredentialsProviderTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractClientCredentialsProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { diff --git a/tests/annotation/vanilla/src/test/java/demo/GlobalMethodSecurityTests.java b/tests/annotation/vanilla/src/test/java/demo/GlobalMethodSecurityTests.java index 5977d393d..fcbf10952 100644 --- a/tests/annotation/vanilla/src/test/java/demo/GlobalMethodSecurityTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/GlobalMethodSecurityTests.java @@ -1,23 +1,23 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.context.annotation.Configuration; import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler; -import sparklr.common.AbstractProtectedResourceTests; import demo.GlobalMethodSecurityTests.GlobalSecurityConfiguration; +import sparklr.common.AbstractProtectedResourceTests; -@SpringApplicationConfiguration(classes = { Application.class, - GlobalSecurityConfiguration.class }) +@SpringBootTest(classes = { Application.class, GlobalSecurityConfiguration.class }, webEnvironment=WebEnvironment.RANDOM_PORT) public class GlobalMethodSecurityTests extends AbstractProtectedResourceTests { @Configuration @EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true) - protected static class GlobalSecurityConfiguration extends - GlobalMethodSecurityConfiguration { + protected static class GlobalSecurityConfiguration + extends GlobalMethodSecurityConfiguration { @Override protected MethodSecurityExpressionHandler createExpressionHandler() { diff --git a/tests/annotation/vanilla/src/test/java/demo/ImplicitProviderTests.java b/tests/annotation/vanilla/src/test/java/demo/ImplicitProviderTests.java index 06ebe766b..ef7c254ce 100644 --- a/tests/annotation/vanilla/src/test/java/demo/ImplicitProviderTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/ImplicitProviderTests.java @@ -14,8 +14,7 @@ import org.junit.BeforeClass; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.boot.test.TestRestTemplate; +import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; @@ -26,7 +25,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes = Application.class) public class ImplicitProviderTests extends AbstractImplicitProviderTests { @BeforeClass diff --git a/tests/annotation/vanilla/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/vanilla/src/test/java/demo/ProtectedResourceTests.java index c752cbe12..302b30f96 100644 --- a/tests/annotation/vanilla/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/ProtectedResourceTests.java @@ -13,15 +13,12 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractProtectedResourceTests; /** * @author Dave Syer * */ -@SpringApplicationConfiguration(classes = Application.class) public class ProtectedResourceTests extends AbstractProtectedResourceTests { } diff --git a/tests/annotation/vanilla/src/test/java/demo/RefreshTokenSupportTests.java b/tests/annotation/vanilla/src/test/java/demo/RefreshTokenSupportTests.java index 4ed370eea..417bac867 100644 --- a/tests/annotation/vanilla/src/test/java/demo/RefreshTokenSupportTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/RefreshTokenSupportTests.java @@ -1,13 +1,10 @@ package demo; -import org.springframework.boot.test.SpringApplicationConfiguration; - import sparklr.common.AbstractRefreshTokenSupportTests; /** * @author Ryan Heaton * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class RefreshTokenSupportTests extends AbstractRefreshTokenSupportTests { } diff --git a/tests/annotation/vanilla/src/test/java/demo/ResourceOwnerPasswordProviderTests.java b/tests/annotation/vanilla/src/test/java/demo/ResourceOwnerPasswordProviderTests.java index 28a8e9f84..31a0f75b8 100644 --- a/tests/annotation/vanilla/src/test/java/demo/ResourceOwnerPasswordProviderTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -3,8 +3,7 @@ import static org.junit.Assert.assertEquals; import org.junit.Test; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.boot.test.TestRestTemplate; +import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; @@ -14,7 +13,6 @@ /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class ResourceOwnerPasswordProviderTests extends AbstractResourceOwnerPasswordProviderTests { @Test diff --git a/tests/pom.xml b/tests/pom.xml index 4d58bbcb0..234e3141c 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT spring-security-oauth-tests diff --git a/tests/xml/approval/pom.xml b/tests/xml/approval/pom.xml index f66b6a0f6..c8569a5d2 100644 --- a/tests/xml/approval/pom.xml +++ b/tests/xml/approval/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/xml/client/pom.xml b/tests/xml/client/pom.xml index 349d602a2..049f30793 100644 --- a/tests/xml/client/pom.xml +++ b/tests/xml/client/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml index 654689b20..4d15848f3 100644 --- a/tests/xml/common/pom.xml +++ b/tests/xml/common/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/xml/form/pom.xml b/tests/xml/form/pom.xml index e6302c055..37d5a50f7 100644 --- a/tests/xml/form/pom.xml +++ b/tests/xml/form/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/xml/jdbc/pom.xml b/tests/xml/jdbc/pom.xml index e777afb3d..1c130362a 100644 --- a/tests/xml/jdbc/pom.xml +++ b/tests/xml/jdbc/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/xml/jwt/pom.xml b/tests/xml/jwt/pom.xml index 965689999..0275e803f 100644 --- a/tests/xml/jwt/pom.xml +++ b/tests/xml/jwt/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/xml/mappings/pom.xml b/tests/xml/mappings/pom.xml index 84d9a32d9..f55d557c9 100644 --- a/tests/xml/mappings/pom.xml +++ b/tests/xml/mappings/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 421c0c48a..887dca74e 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT pom @@ -33,7 +33,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT jackson-mapper-asl diff --git a/tests/xml/vanilla/pom.xml b/tests/xml/vanilla/pom.xml index f64a2d1f2..abe8c9fa1 100644 --- a/tests/xml/vanilla/pom.xml +++ b/tests/xml/vanilla/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.13.BUILD-SNAPSHOT + 2.1.1.BUILD-SNAPSHOT