Fix defaultMethodExpressionHandler autowiring
Previously if a Bean for GlobalMethodSecurityConfiguration's defaultMethodExpressionHandler was found on a Configuration that also @Autowired a Bean that enabled method security, the Bean that was @Autowired would not have security enabled. This fixes the issue by delaying the lookup of Beans populated on GlobalMethodSecurityConfiguration's defaultMethodExpressionHandler. Fixes gh-4020
This commit is contained in:
parent
e080905a79
commit
bb997eecde
|
@ -150,6 +150,32 @@ public class GlobalMethodSecurityConfiguration
|
|||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
PermissionEvaluator permissionEvaluator = getSingleBeanOrNull(
|
||||
PermissionEvaluator.class);
|
||||
if (permissionEvaluator != null) {
|
||||
this.defaultMethodExpressionHandler
|
||||
.setPermissionEvaluator(permissionEvaluator);
|
||||
}
|
||||
|
||||
RoleHierarchy roleHierarchy = getSingleBeanOrNull(RoleHierarchy.class);
|
||||
if (roleHierarchy != null) {
|
||||
this.defaultMethodExpressionHandler.setRoleHierarchy(roleHierarchy);
|
||||
}
|
||||
|
||||
AuthenticationTrustResolver trustResolver = getSingleBeanOrNull(
|
||||
AuthenticationTrustResolver.class);
|
||||
if (trustResolver != null) {
|
||||
this.defaultMethodExpressionHandler.setTrustResolver(trustResolver);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T getSingleBeanOrNull(Class<T> type) {
|
||||
String[] beanNamesForType = this.context.getBeanNamesForType(type);
|
||||
if (beanNamesForType == null || beanNamesForType.length != 1) {
|
||||
return null;
|
||||
}
|
||||
return this.context.getBean(beanNamesForType[0], type);
|
||||
}
|
||||
|
||||
private void initializeMethodSecurityInterceptor() throws Exception {
|
||||
|
@ -357,16 +383,6 @@ public class GlobalMethodSecurityConfiguration
|
|||
enableMethodSecurity = AnnotationAttributes.fromMap(annotationAttributes);
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setAuthenticationTrustResolver(AuthenticationTrustResolver trustResolver) {
|
||||
this.defaultMethodExpressionHandler.setTrustResolver(trustResolver);
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setRoleHierarchy(RoleHierarchy roleHierarchy){
|
||||
this.defaultMethodExpressionHandler.setRoleHierarchy(roleHierarchy);
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setObjectPostProcessor(ObjectPostProcessor<Object> objectPostProcessor) {
|
||||
this.objectPostProcessor = objectPostProcessor;
|
||||
|
@ -380,16 +396,6 @@ public class GlobalMethodSecurityConfiguration
|
|||
this.jsr250MethodSecurityMetadataSource = jsr250MethodSecurityMetadataSource;
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setPermissionEvaluator(List<PermissionEvaluator> permissionEvaluators) {
|
||||
if (permissionEvaluators.size() != 1) {
|
||||
logger.debug("Not autwiring PermissionEvaluator since size != 1. Got "
|
||||
+ permissionEvaluators);
|
||||
}
|
||||
this.defaultMethodExpressionHandler.setPermissionEvaluator(permissionEvaluators
|
||||
.get(0));
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setMethodSecurityExpressionHandler(
|
||||
List<MethodSecurityExpressionHandler> handlers) {
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright 2012-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.config.method.configuration;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.access.PermissionEvaluator;
|
||||
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
|
||||
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class Gh4020GlobalMethodSecurityConfigurationTests {
|
||||
@Autowired
|
||||
DenyAllService denyAll;
|
||||
|
||||
// gh-4020
|
||||
@Test(expected = AuthenticationCredentialsNotFoundException.class)
|
||||
public void denyAll() {
|
||||
this.denyAll.denyAll();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
static class SecurityConfig {
|
||||
@Bean
|
||||
PermissionEvaluator permissionEvaluator() {
|
||||
return mock(PermissionEvaluator.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
RoleHierarchy RoleHierarchy() {
|
||||
return mock(RoleHierarchy.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
AuthenticationTrustResolver trustResolver() {
|
||||
return mock(AuthenticationTrustResolver.class);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
DenyAllService denyAll;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class ServiceConfig {
|
||||
@Bean
|
||||
DenyAllService denyAllService() {
|
||||
return new DenyAllService();
|
||||
}
|
||||
}
|
||||
|
||||
@PreAuthorize("denyAll")
|
||||
static class DenyAllService {
|
||||
void denyAll() {
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue