Spring Security
  1. Spring Security
  2. SEC-1448

LocalVariableTableParameterNameDiscoverer doesn't find Generic method parameters

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 3.0.1
    • Fix Version/s: 3.0.3, 3.1.0.M1
    • Component/s: None
    • Labels:
      None
    • Environment:
      Spring 3.0.1 Maven release

      Description

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

      public interface Foo<T extends MyModel> {
      @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

        Activity

        Hide
        Peter Mularien added a comment -

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

        Show
        Peter Mularien added a comment - It appears that this is caused by LocalVariableTableParameterNameDiscoverer not being updated to include getGenericParameterTypes() in addition to getParameterTypes() when discovering the available method parameters.
        Hide
        Juergen Hoeller added a comment -

        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

        Show
        Juergen Hoeller added a comment - 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
        Hide
        Luke Taylor added a comment -

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

        Show
        Luke Taylor added a comment - This is actually due to the use of ClassUtils.getMostSpecificMethod() which doesn't work well with generics. Switched to AopUtils instead.

          People

          • Assignee:
            Luke Taylor
            Reporter:
            Jan Heuer
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: