mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-30 16:52:13 +00:00
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:
parent
053af720a4
commit
f1cee9500f
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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" />
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user