Skip to content

Commit 150b668

Browse files
dbuoseleftherias
authored andcommitted
Make MethodSecurityEvaluationContext Delegate to MethodBasedEvaluationContext
Spring Security's MethodSecurityEvaluationContext should delegate to Spring Framework's MethodBasedEvaluationContext Fixes: gh-6224
1 parent 96d82ec commit 150b668

File tree

2 files changed

+16
-72
lines changed

2 files changed

+16
-72
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -22,8 +22,8 @@
2222
import org.apache.commons.logging.LogFactory;
2323
import org.springframework.aop.framework.AopProxyUtils;
2424
import org.springframework.aop.support.AopUtils;
25+
import org.springframework.context.expression.MethodBasedEvaluationContext;
2526
import org.springframework.core.ParameterNameDiscoverer;
26-
import org.springframework.expression.spel.support.StandardEvaluationContext;
2727
import org.springframework.security.core.Authentication;
2828
import org.springframework.security.core.parameters.DefaultSecurityParameterNameDiscoverer;
2929

@@ -33,16 +33,13 @@
3333
* when they are required.
3434
*
3535
* @author Luke Taylor
36+
* @author Daniel Bustamante
3637
* @since 3.0
3738
*/
38-
class MethodSecurityEvaluationContext extends StandardEvaluationContext {
39+
class MethodSecurityEvaluationContext extends MethodBasedEvaluationContext {
3940
private static final Log logger = LogFactory
4041
.getLog(MethodSecurityEvaluationContext.class);
4142

42-
private ParameterNameDiscoverer parameterNameDiscoverer;
43-
private final MethodInvocation mi;
44-
private boolean argumentsAdded;
45-
4643
/**
4744
* Intended for testing. Don't use in practice as it creates a new parameter resolver
4845
* for each instance. Use the constructor which takes the resolver, as an argument
@@ -54,68 +51,10 @@ class MethodSecurityEvaluationContext extends StandardEvaluationContext {
5451

5552
MethodSecurityEvaluationContext(Authentication user, MethodInvocation mi,
5653
ParameterNameDiscoverer parameterNameDiscoverer) {
57-
this.mi = mi;
58-
this.parameterNameDiscoverer = parameterNameDiscoverer;
54+
super(mi.getThis(), getSpecificMethod(mi), mi.getArguments(), parameterNameDiscoverer);
5955
}
6056

61-
@Override
62-
public Object lookupVariable(String name) {
63-
Object variable = super.lookupVariable(name);
64-
65-
if (variable != null) {
66-
return variable;
67-
}
68-
69-
if (!argumentsAdded) {
70-
addArgumentsAsVariables();
71-
argumentsAdded = true;
72-
}
73-
74-
variable = super.lookupVariable(name);
75-
76-
if (variable != null) {
77-
return variable;
78-
}
79-
80-
return null;
81-
}
82-
83-
public void setParameterNameDiscoverer(ParameterNameDiscoverer parameterNameDiscoverer) {
84-
this.parameterNameDiscoverer = parameterNameDiscoverer;
57+
private static Method getSpecificMethod(MethodInvocation mi) {
58+
return AopUtils.getMostSpecificMethod(mi.getMethod(), AopProxyUtils.ultimateTargetClass(mi.getThis()));
8559
}
86-
87-
private void addArgumentsAsVariables() {
88-
Object[] args = mi.getArguments();
89-
90-
if (args.length == 0) {
91-
return;
92-
}
93-
94-
Object targetObject = mi.getThis();
95-
// SEC-1454
96-
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(targetObject);
97-
98-
if (targetClass == null) {
99-
// TODO: Spring should do this, but there's a bug in ultimateTargetClass()
100-
// which returns null
101-
targetClass = targetObject.getClass();
102-
}
103-
104-
Method method = AopUtils.getMostSpecificMethod(mi.getMethod(), targetClass);
105-
String[] paramNames = parameterNameDiscoverer.getParameterNames(method);
106-
107-
if (paramNames == null) {
108-
logger.warn("Unable to resolve method parameter names for method: "
109-
+ method
110-
+ ". Debug symbol information is required if you are using parameter names in expressions.");
111-
return;
112-
}
113-
114-
for (int i = 0; i < args.length; i++) {
115-
if (paramNames[i] != null) {
116-
setVariable(paramNames[i], args[i]);
117-
}
118-
}
119-
}
120-
12160
}

core/src/test/java/org/springframework/security/access/expression/method/DefaultMethodSecurityExpressionHandlerTests.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -35,9 +35,7 @@
3535

3636
import static org.assertj.core.api.Assertions.assertThat;
3737
import static org.mockito.ArgumentMatchers.any;
38-
import static org.mockito.Mockito.doReturn;
39-
import static org.mockito.Mockito.mock;
40-
import static org.mockito.Mockito.verify;
38+
import static org.mockito.Mockito.*;
4139

4240
@RunWith(MockitoJUnitRunner.class)
4341
public class DefaultMethodSecurityExpressionHandlerTests {
@@ -53,6 +51,8 @@ public class DefaultMethodSecurityExpressionHandlerTests {
5351
@Before
5452
public void setup() {
5553
handler = new DefaultMethodSecurityExpressionHandler();
54+
when(methodInvocation.getThis()).thenReturn(new Foo());
55+
when(methodInvocation.getMethod()).thenReturn(Foo.class.getMethods()[0]);
5656
}
5757

5858
@After
@@ -108,4 +108,9 @@ public void filterStreamWhenClosedThenUpstreamGetsClosed() {
108108
((Stream) handler.filter(upstream, expression, context)).close();
109109
verify(upstream).close();
110110
}
111+
112+
private static class Foo {
113+
public void bar(){
114+
}
115+
}
111116
}

0 commit comments

Comments
 (0)