Ensure classes are defined in their own files

Ensure that all classes are defined in their own files. Mostly classes
have been changed to inner-types.

Issue gh-8945
This commit is contained in:
Phillip Webb 2020-07-27 11:28:04 -07:00 committed by Rob Winch
parent 053af720a4
commit f1cee9500f
15 changed files with 599 additions and 567 deletions

View File

@ -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();
}
class SecuredImpl implements SecuredInterface {
// Not really secured because AspectJ doesn't inherit annotations from interfaces
@Override
public void securedMethod() {
}
@Secured("ROLE_A")
public void securedClassMethod() {
static class SecuredImpl implements SecuredInterface {
// Not really secured because AspectJ doesn't inherit annotations from interfaces
@Override
public void securedMethod() {
}
@Secured("ROLE_A")
public void securedClassMethod() {
}
@Secured("ROLE_X")
private void privateMethod() {
}
@Secured("ROLE_X")
protected void protectedMethod() {
}
@Secured("ROLE_X")
public void publicCallsPrivate() {
privateMethod();
}
}
@Secured("ROLE_X")
private void privateMethod() {
static class SecuredImplSubclass extends SecuredImpl {
@Override
protected void protectedMethod() {
}
@Override
public void publicCallsPrivate() {
super.publicCallsPrivate();
}
}
@Secured("ROLE_X")
protected void protectedMethod() {
}
static class PrePostSecured {
@PreAuthorize("denyAll")
public void denyAllMethod() {
}
@PostFilter("filterObject.startsWith('a')")
public List<String> postFilterMethod() {
ArrayList<String> objects = new ArrayList<>();
objects.addAll(Arrays.asList(new String[] { "apple", "banana", "aubergine", "orange" }));
return objects;
}
@Secured("ROLE_X")
public void publicCallsPrivate() {
privateMethod();
}
}
class SecuredImplSubclass extends SecuredImpl {
@Override
protected void protectedMethod() {
}
@Override
public void publicCallsPrivate() {
super.publicCallsPrivate();
}
}
class PrePostSecured {
@PreAuthorize("denyAll")
public void denyAllMethod() {
}
@PostFilter("filterObject.startsWith('a')")
public List<String> postFilterMethod() {
ArrayList<String> objects = new ArrayList<>();
objects.addAll(Arrays.asList(new String[] { "apple", "banana", "aubergine", "orange" }));
return objects;
}
}

View File

@ -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);
}
}
static class RequestRejectedHandlerPostProcessor implements BeanDefinitionRegistryPostProcessor {
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();
}
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;
}
}
/**
* 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);
@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));
}
}
super.afterPropertiesSet();
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
/**
* 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
* 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
*/
public boolean isEraseCredentialsAfterAuthentication() {
return false;
static final class ClearCredentialsMethodInvokingFactoryBean extends MethodInvokingFactoryBean {
@Override
public void afterPropertiesSet() throws Exception {
boolean isTargetProviderManager = getTargetObject() instanceof ProviderManager;
if (!isTargetProviderManager) {
setTargetObject(this);
}
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;
}
}
}

View File

@ -196,177 +196,178 @@ final class OAuth2ResourceServerBeanDefinitionParser implements BeanDefinitionPa
}
}
}
static final class JwtBeanDefinitionParser implements BeanDefinitionParser {
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();
}
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);
}
}
Object getDecoder(Element element) {
String decoderRef = element.getAttribute(DECODER_REF);
if (!StringUtils.isEmpty(decoderRef)) {
return new RuntimeBeanReference(decoderRef);
return jwtProviderBuilder.getBeanDefinition();
}
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.rootBeanDefinition(NimbusJwtDecoderJwkSetUriFactoryBean.class);
builder.addConstructorArgValue(element.getAttribute(JWK_SET_URI));
return builder.getBeanDefinition();
}
void validateConfiguration(Element element, ParserContext pc) {
boolean usesDecoder = element.hasAttribute(DECODER_REF);
boolean usesJwkSetUri = element.hasAttribute(JWK_SET_URI);
Object getJwtAuthenticationConverter(Element element) {
String jwtDecoderRef = element.getAttribute(JWT_AUTHENTICATION_CONVERTER_REF);
if (!StringUtils.isEmpty(jwtDecoderRef)) {
return new RuntimeBeanReference(jwtDecoderRef);
}
return new JwtAuthenticationConverter();
}
JwtBeanDefinitionParser() {
}
}
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";
@Override
public BeanDefinition parse(Element element, ParserContext pc) {
validateConfiguration(element, pc);
BeanMetadataElement introspector = getIntrospector(element);
BeanDefinitionBuilder opaqueTokenProviderBuilder = BeanDefinitionBuilder
.rootBeanDefinition(OpaqueTokenAuthenticationProvider.class);
opaqueTokenProviderBuilder.addConstructorArgValue(introspector);
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);
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 (usesDecoder == usesJwkSetUri) {
pc.getReaderContext().error("Please specify either decoder-ref or jwk-set-uri.", element);
}
}
}
BeanMetadataElement getIntrospector(Element element) {
String introspectorRef = element.getAttribute(INTROSPECTOR_REF);
if (!StringUtils.isEmpty(introspectorRef)) {
return new RuntimeBeanReference(introspectorRef);
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();
}
String introspectionUri = element.getAttribute(INTROSPECTION_URI);
String clientId = element.getAttribute(CLIENT_ID);
String clientSecret = element.getAttribute(CLIENT_SECRET);
Object getJwtAuthenticationConverter(Element element) {
String jwtDecoderRef = element.getAttribute(JWT_AUTHENTICATION_CONVERTER_REF);
if (!StringUtils.isEmpty(jwtDecoderRef)) {
return new RuntimeBeanReference(jwtDecoderRef);
}
BeanDefinitionBuilder introspectorBuilder = BeanDefinitionBuilder
.rootBeanDefinition(NimbusOpaqueTokenIntrospector.class);
introspectorBuilder.addConstructorArgValue(introspectionUri);
introspectorBuilder.addConstructorArgValue(clientId);
introspectorBuilder.addConstructorArgValue(clientSecret);
return introspectorBuilder.getBeanDefinition();
}
OpaqueTokenBeanDefinitionParser() {
}
}
final class StaticAuthenticationManagerResolver implements AuthenticationManagerResolver<HttpServletRequest> {
private final AuthenticationManager authenticationManager;
StaticAuthenticationManagerResolver(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
public AuthenticationManager resolve(HttpServletRequest context) {
return this.authenticationManager;
}
}
final class NimbusJwtDecoderJwkSetUriFactoryBean implements FactoryBean<JwtDecoder> {
private final String jwkSetUri;
NimbusJwtDecoderJwkSetUriFactoryBean(String jwkSetUri) {
this.jwkSetUri = jwkSetUri;
}
@Override
public JwtDecoder getObject() {
return NimbusJwtDecoder.withJwkSetUri(this.jwkSetUri).build();
}
@Override
public Class<?> getObjectType() {
return JwtDecoder.class;
}
}
final class BearerTokenRequestMatcher implements RequestMatcher {
private final BearerTokenResolver bearerTokenResolver;
BearerTokenRequestMatcher(BearerTokenResolver bearerTokenResolver) {
Assert.notNull(bearerTokenResolver, "bearerTokenResolver cannot be null");
this.bearerTokenResolver = bearerTokenResolver;
}
@Override
public boolean matches(HttpServletRequest request) {
try {
return this.bearerTokenResolver.resolve(request) != null;
return new JwtAuthenticationConverter();
}
catch (OAuth2AuthenticationException e) {
return false;
JwtBeanDefinitionParser() {
}
}
static 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";
@Override
public BeanDefinition parse(Element element, ParserContext pc) {
validateConfiguration(element, pc);
BeanMetadataElement introspector = getIntrospector(element);
BeanDefinitionBuilder opaqueTokenProviderBuilder = BeanDefinitionBuilder
.rootBeanDefinition(OpaqueTokenAuthenticationProvider.class);
opaqueTokenProviderBuilder.addConstructorArgValue(introspector);
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);
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);
}
}
}
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);
BeanDefinitionBuilder introspectorBuilder = BeanDefinitionBuilder
.rootBeanDefinition(NimbusOpaqueTokenIntrospector.class);
introspectorBuilder.addConstructorArgValue(introspectionUri);
introspectorBuilder.addConstructorArgValue(clientId);
introspectorBuilder.addConstructorArgValue(clientSecret);
return introspectorBuilder.getBeanDefinition();
}
OpaqueTokenBeanDefinitionParser() {
}
}
static final class StaticAuthenticationManagerResolver
implements AuthenticationManagerResolver<HttpServletRequest> {
private final AuthenticationManager authenticationManager;
StaticAuthenticationManagerResolver(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
public AuthenticationManager resolve(HttpServletRequest context) {
return this.authenticationManager;
}
}
static final class NimbusJwtDecoderJwkSetUriFactoryBean implements FactoryBean<JwtDecoder> {
private final String jwkSetUri;
NimbusJwtDecoderJwkSetUriFactoryBean(String jwkSetUri) {
this.jwkSetUri = jwkSetUri;
}
@Override
public JwtDecoder getObject() {
return NimbusJwtDecoder.withJwkSetUri(this.jwkSetUri).build();
}
@Override
public Class<?> getObjectType() {
return JwtDecoder.class;
}
}
static final class BearerTokenRequestMatcher implements RequestMatcher {
private final BearerTokenResolver bearerTokenResolver;
BearerTokenRequestMatcher(BearerTokenResolver bearerTokenResolver) {
Assert.notNull(bearerTokenResolver, "bearerTokenResolver cannot be null");
this.bearerTokenResolver = bearerTokenResolver;
}
@Override
public boolean matches(HttpServletRequest request) {
try {
return this.bearerTokenResolver.resolve(request) != null;
}
catch (OAuth2AuthenticationException e) {
return false;
}
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
interceptor.addPropertyValue("accessDecisionManager", new RuntimeBeanReference(accessManagerId));
interceptor.addPropertyValue("authenticationManager", new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER));
// Lookup parent bean information
String parentBeanClass = ((Element) node.getParentNode()).getAttribute("class");
// Parse the included methods
List<Element> methods = DomUtils.getChildElementsByTagName(interceptMethodsElt, Elements.PROTECT);
Map<String, BeanDefinition> mappings = new ManagedMap<>();
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);
if (methodName.lastIndexOf(".") == -1) {
if (parentBeanClass != null && !"".equals(parentBeanClass)) {
methodName = parentBeanClass + "." + methodName;
}
if (!StringUtils.hasText(accessManagerId)) {
accessManagerId = BeanIds.METHOD_ACCESS_MANAGER;
}
mappings.put(methodName, attributeBuilder.getBeanDefinition());
interceptor.addPropertyValue("accessDecisionManager", new RuntimeBeanReference(accessManagerId));
interceptor.addPropertyValue("authenticationManager",
new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER));
// Lookup parent bean information
String parentBeanClass = ((Element) node.getParentNode()).getAttribute("class");
// Parse the included methods
List<Element> methods = DomUtils.getChildElementsByTagName(interceptMethodsElt, Elements.PROTECT);
Map<String, BeanDefinition> mappings = new ManagedMap<>();
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);
if (methodName.lastIndexOf(".") == -1) {
if (parentBeanClass != null && !"".equals(parentBeanClass)) {
methodName = parentBeanClass + "." + methodName;
}
}
mappings.put(methodName, attributeBuilder.getBeanDefinition());
}
BeanDefinition metadataSource = new RootBeanDefinition(MapBasedMethodSecurityMetadataSource.class);
metadataSource.getConstructorArgumentValues().addGenericArgumentValue(mappings);
interceptor.addPropertyValue("securityMetadataSource", metadataSource);
return interceptor.getBeanDefinition();
}
BeanDefinition metadataSource = new RootBeanDefinition(MapBasedMethodSecurityMetadataSource.class);
metadataSource.getConstructorArgumentValues().addGenericArgumentValue(mappings);
interceptor.addPropertyValue("securityMetadataSource", metadataSource);
return interceptor.getBeanDefinition();
}
}

View File

@ -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;

View File

@ -82,20 +82,20 @@ public class SecuredAnnotationSecurityMetadataSource extends AbstractFallbackMet
return this.annotationExtractor.extractAttributes(a);
}
}
static class SecuredAnnotationMetadataExtractor implements AnnotationMetadataExtractor<Secured> {
class SecuredAnnotationMetadataExtractor implements AnnotationMetadataExtractor<Secured> {
@Override
public Collection<ConfigAttribute> extractAttributes(Secured secured) {
String[] attributeTokens = secured.value();
List<ConfigAttribute> attributes = new ArrayList<>(attributeTokens.length);
@Override
public Collection<ConfigAttribute> extractAttributes(Secured secured) {
String[] attributeTokens = secured.value();
List<ConfigAttribute> 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;
}
}

View File

@ -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;
}
}

View File

@ -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")
class Nested {
private String protectedField = "z";
}
@SuppressWarnings("unused")
static class Nested {
private String protectedField = "z";
}
}

View File

@ -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);
}
}

View File

@ -3,7 +3,6 @@
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
<suppressions>
<suppress files=".*" checks="OneTopLevelClass" />
<suppress files=".*" checks="ParenPad" />
<suppress files=".*" checks="RedundantImport" />
<suppress files=".*" checks="RegexpSinglelineJava" />

View File

@ -140,193 +140,193 @@ public class FilterInvocation {
return "FilterInvocation: URL: " + getRequestUrl();
}
}
static class DummyRequest extends HttpServletRequestWrapper {
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<String, String[]> parameters = new LinkedHashMap<>();
private final Map<String, String[]> parameters = new LinkedHashMap<>();
DummyRequest() {
super(UNSUPPORTED_REQUEST);
}
@Override
public String getCharacterEncoding() {
return "UTF-8";
}
@Override
public Object getAttribute(String attributeName) {
return null;
}
public void setRequestURI(String requestURI) {
this.requestURI = requestURI;
}
public void setPathInfo(String pathInfo) {
this.pathInfo = pathInfo;
}
@Override
public String getRequestURI() {
return this.requestURI;
}
public void setContextPath(String contextPath) {
this.contextPath = contextPath;
}
@Override
public String getContextPath() {
return this.contextPath;
}
public void setServletPath(String servletPath) {
this.servletPath = servletPath;
}
@Override
public String getServletPath() {
return this.servletPath;
}
public void setMethod(String method) {
this.method = method;
}
@Override
public String getMethod() {
return this.method;
}
@Override
public String getPathInfo() {
return this.pathInfo;
}
@Override
public String getQueryString() {
return this.queryString;
}
public void setQueryString(String queryString) {
this.queryString = queryString;
}
@Override
public String getServerName() {
return null;
}
@Override
public String getHeader(String name) {
return this.headers.getFirst(name);
}
@Override
public Enumeration<String> getHeaders(String name) {
return Collections.enumeration(this.headers.get(name));
}
@Override
public Enumeration<String> getHeaderNames() {
return Collections.enumeration(this.headers.keySet());
}
@Override
public int getIntHeader(String name) {
String value = this.headers.getFirst(name);
if (value == null) {
return -1;
DummyRequest() {
super(UNSUPPORTED_REQUEST);
}
else {
return Integer.parseInt(value);
@Override
public String getCharacterEncoding() {
return "UTF-8";
}
@Override
public Object getAttribute(String attributeName) {
return null;
}
public void setRequestURI(String requestURI) {
this.requestURI = requestURI;
}
public void setPathInfo(String pathInfo) {
this.pathInfo = pathInfo;
}
@Override
public String getRequestURI() {
return this.requestURI;
}
public void setContextPath(String contextPath) {
this.contextPath = contextPath;
}
@Override
public String getContextPath() {
return this.contextPath;
}
public void setServletPath(String servletPath) {
this.servletPath = servletPath;
}
@Override
public String getServletPath() {
return this.servletPath;
}
public void setMethod(String method) {
this.method = method;
}
@Override
public String getMethod() {
return this.method;
}
@Override
public String getPathInfo() {
return this.pathInfo;
}
@Override
public String getQueryString() {
return this.queryString;
}
public void setQueryString(String queryString) {
this.queryString = queryString;
}
@Override
public String getServerName() {
return null;
}
@Override
public String getHeader(String name) {
return this.headers.getFirst(name);
}
@Override
public Enumeration<String> getHeaders(String name) {
return Collections.enumeration(this.headers.get(name));
}
@Override
public Enumeration<String> getHeaderNames() {
return Collections.enumeration(this.headers.keySet());
}
@Override
public int getIntHeader(String name) {
String value = this.headers.getFirst(name);
if (value == null) {
return -1;
}
else {
return Integer.parseInt(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 Map<String, String[]> getParameterMap() {
return Collections.unmodifiableMap(this.parameters);
}
@Override
public Enumeration<String> getParameterNames() {
return Collections.enumeration(this.parameters.keySet());
}
@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 addHeader(String name, String value) {
this.headers.add(name, value);
}
static final class UnsupportedOperationExceptionInvocationHandler implements InvocationHandler {
@Override
public String getParameter(String name) {
String[] arr = this.parameters.get(name);
return (arr != null && arr.length > 0 ? arr[0] : null);
}
private static final float JAVA_VERSION = Float.parseFloat(System.getProperty("java.class.version", "52"));
@Override
public Map<String, String[]> getParameterMap() {
return Collections.unmodifiableMap(this.parameters);
}
@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");
}
@Override
public Enumeration<String> getParameterNames() {
return Collections.enumeration(this.parameters.keySet());
}
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);
}
@Override
public String[] getParameterValues(String name) {
return this.parameters.get(name);
}
private Object invokeDefaultMethodForJdk8(Object proxy, Method method, Object[] args) throws Throwable {
Constructor<Lookup> 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);
}
private boolean isJdk8OrEarlier() {
return JAVA_VERSION <= 52;
}
public void setParameter(String name, String... values) {
this.parameters.put(name, values);
}
}
final class UnsupportedOperationExceptionInvocationHandler implements InvocationHandler {
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);
}
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);
}
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<Lookup> 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);
}
private boolean isJdk8OrEarlier() {
return JAVA_VERSION <= 52;
}
}

View File

@ -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);
}
@Override
public HttpSession getSession() {
boolean sessionExists = super.getSession(false) != null;
HttpSession session = super.getSession();
if (!sessionExists) {
logger.info("New HTTP session created: " + session.getId(), true);
DebugRequestWrapper(HttpServletRequest request) {
super(request);
}
return session;
}
@Override
public HttpSession getSession() {
boolean sessionExists = super.getSession(false) != null;
HttpSession session = super.getSession();
@Override
public HttpSession getSession(boolean create) {
if (!create) {
return super.getSession(create);
if (!sessionExists) {
DebugRequestWrapper.logger.info("New HTTP session created: " + session.getId(), true);
}
return session;
}
return getSession();
@Override
public HttpSession getSession(boolean create) {
if (!create) {
return super.getSession(create);
}
return getSession();
}
}
}

View File

@ -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;

View File

@ -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;