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) {
|
catch (Exception e) {
|
||||||
throw new RuntimeException(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 {
|
private void initializeMethodSecurityInterceptor() throws Exception {
|
||||||
|
@ -357,16 +383,6 @@ public class GlobalMethodSecurityConfiguration
|
||||||
enableMethodSecurity = AnnotationAttributes.fromMap(annotationAttributes);
|
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)
|
@Autowired(required = false)
|
||||||
public void setObjectPostProcessor(ObjectPostProcessor<Object> objectPostProcessor) {
|
public void setObjectPostProcessor(ObjectPostProcessor<Object> objectPostProcessor) {
|
||||||
this.objectPostProcessor = objectPostProcessor;
|
this.objectPostProcessor = objectPostProcessor;
|
||||||
|
@ -380,16 +396,6 @@ public class GlobalMethodSecurityConfiguration
|
||||||
this.jsr250MethodSecurityMetadataSource = jsr250MethodSecurityMetadataSource;
|
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)
|
@Autowired(required = false)
|
||||||
public void setMethodSecurityExpressionHandler(
|
public void setMethodSecurityExpressionHandler(
|
||||||
List<MethodSecurityExpressionHandler> handlers) {
|
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