복붙노트

[SPRING] SpelEvaluationException : EL1004E : (pos 0) : 메서드 호출 : 메서드 hasPermission (java.lang.String) MethodSecurityExpressionRoot 형식에서 찾을 수 없습니다.

SPRING

SpelEvaluationException : EL1004E : (pos 0) : 메서드 호출 : 메서드 hasPermission (java.lang.String) MethodSecurityExpressionRoot 형식에서 찾을 수 없습니다.

내 프로젝트에 구성 클래스 MethodSecurityConfig로 구성된 CustomPermissionEvaluator 클래스를 추가하지만 내 로그인 자격 증명을 알린 후 응용 프로그램을 실행하려고하면이 오류 메시지가 나타납니다.

Grave: Servlet.service() for servlet [dispatcher] in context with path [/webapp2] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: Failed to evaluate expression 'hasPermission('admin_main')'] with root cause
org.springframework.expression.spel.SpelEvaluationException: EL1004E:(pos 0): Method call: Method hasPermission(java.lang.String) cannot be found on org.springframework.security.access.expression.method.MethodSecurityExpressionRoot type
    at org.springframework.expression.spel.ast.MethodReference.findAccessorForMethod(MethodReference.java:202)
    at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:118)
    at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:80)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:102)
    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:41)
    at org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter.vote(PreInvocationAuthorizationAdviceVoter.java:54)
    at org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter.vote(PreInvocationAuthorizationAdviceVoter.java:24)
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:62)
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:206)
    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:60)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
    at com.spring.webapp.lojavirtual.acesso.controller.PrivadoController$$EnhancerByCGLIB$$e6bb4ae6_2.admin(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:146)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)

내 클래스 Custom PermissionEvaluator는 다음과 같습니다.

@Component
public class CustomPermissionEvaluator implements PermissionEvaluator {

    public CustomPermissionEvaluator() {
    }

    @Override
    public boolean hasPermission(Authentication arg0, Object arg1, Object arg2) {
        System.out.println("CustomPermissionEvaluator.hasPermission");
        if (arg0 == null || !arg0.isAuthenticated())
            return false;
        else
            return arg0.getAuthorities().contains(arg1);
    }

    @Override
    public boolean hasPermission(Authentication arg0, Serializable arg1, String arg2, Object arg3) {
        throw new RuntimeException("Id-based permission evaluation not currently supported.");
    }

}

내 구성 클래스 MethodSecurityConfig는 다음과 같습니다.

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {

    protected MethodSecurityExpressionHandler createExpressionHandler() {
        System.out.println("MethodSecurityConfig.createExpressionHandler");
        DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
        expressionHandler.setPermissionEvaluator(new CustomPermissionEvaluator());
        return expressionHandler;
    }

}

내 보안 계층의 전체 코드는 다음에서 찾을 수 있습니다.

https://github.com/klebermo/webapp2/tree/master/src/com/spring/webapp/lojavirtual/config/security

누구나 내가 여기서 잘못하고있는 것을 지적 할 수 있습니까?

최신 정보

이런 식으로 주석 @PreAuthorize를 사용합니다.

@Controller
@RequestMapping(value="privado")
public class PrivadoController {

    @RequestMapping(value="admin")
    @PreAuthorize("hasPermission('admin_main')")
    public ModelAndView admin() {
        ModelAndView mav = new ModelAndView();
        mav.setViewName("privado/admin");
        return mav;
    }

    @RequestMapping(value="customer")
    @PreAuthorize("hasPermission('customer_main')")
    public ModelAndView customer() {
        ModelAndView mav = new ModelAndView();
        mav.setViewName("privado/customer");
        return mav;
    }

}

해결법

  1. ==============================

    1.좋아, 마침내 나는 내 프로젝트의이 부분을 끝내야한다. Custom PermissionEvaluator의 최종 코드는 다음과 같습니다.

    좋아, 마침내 나는 내 프로젝트의이 부분을 끝내야한다. Custom PermissionEvaluator의 최종 코드는 다음과 같습니다.

    @Component
    public class CustomPermissionEvaluator implements PermissionEvaluator {
    
        public CustomPermissionEvaluator() {
        }
    
        public boolean hasPermission(Authentication arg0, Object arg1) {
            System.out.println("CustomPermissionEvaluator.hasPermission");
            System.out.println("arg0 = "+arg0);
            System.out.println("arg1 = "+arg1);
    
            if (arg0 == null || !arg0.isAuthenticated()) {
                System.out.println("false");
                return false;
            }
            else {
                System.out.println("true");
                for(GrantedAuthority authority: arg0.getAuthorities()) {
                    if(authority.getAuthority().equals(arg1))
                        return true;
                }
                return false;
            }
        }
    
        @Override
        public boolean hasPermission(Authentication arg0, Object arg1, Object arg2) {
            System.out.println("CustomPermissionEvaluator.hasPermission");
            System.out.println("arg0 = "+arg0);
            System.out.println("arg1 = "+arg1);
            System.out.println("arg2 = "+arg2);
    
            if (arg0 == null || !arg0.isAuthenticated()) {
                System.out.println("false");
                return false;
            }
            else {
                System.out.println("true");
                for(GrantedAuthority authority: arg0.getAuthorities()) {
                    if(authority.getAuthority().equals(arg2))
                        return true;
                }
                return false;
            }
        }
    
        @Override
        public boolean hasPermission(Authentication arg0, Serializable arg1, String arg2, Object arg3) {
            throw new RuntimeException("Id-based permission evaluation not currently supported.");
        }
    
    }
    
  2. ==============================

    2.

    ... Method hasPermission(java.lang.String) cannot be found ...
    

    hasPermission () 메서드는 하나의 인수 만 사용하여 언제든지 호출되지만 3 및 4 인수를 제공합니다.

    public boolean hasPermission(Authentication arg0, Object arg1, Object arg2)
    public boolean hasPermission(Authentication arg0, Serializable arg1, String arg2, Object arg3)
    

    public boolean hasPermission (String permission) 메소드를 추가하고 다시 시도하십시오.

  3. ==============================

    3.당신은 hasPermission ( 'admin_main')을 사용하는 코드를 보여주지 않는다.

    당신은 hasPermission ( 'admin_main')을 사용하는 코드를 보여주지 않는다.

    어쨌든 잘못된 것이지만 CustomPermissionEvaluator에는 단일 인수가있는 메소드가 없습니다. 또는 스프링 보안과 관련하여 다음과 같이하십시오.

    boolean hasPermission(Authentication authentication, Object permission);
    

    어쩌면 당신은 hasRole ( 'admin_main')을 사용하고 싶습니까?

    메소드 구현을위한 충분한 인수를 제공하지 않는 주요 문제점.

  4. ==============================

    4.그런 다음 여기에 제시된 문제를 해결하여 내 컨트롤러의 메서드에서 hasPermission에 대한 호출을 변경합니다. 최종 코드는 다음과 같습니다.

    그런 다음 여기에 제시된 문제를 해결하여 내 컨트롤러의 메서드에서 hasPermission에 대한 호출을 변경합니다. 최종 코드는 다음과 같습니다.

    @Controller
    @RequestMapping(value="privado")
    public class PrivadoController {
    
        @RequestMapping(value="admin")
        @PreAuthorize("hasPermission(#usuario, 'admin_main')")
        public ModelAndView admin() {
            ModelAndView mav = new ModelAndView();
            mav.setViewName("privado/admin");
            return mav;
        }
    
        @RequestMapping(value="customer")
        @PreAuthorize("hasPermission(#usuario, 'customer_main')")
        public ModelAndView customer() {
            ModelAndView mav = new ModelAndView();
            mav.setViewName("privado/customer");
            return mav;
        }
    
    }
    

    (이제 null 값을 반환하는 #usuario를 대체하기위한 올바른 인수를 찾으려고 시도하지만 다른 주제가 필요합니다).

  5. from https://stackoverflow.com/questions/23154239/spelevaluationexception-el1004epos-0-method-call-method-haspermissionjava by cc-by-sa and MIT license