diff --git a/aspects/src/test/java/org/springframework/security/access/intercept/aspectj/aspect/AnnotationSecurityAspectTests.java b/aspects/src/test/java/org/springframework/security/access/intercept/aspectj/aspect/AnnotationSecurityAspectTests.java index c8f8fc9802..9a6b63ddc8 100644 --- a/aspects/src/test/java/org/springframework/security/access/intercept/aspectj/aspect/AnnotationSecurityAspectTests.java +++ b/aspects/src/test/java/org/springframework/security/access/intercept/aspectj/aspect/AnnotationSecurityAspectTests.java @@ -161,65 +161,65 @@ public class AnnotationSecurityAspectTests { this.interceptor.setAfterInvocationManager(aim); } -} + interface SecuredInterface { -interface SecuredInterface { + @Secured("ROLE_X") + void securedMethod(); - @Secured("ROLE_X") - void securedMethod(); + } -} + static class SecuredImpl implements SecuredInterface { -class SecuredImpl implements SecuredInterface { + // Not really secured because AspectJ doesn't inherit annotations from interfaces + @Override + public void securedMethod() { + } - // Not really secured because AspectJ doesn't inherit annotations from interfaces - @Override - public void securedMethod() { - } + @Secured("ROLE_A") + public void securedClassMethod() { + } - @Secured("ROLE_A") - public void securedClassMethod() { - } + @Secured("ROLE_X") + private void privateMethod() { + } - @Secured("ROLE_X") - private void privateMethod() { - } + @Secured("ROLE_X") + protected void protectedMethod() { + } - @Secured("ROLE_X") - protected void protectedMethod() { - } + @Secured("ROLE_X") + public void publicCallsPrivate() { + privateMethod(); + } - @Secured("ROLE_X") - public void publicCallsPrivate() { - privateMethod(); } -} + static class SecuredImplSubclass extends SecuredImpl { -class SecuredImplSubclass extends SecuredImpl { + @Override + protected void protectedMethod() { + } - @Override - protected void protectedMethod() { - } + @Override + public void publicCallsPrivate() { + super.publicCallsPrivate(); + } - @Override - public void publicCallsPrivate() { - super.publicCallsPrivate(); } -} + static class PrePostSecured { -class PrePostSecured { + @PreAuthorize("denyAll") + public void denyAllMethod() { + } - @PreAuthorize("denyAll") - public void denyAllMethod() { - } + @PostFilter("filterObject.startsWith('a')") + public List postFilterMethod() { + ArrayList objects = new ArrayList<>(); + objects.addAll(Arrays.asList(new String[] { "apple", "banana", "aubergine", "orange" })); + return objects; + } - @PostFilter("filterObject.startsWith('a')") - public List postFilterMethod() { - ArrayList objects = new ArrayList<>(); - objects.addAll(Arrays.asList(new String[] { "apple", "banana", "aubergine", "orange" })); - return objects; } } diff --git a/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java index 9ffa600d88..c43d1b3903 100644 --- a/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/http/HttpSecurityBeanDefinitionParser.java @@ -42,7 +42,6 @@ import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.core.OrderComparator; -import org.springframework.core.Ordered; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.DefaultAuthenticationEventPublisher; import org.springframework.security.authentication.ProviderManager; @@ -399,97 +398,70 @@ public class HttpSecurityBeanDefinitionParser implements BeanDefinitionParser { registry.registerBeanDefinition(requestRejectedPostProcessorName, requestRejectedBean); } -} - -class RequestRejectedHandlerPostProcessor implements BeanDefinitionRegistryPostProcessor { + static class RequestRejectedHandlerPostProcessor implements BeanDefinitionRegistryPostProcessor { - private final String beanName; + private final String beanName; - private final String targetBeanName; + private final String targetBeanName; - private final String targetPropertyName; + private final String targetPropertyName; - RequestRejectedHandlerPostProcessor(String beanName, String targetBeanName, String targetPropertyName) { - this.beanName = beanName; - this.targetBeanName = targetBeanName; - this.targetPropertyName = targetPropertyName; - } - - @Override - public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { - if (registry.containsBeanDefinition(this.beanName)) { - BeanDefinition beanDefinition = registry.getBeanDefinition(this.targetBeanName); - beanDefinition.getPropertyValues().add(this.targetPropertyName, new RuntimeBeanReference(this.beanName)); + RequestRejectedHandlerPostProcessor(String beanName, String targetBeanName, String targetPropertyName) { + this.beanName = beanName; + this.targetBeanName = targetBeanName; + this.targetPropertyName = targetPropertyName; } - } - - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - - } -} - -class OrderDecorator implements Ordered { - - final BeanMetadataElement bean; - - final int order; - - OrderDecorator(BeanMetadataElement bean, SecurityFilters filterOrder) { - this.bean = bean; - this.order = filterOrder.getOrder(); - } + @Override + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { + if (registry.containsBeanDefinition(this.beanName)) { + BeanDefinition beanDefinition = registry.getBeanDefinition(this.targetBeanName); + beanDefinition.getPropertyValues().add(this.targetPropertyName, + new RuntimeBeanReference(this.beanName)); + } + } - OrderDecorator(BeanMetadataElement bean, int order) { - this.bean = bean; - this.order = order; - } + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - @Override - public int getOrder() { - return this.order; - } + } - @Override - public String toString() { - return this.bean + ", order = " + this.order; } -} + /** + * Custom {@link MethodInvokingFactoryBean} that is specifically used for looking up + * the child {@link ProviderManager} value for + * {@link ProviderManager#setEraseCredentialsAfterAuthentication(boolean)} given the + * parent {@link AuthenticationManager}. This is necessary because the parent + * {@link AuthenticationManager} might not be a {@link ProviderManager}. + * + * @author Rob Winch + */ + static final class ClearCredentialsMethodInvokingFactoryBean extends MethodInvokingFactoryBean { -/** - * Custom {@link MethodInvokingFactoryBean} that is specifically used for looking up the - * child {@link ProviderManager} value for - * {@link ProviderManager#setEraseCredentialsAfterAuthentication(boolean)} given the - * parent {@link AuthenticationManager}. This is necessary because the parent - * {@link AuthenticationManager} might not be a {@link ProviderManager}. - * - * @author Rob Winch - */ -final class ClearCredentialsMethodInvokingFactoryBean extends MethodInvokingFactoryBean { + @Override + public void afterPropertiesSet() throws Exception { + boolean isTargetProviderManager = getTargetObject() instanceof ProviderManager; + if (!isTargetProviderManager) { + setTargetObject(this); + } + super.afterPropertiesSet(); + } - @Override - public void afterPropertiesSet() throws Exception { - boolean isTargetProviderManager = getTargetObject() instanceof ProviderManager; - if (!isTargetProviderManager) { - setTargetObject(this); + /** + * The default value if the target object is not a ProviderManager is false. We + * use false because this feature is associated with {@link ProviderManager} not + * {@link AuthenticationManager}. If the user wants to leverage + * {@link ProviderManager#setEraseCredentialsAfterAuthentication(boolean)} their + * original {@link AuthenticationManager} must be a {@link ProviderManager} (we + * should not magically add this functionality to their implementation since we + * cannot determine if it should be on or off). + * @return + */ + public boolean isEraseCredentialsAfterAuthentication() { + return false; } - super.afterPropertiesSet(); - } - /** - * The default value if the target object is not a ProviderManager is false. We use - * false because this feature is associated with {@link ProviderManager} not - * {@link AuthenticationManager}. If the user wants to leverage - * {@link ProviderManager#setEraseCredentialsAfterAuthentication(boolean)} their - * original {@link AuthenticationManager} must be a {@link ProviderManager} (we should - * not magically add this functionality to their implementation since we cannot - * determine if it should be on or off). - * @return - */ - public boolean isEraseCredentialsAfterAuthentication() { - return false; } } diff --git a/config/src/main/java/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParser.java b/config/src/main/java/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParser.java index ef79bc4c64..5c7358ab73 100644 --- a/config/src/main/java/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParser.java +++ b/config/src/main/java/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParser.java @@ -196,177 +196,178 @@ final class OAuth2ResourceServerBeanDefinitionParser implements BeanDefinitionPa } } -} - -final class JwtBeanDefinitionParser implements BeanDefinitionParser { + static final class JwtBeanDefinitionParser implements BeanDefinitionParser { - static final String DECODER_REF = "decoder-ref"; - static final String JWK_SET_URI = "jwk-set-uri"; - static final String JWT_AUTHENTICATION_CONVERTER_REF = "jwt-authentication-converter-ref"; - static final String JWT_AUTHENTICATION_CONVERTER = "jwtAuthenticationConverter"; + static final String DECODER_REF = "decoder-ref"; + static final String JWK_SET_URI = "jwk-set-uri"; + static final String JWT_AUTHENTICATION_CONVERTER_REF = "jwt-authentication-converter-ref"; + static final String JWT_AUTHENTICATION_CONVERTER = "jwtAuthenticationConverter"; - @Override - public BeanDefinition parse(Element element, ParserContext pc) { - validateConfiguration(element, pc); + @Override + public BeanDefinition parse(Element element, ParserContext pc) { + validateConfiguration(element, pc); - BeanDefinitionBuilder jwtProviderBuilder = BeanDefinitionBuilder - .rootBeanDefinition(JwtAuthenticationProvider.class); - jwtProviderBuilder.addConstructorArgValue(getDecoder(element)); - jwtProviderBuilder.addPropertyValue(JWT_AUTHENTICATION_CONVERTER, getJwtAuthenticationConverter(element)); + BeanDefinitionBuilder jwtProviderBuilder = BeanDefinitionBuilder + .rootBeanDefinition(JwtAuthenticationProvider.class); + jwtProviderBuilder.addConstructorArgValue(getDecoder(element)); + jwtProviderBuilder.addPropertyValue(JWT_AUTHENTICATION_CONVERTER, getJwtAuthenticationConverter(element)); - return jwtProviderBuilder.getBeanDefinition(); - } + return jwtProviderBuilder.getBeanDefinition(); + } - void validateConfiguration(Element element, ParserContext pc) { - boolean usesDecoder = element.hasAttribute(DECODER_REF); - boolean usesJwkSetUri = element.hasAttribute(JWK_SET_URI); + void validateConfiguration(Element element, ParserContext pc) { + boolean usesDecoder = element.hasAttribute(DECODER_REF); + boolean usesJwkSetUri = element.hasAttribute(JWK_SET_URI); - if (usesDecoder == usesJwkSetUri) { - pc.getReaderContext().error("Please specify either decoder-ref or jwk-set-uri.", element); + if (usesDecoder == usesJwkSetUri) { + pc.getReaderContext().error("Please specify either decoder-ref or jwk-set-uri.", element); + } } - } - Object getDecoder(Element element) { - String decoderRef = element.getAttribute(DECODER_REF); - if (!StringUtils.isEmpty(decoderRef)) { - return new RuntimeBeanReference(decoderRef); + Object getDecoder(Element element) { + String decoderRef = element.getAttribute(DECODER_REF); + if (!StringUtils.isEmpty(decoderRef)) { + return new RuntimeBeanReference(decoderRef); + } + + BeanDefinitionBuilder builder = BeanDefinitionBuilder + .rootBeanDefinition(NimbusJwtDecoderJwkSetUriFactoryBean.class); + builder.addConstructorArgValue(element.getAttribute(JWK_SET_URI)); + return builder.getBeanDefinition(); } - BeanDefinitionBuilder builder = BeanDefinitionBuilder - .rootBeanDefinition(NimbusJwtDecoderJwkSetUriFactoryBean.class); - builder.addConstructorArgValue(element.getAttribute(JWK_SET_URI)); - return builder.getBeanDefinition(); - } + Object getJwtAuthenticationConverter(Element element) { + String jwtDecoderRef = element.getAttribute(JWT_AUTHENTICATION_CONVERTER_REF); + if (!StringUtils.isEmpty(jwtDecoderRef)) { + return new RuntimeBeanReference(jwtDecoderRef); + } - Object getJwtAuthenticationConverter(Element element) { - String jwtDecoderRef = element.getAttribute(JWT_AUTHENTICATION_CONVERTER_REF); - if (!StringUtils.isEmpty(jwtDecoderRef)) { - return new RuntimeBeanReference(jwtDecoderRef); + return new JwtAuthenticationConverter(); } - return new JwtAuthenticationConverter(); - } + JwtBeanDefinitionParser() { + } - JwtBeanDefinitionParser() { } -} + static final class OpaqueTokenBeanDefinitionParser implements BeanDefinitionParser { -final class OpaqueTokenBeanDefinitionParser implements BeanDefinitionParser { + static final String INTROSPECTOR_REF = "introspector-ref"; + static final String INTROSPECTION_URI = "introspection-uri"; + static final String CLIENT_ID = "client-id"; + static final String CLIENT_SECRET = "client-secret"; - static final String INTROSPECTOR_REF = "introspector-ref"; - static final String INTROSPECTION_URI = "introspection-uri"; - static final String CLIENT_ID = "client-id"; - static final String CLIENT_SECRET = "client-secret"; + @Override + public BeanDefinition parse(Element element, ParserContext pc) { + validateConfiguration(element, pc); - @Override - public BeanDefinition parse(Element element, ParserContext pc) { - validateConfiguration(element, pc); + BeanMetadataElement introspector = getIntrospector(element); + BeanDefinitionBuilder opaqueTokenProviderBuilder = BeanDefinitionBuilder + .rootBeanDefinition(OpaqueTokenAuthenticationProvider.class); + opaqueTokenProviderBuilder.addConstructorArgValue(introspector); - BeanMetadataElement introspector = getIntrospector(element); - BeanDefinitionBuilder opaqueTokenProviderBuilder = BeanDefinitionBuilder - .rootBeanDefinition(OpaqueTokenAuthenticationProvider.class); - opaqueTokenProviderBuilder.addConstructorArgValue(introspector); + return opaqueTokenProviderBuilder.getBeanDefinition(); + } - return opaqueTokenProviderBuilder.getBeanDefinition(); - } + void validateConfiguration(Element element, ParserContext pc) { + boolean usesIntrospector = element.hasAttribute(INTROSPECTOR_REF); + boolean usesEndpoint = element.hasAttribute(INTROSPECTION_URI) || element.hasAttribute(CLIENT_ID) + || element.hasAttribute(CLIENT_SECRET); - void validateConfiguration(Element element, ParserContext pc) { - boolean usesIntrospector = element.hasAttribute(INTROSPECTOR_REF); - boolean usesEndpoint = element.hasAttribute(INTROSPECTION_URI) || element.hasAttribute(CLIENT_ID) - || element.hasAttribute(CLIENT_SECRET); + if (usesIntrospector == usesEndpoint) { + pc.getReaderContext().error("Please specify either introspector-ref or all of " + + "introspection-uri, client-id, and client-secret.", element); + return; + } - if (usesIntrospector == usesEndpoint) { - pc.getReaderContext().error("Please specify either introspector-ref or all of " - + "introspection-uri, client-id, and client-secret.", element); - return; + if (usesEndpoint) { + if (!(element.hasAttribute(INTROSPECTION_URI) && element.hasAttribute(CLIENT_ID) + && element.hasAttribute(CLIENT_SECRET))) { + pc.getReaderContext() + .error("Please specify introspection-uri, client-id, and client-secret together", element); + } + } } - if (usesEndpoint) { - if (!(element.hasAttribute(INTROSPECTION_URI) && element.hasAttribute(CLIENT_ID) - && element.hasAttribute(CLIENT_SECRET))) { - pc.getReaderContext().error("Please specify introspection-uri, client-id, and client-secret together", - element); + BeanMetadataElement getIntrospector(Element element) { + String introspectorRef = element.getAttribute(INTROSPECTOR_REF); + if (!StringUtils.isEmpty(introspectorRef)) { + return new RuntimeBeanReference(introspectorRef); } - } - } - BeanMetadataElement getIntrospector(Element element) { - String introspectorRef = element.getAttribute(INTROSPECTOR_REF); - if (!StringUtils.isEmpty(introspectorRef)) { - return new RuntimeBeanReference(introspectorRef); - } + String introspectionUri = element.getAttribute(INTROSPECTION_URI); + String clientId = element.getAttribute(CLIENT_ID); + String clientSecret = element.getAttribute(CLIENT_SECRET); - String introspectionUri = element.getAttribute(INTROSPECTION_URI); - String clientId = element.getAttribute(CLIENT_ID); - String clientSecret = element.getAttribute(CLIENT_SECRET); + BeanDefinitionBuilder introspectorBuilder = BeanDefinitionBuilder + .rootBeanDefinition(NimbusOpaqueTokenIntrospector.class); + introspectorBuilder.addConstructorArgValue(introspectionUri); + introspectorBuilder.addConstructorArgValue(clientId); + introspectorBuilder.addConstructorArgValue(clientSecret); - BeanDefinitionBuilder introspectorBuilder = BeanDefinitionBuilder - .rootBeanDefinition(NimbusOpaqueTokenIntrospector.class); - introspectorBuilder.addConstructorArgValue(introspectionUri); - introspectorBuilder.addConstructorArgValue(clientId); - introspectorBuilder.addConstructorArgValue(clientSecret); + return introspectorBuilder.getBeanDefinition(); + } - return introspectorBuilder.getBeanDefinition(); - } + OpaqueTokenBeanDefinitionParser() { + } - OpaqueTokenBeanDefinitionParser() { } -} + static final class StaticAuthenticationManagerResolver + implements AuthenticationManagerResolver { -final class StaticAuthenticationManagerResolver implements AuthenticationManagerResolver { + private final AuthenticationManager authenticationManager; - private final AuthenticationManager authenticationManager; + StaticAuthenticationManagerResolver(AuthenticationManager authenticationManager) { + this.authenticationManager = authenticationManager; + } - StaticAuthenticationManagerResolver(AuthenticationManager authenticationManager) { - this.authenticationManager = authenticationManager; - } + @Override + public AuthenticationManager resolve(HttpServletRequest context) { + return this.authenticationManager; + } - @Override - public AuthenticationManager resolve(HttpServletRequest context) { - return this.authenticationManager; } -} + static final class NimbusJwtDecoderJwkSetUriFactoryBean implements FactoryBean { -final class NimbusJwtDecoderJwkSetUriFactoryBean implements FactoryBean { + private final String jwkSetUri; - private final String jwkSetUri; + NimbusJwtDecoderJwkSetUriFactoryBean(String jwkSetUri) { + this.jwkSetUri = jwkSetUri; + } - NimbusJwtDecoderJwkSetUriFactoryBean(String jwkSetUri) { - this.jwkSetUri = jwkSetUri; - } + @Override + public JwtDecoder getObject() { + return NimbusJwtDecoder.withJwkSetUri(this.jwkSetUri).build(); + } - @Override - public JwtDecoder getObject() { - return NimbusJwtDecoder.withJwkSetUri(this.jwkSetUri).build(); - } + @Override + public Class getObjectType() { + return JwtDecoder.class; + } - @Override - public Class getObjectType() { - return JwtDecoder.class; } -} - -final class BearerTokenRequestMatcher implements RequestMatcher { - - private final BearerTokenResolver bearerTokenResolver; + static final class BearerTokenRequestMatcher implements RequestMatcher { - BearerTokenRequestMatcher(BearerTokenResolver bearerTokenResolver) { - Assert.notNull(bearerTokenResolver, "bearerTokenResolver cannot be null"); - this.bearerTokenResolver = bearerTokenResolver; - } + private final BearerTokenResolver bearerTokenResolver; - @Override - public boolean matches(HttpServletRequest request) { - try { - return this.bearerTokenResolver.resolve(request) != null; + BearerTokenRequestMatcher(BearerTokenResolver bearerTokenResolver) { + Assert.notNull(bearerTokenResolver, "bearerTokenResolver cannot be null"); + this.bearerTokenResolver = bearerTokenResolver; } - catch (OAuth2AuthenticationException e) { - return false; + + @Override + public boolean matches(HttpServletRequest request) { + try { + return this.bearerTokenResolver.resolve(request) != null; + } + catch (OAuth2AuthenticationException e) { + return false; + } } + } } diff --git a/config/src/main/java/org/springframework/security/config/http/OrderDecorator.java b/config/src/main/java/org/springframework/security/config/http/OrderDecorator.java new file mode 100644 index 0000000000..3b14abaf8d --- /dev/null +++ b/config/src/main/java/org/springframework/security/config/http/OrderDecorator.java @@ -0,0 +1,53 @@ +/* + * Copyright 2020 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 + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the 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.config.http; + +import org.springframework.beans.BeanMetadataElement; +import org.springframework.core.Ordered; + +/** + * Wrapper to provide ordering to a {@link BeanMetadataElement}. + * + * @author Rob Winch + */ +class OrderDecorator implements Ordered { + + final BeanMetadataElement bean; + + final int order; + + OrderDecorator(BeanMetadataElement bean, SecurityFilters filterOrder) { + this.bean = bean; + this.order = filterOrder.getOrder(); + } + + OrderDecorator(BeanMetadataElement bean, int order) { + this.bean = bean; + this.order = order; + } + + @Override + public int getOrder() { + return this.order; + } + + @Override + public String toString() { + return this.bean + ", order = " + this.order; + } + +} diff --git a/config/src/main/java/org/springframework/security/config/method/InterceptMethodsBeanDefinitionDecorator.java b/config/src/main/java/org/springframework/security/config/method/InterceptMethodsBeanDefinitionDecorator.java index 3d7fcb0223..9c24b37c15 100644 --- a/config/src/main/java/org/springframework/security/config/method/InterceptMethodsBeanDefinitionDecorator.java +++ b/config/src/main/java/org/springframework/security/config/method/InterceptMethodsBeanDefinitionDecorator.java @@ -55,66 +55,69 @@ public class InterceptMethodsBeanDefinitionDecorator implements BeanDefinitionDe return this.delegate.decorate(node, definition, parserContext); } -} + /** + * This is the real class which does the work. We need access to the ParserContext in + * order to do bean registration. + */ + static class InternalInterceptMethodsBeanDefinitionDecorator + extends AbstractInterceptorDrivenBeanDefinitionDecorator { -/** - * This is the real class which does the work. We need access to the ParserContext in - * order to do bean registration. - */ -class InternalInterceptMethodsBeanDefinitionDecorator extends AbstractInterceptorDrivenBeanDefinitionDecorator { + static final String ATT_METHOD = "method"; + static final String ATT_ACCESS = "access"; - static final String ATT_METHOD = "method"; - static final String ATT_ACCESS = "access"; + private static final String ATT_ACCESS_MGR = "access-decision-manager-ref"; - private static final String ATT_ACCESS_MGR = "access-decision-manager-ref"; - - @Override - protected BeanDefinition createInterceptorDefinition(Node node) { - Element interceptMethodsElt = (Element) node; - BeanDefinitionBuilder interceptor = BeanDefinitionBuilder.rootBeanDefinition(MethodSecurityInterceptor.class); + @Override + protected BeanDefinition createInterceptorDefinition(Node node) { + Element interceptMethodsElt = (Element) node; + BeanDefinitionBuilder interceptor = BeanDefinitionBuilder + .rootBeanDefinition(MethodSecurityInterceptor.class); - // Default to autowiring to pick up after invocation mgr - interceptor.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE); + // Default to autowiring to pick up after invocation mgr + interceptor.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE); - String accessManagerId = interceptMethodsElt.getAttribute(ATT_ACCESS_MGR); + String accessManagerId = interceptMethodsElt.getAttribute(ATT_ACCESS_MGR); - if (!StringUtils.hasText(accessManagerId)) { - accessManagerId = BeanIds.METHOD_ACCESS_MANAGER; - } + if (!StringUtils.hasText(accessManagerId)) { + accessManagerId = BeanIds.METHOD_ACCESS_MANAGER; + } - interceptor.addPropertyValue("accessDecisionManager", new RuntimeBeanReference(accessManagerId)); - interceptor.addPropertyValue("authenticationManager", new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER)); + interceptor.addPropertyValue("accessDecisionManager", new RuntimeBeanReference(accessManagerId)); + interceptor.addPropertyValue("authenticationManager", + new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER)); - // Lookup parent bean information + // Lookup parent bean information - String parentBeanClass = ((Element) node.getParentNode()).getAttribute("class"); + String parentBeanClass = ((Element) node.getParentNode()).getAttribute("class"); - // Parse the included methods - List methods = DomUtils.getChildElementsByTagName(interceptMethodsElt, Elements.PROTECT); - Map mappings = new ManagedMap<>(); + // Parse the included methods + List methods = DomUtils.getChildElementsByTagName(interceptMethodsElt, Elements.PROTECT); + Map mappings = new ManagedMap<>(); - for (Element protectmethodElt : methods) { - BeanDefinitionBuilder attributeBuilder = BeanDefinitionBuilder.rootBeanDefinition(SecurityConfig.class); - attributeBuilder.setFactoryMethod("createListFromCommaDelimitedString"); - attributeBuilder.addConstructorArgValue(protectmethodElt.getAttribute(ATT_ACCESS)); + for (Element protectmethodElt : methods) { + BeanDefinitionBuilder attributeBuilder = BeanDefinitionBuilder.rootBeanDefinition(SecurityConfig.class); + attributeBuilder.setFactoryMethod("createListFromCommaDelimitedString"); + attributeBuilder.addConstructorArgValue(protectmethodElt.getAttribute(ATT_ACCESS)); - // Support inference of class names - String methodName = protectmethodElt.getAttribute(ATT_METHOD); + // Support inference of class names + String methodName = protectmethodElt.getAttribute(ATT_METHOD); - if (methodName.lastIndexOf(".") == -1) { - if (parentBeanClass != null && !"".equals(parentBeanClass)) { - methodName = parentBeanClass + "." + methodName; + if (methodName.lastIndexOf(".") == -1) { + if (parentBeanClass != null && !"".equals(parentBeanClass)) { + methodName = parentBeanClass + "." + methodName; + } } + + mappings.put(methodName, attributeBuilder.getBeanDefinition()); } - mappings.put(methodName, attributeBuilder.getBeanDefinition()); - } + BeanDefinition metadataSource = new RootBeanDefinition(MapBasedMethodSecurityMetadataSource.class); + metadataSource.getConstructorArgumentValues().addGenericArgumentValue(mappings); + interceptor.addPropertyValue("securityMetadataSource", metadataSource); - BeanDefinition metadataSource = new RootBeanDefinition(MapBasedMethodSecurityMetadataSource.class); - metadataSource.getConstructorArgumentValues().addGenericArgumentValue(mappings); - interceptor.addPropertyValue("securityMetadataSource", metadataSource); + return interceptor.getBeanDefinition(); + } - return interceptor.getBeanDefinition(); } } diff --git a/config/src/test/java/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParserTests.java b/config/src/test/java/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParserTests.java index 66e957d0a7..c753c8d1a6 100644 --- a/config/src/test/java/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParserTests.java +++ b/config/src/test/java/org/springframework/security/config/http/OAuth2ResourceServerBeanDefinitionParserTests.java @@ -68,6 +68,8 @@ import org.springframework.http.MediaType; import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.AuthenticationManagerResolver; +import org.springframework.security.config.http.OAuth2ResourceServerBeanDefinitionParser.JwtBeanDefinitionParser; +import org.springframework.security.config.http.OAuth2ResourceServerBeanDefinitionParser.OpaqueTokenBeanDefinitionParser; import org.springframework.security.config.test.SpringTestRule; import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.OAuth2TokenValidator; @@ -103,11 +105,11 @@ import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.powermock.api.mockito.PowerMockito.when; -import static org.springframework.security.config.http.JwtBeanDefinitionParser.DECODER_REF; -import static org.springframework.security.config.http.JwtBeanDefinitionParser.JWK_SET_URI; import static org.springframework.security.config.http.OAuth2ResourceServerBeanDefinitionParser.AUTHENTICATION_MANAGER_RESOLVER_REF; -import static org.springframework.security.config.http.OpaqueTokenBeanDefinitionParser.INTROSPECTION_URI; -import static org.springframework.security.config.http.OpaqueTokenBeanDefinitionParser.INTROSPECTOR_REF; +import static org.springframework.security.config.http.OAuth2ResourceServerBeanDefinitionParser.JwtBeanDefinitionParser.DECODER_REF; +import static org.springframework.security.config.http.OAuth2ResourceServerBeanDefinitionParser.JwtBeanDefinitionParser.JWK_SET_URI; +import static org.springframework.security.config.http.OAuth2ResourceServerBeanDefinitionParser.OpaqueTokenBeanDefinitionParser.INTROSPECTION_URI; +import static org.springframework.security.config.http.OAuth2ResourceServerBeanDefinitionParser.OpaqueTokenBeanDefinitionParser.INTROSPECTOR_REF; import static org.springframework.security.oauth2.jwt.JwtClaimNames.ISS; import static org.springframework.security.oauth2.jwt.JwtClaimNames.SUB; import static org.springframework.security.oauth2.jwt.TestJwts.jwt; diff --git a/core/src/main/java/org/springframework/security/access/annotation/SecuredAnnotationSecurityMetadataSource.java b/core/src/main/java/org/springframework/security/access/annotation/SecuredAnnotationSecurityMetadataSource.java index ab6fc143b7..903e91b4a2 100644 --- a/core/src/main/java/org/springframework/security/access/annotation/SecuredAnnotationSecurityMetadataSource.java +++ b/core/src/main/java/org/springframework/security/access/annotation/SecuredAnnotationSecurityMetadataSource.java @@ -82,20 +82,20 @@ public class SecuredAnnotationSecurityMetadataSource extends AbstractFallbackMet return this.annotationExtractor.extractAttributes(a); } -} + static class SecuredAnnotationMetadataExtractor implements AnnotationMetadataExtractor { -class SecuredAnnotationMetadataExtractor implements AnnotationMetadataExtractor { + @Override + public Collection extractAttributes(Secured secured) { + String[] attributeTokens = secured.value(); + List attributes = new ArrayList<>(attributeTokens.length); - @Override - public Collection extractAttributes(Secured secured) { - String[] attributeTokens = secured.value(); - List attributes = new ArrayList<>(attributeTokens.length); + for (String token : attributeTokens) { + attributes.add(new SecurityConfig(token)); + } - for (String token : attributeTokens) { - attributes.add(new SecurityConfig(token)); + return attributes; } - return attributes; } } diff --git a/core/src/test/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandlerTests.java b/core/src/test/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandlerTests.java index 259474e668..9d20cc5efa 100644 --- a/core/src/test/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandlerTests.java +++ b/core/src/test/java/org/springframework/security/access/expression/AbstractSecurityExpressionHandlerTests.java @@ -69,19 +69,19 @@ public class AbstractSecurityExpressionHandlerTests { assertThat(parser == this.handler.getExpressionParser()).isTrue(); } -} + @Configuration + static class TestConfiguration { -@Configuration -class TestConfiguration { + @Bean + Integer number10() { + return 10; + } - @Bean - Integer number10() { - return 10; - } + @Bean + Integer number20() { + return 20; + } - @Bean - Integer number20() { - return 20; } } diff --git a/core/src/test/java/org/springframework/security/util/FieldUtilsTests.java b/core/src/test/java/org/springframework/security/util/FieldUtilsTests.java index bf5fe9e788..c2b84381ae 100644 --- a/core/src/test/java/org/springframework/security/util/FieldUtilsTests.java +++ b/core/src/test/java/org/springframework/security/util/FieldUtilsTests.java @@ -42,20 +42,20 @@ public class FieldUtilsTests { } } -} + @SuppressWarnings("unused") + static class TestClass { -@SuppressWarnings("unused") -class TestClass { + private String protectedField = "x"; - private String protectedField = "x"; + private Nested nested = new Nested(); - private Nested nested = new Nested(); + } -} + @SuppressWarnings("unused") + static class Nested { -@SuppressWarnings("unused") -class Nested { + private String protectedField = "z"; - private String protectedField = "z"; + } } diff --git a/crypto/src/main/java/org/springframework/security/crypto/codec/Base64.java b/crypto/src/main/java/org/springframework/security/crypto/codec/Base64.java index f03951f696..b29021dc07 100644 --- a/crypto/src/main/java/org/springframework/security/crypto/codec/Base64.java +++ b/crypto/src/main/java/org/springframework/security/crypto/codec/Base64.java @@ -611,12 +611,12 @@ public final class Base64 { return out; } -} + static class InvalidBase64CharacterException extends IllegalArgumentException { -class InvalidBase64CharacterException extends IllegalArgumentException { + InvalidBase64CharacterException(String message) { + super(message); + } - InvalidBase64CharacterException(String message) { - super(message); } } diff --git a/etc/checkstyle/checkstyle-suppressions.xml b/etc/checkstyle/checkstyle-suppressions.xml index cfa6522e24..0f0f43aa9d 100644 --- a/etc/checkstyle/checkstyle-suppressions.xml +++ b/etc/checkstyle/checkstyle-suppressions.xml @@ -3,7 +3,6 @@ "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN" "https://checkstyle.org/dtds/suppressions_1_2.dtd"> - diff --git a/web/src/main/java/org/springframework/security/web/FilterInvocation.java b/web/src/main/java/org/springframework/security/web/FilterInvocation.java index 160884f2fd..56037c47ac 100644 --- a/web/src/main/java/org/springframework/security/web/FilterInvocation.java +++ b/web/src/main/java/org/springframework/security/web/FilterInvocation.java @@ -140,193 +140,193 @@ public class FilterInvocation { return "FilterInvocation: URL: " + getRequestUrl(); } -} - -class DummyRequest extends HttpServletRequestWrapper { + static class DummyRequest extends HttpServletRequestWrapper { - private static final HttpServletRequest UNSUPPORTED_REQUEST = (HttpServletRequest) Proxy.newProxyInstance( - DummyRequest.class.getClassLoader(), new Class[] { HttpServletRequest.class }, - new UnsupportedOperationExceptionInvocationHandler()); + private static final HttpServletRequest UNSUPPORTED_REQUEST = (HttpServletRequest) Proxy.newProxyInstance( + DummyRequest.class.getClassLoader(), new Class[] { HttpServletRequest.class }, + new UnsupportedOperationExceptionInvocationHandler()); - private String requestURI; + private String requestURI; - private String contextPath = ""; + private String contextPath = ""; - private String servletPath; + private String servletPath; - private String pathInfo; + private String pathInfo; - private String queryString; + private String queryString; - private String method; + private String method; - private final HttpHeaders headers = new HttpHeaders(); + private final HttpHeaders headers = new HttpHeaders(); - private final Map parameters = new LinkedHashMap<>(); + private final Map parameters = new LinkedHashMap<>(); - DummyRequest() { - super(UNSUPPORTED_REQUEST); - } + DummyRequest() { + super(UNSUPPORTED_REQUEST); + } - @Override - public String getCharacterEncoding() { - return "UTF-8"; - } + @Override + public String getCharacterEncoding() { + return "UTF-8"; + } - @Override - public Object getAttribute(String attributeName) { - return null; - } + @Override + public Object getAttribute(String attributeName) { + return null; + } - public void setRequestURI(String requestURI) { - this.requestURI = requestURI; - } + public void setRequestURI(String requestURI) { + this.requestURI = requestURI; + } - public void setPathInfo(String pathInfo) { - this.pathInfo = pathInfo; - } + public void setPathInfo(String pathInfo) { + this.pathInfo = pathInfo; + } - @Override - public String getRequestURI() { - return this.requestURI; - } + @Override + public String getRequestURI() { + return this.requestURI; + } - public void setContextPath(String contextPath) { - this.contextPath = contextPath; - } + public void setContextPath(String contextPath) { + this.contextPath = contextPath; + } - @Override - public String getContextPath() { - return this.contextPath; - } + @Override + public String getContextPath() { + return this.contextPath; + } - public void setServletPath(String servletPath) { - this.servletPath = servletPath; - } + public void setServletPath(String servletPath) { + this.servletPath = servletPath; + } - @Override - public String getServletPath() { - return this.servletPath; - } + @Override + public String getServletPath() { + return this.servletPath; + } - public void setMethod(String method) { - this.method = method; - } + public void setMethod(String method) { + this.method = method; + } - @Override - public String getMethod() { - return this.method; - } + @Override + public String getMethod() { + return this.method; + } - @Override - public String getPathInfo() { - return this.pathInfo; - } + @Override + public String getPathInfo() { + return this.pathInfo; + } - @Override - public String getQueryString() { - return this.queryString; - } + @Override + public String getQueryString() { + return this.queryString; + } - public void setQueryString(String queryString) { - this.queryString = queryString; - } + public void setQueryString(String queryString) { + this.queryString = queryString; + } - @Override - public String getServerName() { - return null; - } + @Override + public String getServerName() { + return null; + } - @Override - public String getHeader(String name) { - return this.headers.getFirst(name); - } + @Override + public String getHeader(String name) { + return this.headers.getFirst(name); + } - @Override - public Enumeration getHeaders(String name) { - return Collections.enumeration(this.headers.get(name)); - } + @Override + public Enumeration getHeaders(String name) { + return Collections.enumeration(this.headers.get(name)); + } - @Override - public Enumeration getHeaderNames() { - return Collections.enumeration(this.headers.keySet()); - } + @Override + public Enumeration getHeaderNames() { + return Collections.enumeration(this.headers.keySet()); + } - @Override - public int getIntHeader(String name) { - String value = this.headers.getFirst(name); - if (value == null) { - return -1; + @Override + public int getIntHeader(String name) { + String value = this.headers.getFirst(name); + if (value == null) { + return -1; + } + else { + return Integer.parseInt(value); + } } - else { - return Integer.parseInt(value); + + public void addHeader(String name, String value) { + this.headers.add(name, value); } - } - public void addHeader(String name, String value) { - this.headers.add(name, value); - } + @Override + public String getParameter(String name) { + String[] arr = this.parameters.get(name); + return (arr != null && arr.length > 0 ? arr[0] : null); + } - @Override - public String getParameter(String name) { - String[] arr = this.parameters.get(name); - return (arr != null && arr.length > 0 ? arr[0] : null); - } + @Override + public Map getParameterMap() { + return Collections.unmodifiableMap(this.parameters); + } - @Override - public Map getParameterMap() { - return Collections.unmodifiableMap(this.parameters); - } + @Override + public Enumeration getParameterNames() { + return Collections.enumeration(this.parameters.keySet()); + } - @Override - public Enumeration getParameterNames() { - return Collections.enumeration(this.parameters.keySet()); - } + @Override + public String[] getParameterValues(String name) { + return this.parameters.get(name); + } - @Override - public String[] getParameterValues(String name) { - return this.parameters.get(name); - } + public void setParameter(String name, String... values) { + this.parameters.put(name, values); + } - public void setParameter(String name, String... values) { - this.parameters.put(name, values); } -} - -final class UnsupportedOperationExceptionInvocationHandler implements InvocationHandler { + static final class UnsupportedOperationExceptionInvocationHandler implements InvocationHandler { - private static final float JAVA_VERSION = Float.parseFloat(System.getProperty("java.class.version", "52")); + private static final float JAVA_VERSION = Float.parseFloat(System.getProperty("java.class.version", "52")); - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - if (method.isDefault()) { - return invokeDefaultMethod(proxy, method, args); + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if (method.isDefault()) { + return invokeDefaultMethod(proxy, method, args); + } + throw new UnsupportedOperationException(method + " is not supported"); } - throw new UnsupportedOperationException(method + " is not supported"); - } - private Object invokeDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable { - if (isJdk8OrEarlier()) { - return invokeDefaultMethodForJdk8(proxy, method, args); + private Object invokeDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable { + if (isJdk8OrEarlier()) { + return invokeDefaultMethodForJdk8(proxy, method, args); + } + return MethodHandles.lookup() + .findSpecial(method.getDeclaringClass(), method.getName(), + MethodType.methodType(method.getReturnType(), new Class[0]), method.getDeclaringClass()) + .bindTo(proxy).invokeWithArguments(args); } - return MethodHandles.lookup() - .findSpecial(method.getDeclaringClass(), method.getName(), - MethodType.methodType(method.getReturnType(), new Class[0]), method.getDeclaringClass()) - .bindTo(proxy).invokeWithArguments(args); - } - private Object invokeDefaultMethodForJdk8(Object proxy, Method method, Object[] args) throws Throwable { - Constructor constructor = Lookup.class.getDeclaredConstructor(Class.class); - constructor.setAccessible(true); + private Object invokeDefaultMethodForJdk8(Object proxy, Method method, Object[] args) throws Throwable { + Constructor constructor = Lookup.class.getDeclaredConstructor(Class.class); + constructor.setAccessible(true); - Class clazz = method.getDeclaringClass(); - return constructor.newInstance(clazz).in(clazz).unreflectSpecial(method, clazz).bindTo(proxy) - .invokeWithArguments(args); - } + Class clazz = method.getDeclaringClass(); + return constructor.newInstance(clazz).in(clazz).unreflectSpecial(method, clazz).bindTo(proxy) + .invokeWithArguments(args); + } + + private boolean isJdk8OrEarlier() { + return JAVA_VERSION <= 52; + } - private boolean isJdk8OrEarlier() { - return JAVA_VERSION <= 52; } } diff --git a/web/src/main/java/org/springframework/security/web/debug/DebugFilter.java b/web/src/main/java/org/springframework/security/web/debug/DebugFilter.java index 7f2fbfc872..174b66a175 100644 --- a/web/src/main/java/org/springframework/security/web/debug/DebugFilter.java +++ b/web/src/main/java/org/springframework/security/web/debug/DebugFilter.java @@ -150,34 +150,34 @@ public final class DebugFilter implements Filter { public void destroy() { } -} + static class DebugRequestWrapper extends HttpServletRequestWrapper { -class DebugRequestWrapper extends HttpServletRequestWrapper { + private static final Logger logger = new Logger(); - private static final Logger logger = new Logger(); + DebugRequestWrapper(HttpServletRequest request) { + super(request); + } - DebugRequestWrapper(HttpServletRequest request) { - super(request); - } + @Override + public HttpSession getSession() { + boolean sessionExists = super.getSession(false) != null; + HttpSession session = super.getSession(); - @Override - public HttpSession getSession() { - boolean sessionExists = super.getSession(false) != null; - HttpSession session = super.getSession(); + if (!sessionExists) { + DebugRequestWrapper.logger.info("New HTTP session created: " + session.getId(), true); + } - if (!sessionExists) { - logger.info("New HTTP session created: " + session.getId(), true); + return session; } - return session; - } - - @Override - public HttpSession getSession(boolean create) { - if (!create) { - return super.getSession(create); + @Override + public HttpSession getSession(boolean create) { + if (!create) { + return super.getSession(create); + } + return getSession(); } - return getSession(); + } } diff --git a/web/src/test/java/org/springframework/security/web/FilterInvocationTests.java b/web/src/test/java/org/springframework/security/web/FilterInvocationTests.java index 1a01b9ddf6..046d52fb7b 100644 --- a/web/src/test/java/org/springframework/security/web/FilterInvocationTests.java +++ b/web/src/test/java/org/springframework/security/web/FilterInvocationTests.java @@ -24,6 +24,7 @@ import org.junit.Test; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.security.web.FilterInvocation.DummyRequest; import org.springframework.security.web.util.UrlUtils; import static org.assertj.core.api.Assertions.assertThat; diff --git a/web/src/test/java/org/springframework/security/web/debug/DebugFilterTests.java b/web/src/test/java/org/springframework/security/web/debug/DebugFilterTests.java index f75efc8e0e..2d0cf0248e 100644 --- a/web/src/test/java/org/springframework/security/web/debug/DebugFilterTests.java +++ b/web/src/test/java/org/springframework/security/web/debug/DebugFilterTests.java @@ -33,6 +33,7 @@ import org.powermock.modules.junit4.PowerMockRunner; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.security.web.FilterChainProxy; +import org.springframework.security.web.debug.DebugFilter.DebugRequestWrapper; import org.springframework.test.util.ReflectionTestUtils; import static org.assertj.core.api.Assertions.assertThat;