SEC-1448: LocalVariableTableParameterNameDiscoverer doesn't find Generic method parameters #1688

Closed
spring-issuemaster opened this Issue Mar 20, 2010 · 3 comments

1 participant

@spring-issuemaster

Jan Heuer (Migrated from SEC-1448) said:

I'm using spring security to secure my service. Here is a sample secured method:

public interface Foo {
@PreAuthorize("hasPermission(#item, 'create')")
public T create(T item);
}

In my junit test I get a NullPointerException when spring parses the EL:

java.lang.NullPointerException
at org.springframework.security.access.expression.method.MethodSecurityEvaluationContext.addArgumentsAsVariables(MethodSecurityEvaluationContext.java:66)
at org.springframework.security.access.expression.method.MethodSecurityEvaluationContext.lookupVariable(MethodSecurityEvaluationContext.java:48)
at org.springframework.expression.spel.ExpressionState.lookupVariable(ExpressionState.java:122)
at org.springframework.expression.spel.ast.VariableReference.getValueInternal(VariableReference.java:52)
at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:59)
at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:93)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:98)
at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:11)
at org.springframework.security.access.expression.method.ExpressionBasedPreInvocationAdvice.before(ExpressionBasedPreInvocationAdvice.java:42)
at org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter.vote(PreInvocationAuthorizationAdviceVoter.java:55)
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:50)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:204)
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:65)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy25.create(Unknown Source)
[snip here comes the junit invocation part]

Debugging the offending code, I noticed that:
org.springframework.core.LocalVariableTableParameterNameDiscoverer#getParameterNames(Method method) returns null.

I guess it is because the method's parameter type is Generic. Can I fix it? Do you have any idea where in the class it's going "wrong" ?

I'd be happy to fix it and submitt a patch but I', not sure where I have to change the code.

Cheers,

Jan

@spring-issuemaster

Peter Mularien said:

It appears that this is caused by LocalVariableTableParameterNameDiscoverer not being updated to include getGenericParameterTypes() in addition to getParameterTypes() when discovering the available method parameters.

@spring-issuemaster

Juergen Hoeller said:

I guess this is rather because of an interface being introspected... Method parameter names are only stored in the class file in case of an actual method body, i.e. not in the case of abstract methods or interface methods. Spring Security should be changed to not rely on the presence of method parameter names there.

Juergen

@spring-issuemaster

Luke Taylor said:

This is actually due to the use of ClassUtils.getMostSpecificMethod() which doesn't work well with generics. Switched to AopUtils instead.

@spring-issuemaster spring-issuemaster added this to the 3.1.0.M1 milestone Feb 5, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment