잡동사니

반응형

질문

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

    @Autowired
    private ApplicationContext context;

    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
        expressionHandler.setPermissionEvaluator(new UserPermissionEvaluator());
        expressionHandler.setApplicationContext(context);
        return expressionHandler;
    }
}

그리고 UserPermission class

@Component("UsrPermission")
public class UserPermissionEvaluator implements PermissionEvaluator {
    @Override
    public boolean hasPermission(Authentication authentication, Object targetObject, Object permission) {
        if (!targetObject.toString().equals("true") && targetObject.toString().equals(permission.toString())) {
            return true;
        } else if (!targetObject.toString().equals("true")) {
            return false;
        }
        ...
        return hasPermission;
    }

    public boolean isAdmin() {
        return CustomSecurityPrincipal.getSecurityPrincipal().isAdmin();
    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
            Object permission) {
        return false;
    }

}

"hasPermission (x, y, z)"는 매력처럼 작동합니다. 그러나 새로운 사용자 지정 메서드를 만들려고 시도했으며 MethodSecurityConfig에 등록되어 있기 때문입니다. 직접 부르려고 해요

@PreAuthorize("isAdmin()")

오류:-

org.springframework.expression.spel.SpelEvaluationException: EL1004E: Method call: Method isAdmin() cannot be found on type org.springframework.security.access.expression.method.MethodSecurityExpressionRoot
    at org.springframework.expression.spel.ast.MethodReference.findAccessorForMethod(MethodReference.java:225) ~[spring-expression-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:134) ~[spring-expression-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:94) ~
    at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:114) ~[spring-expression-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:300) ~[spring-expression-5.1.6.RELEASE.jar:5.1.6.RELEASE]
    at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:26) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.security.access.expression.method.ExpressionBasedPreInvocationAdvice.before(ExpressionBasedPreInvocationAdvice.java:59) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter.vote(PreInvocationAuthorizationAdviceVoter.java:72) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter.vote(PreInvocationAuthorizationAdviceVoter.java:40) ~[spring-security-core-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at 

...


답변1

새 사용자 지정 식을 만들려면 MethodSecurityExpressionOperations 의 사용자 지정 구현을 만들고 여기에 새 작업을 추가해야합니다. 기본 표현식을 지원하도록 SecurityExpressionRoot 를 확장 할 수 있습니다.

public class CustomMethodSecurityExpressionRoot
        extends SecurityExpressionRoot implements MethodSecurityExpressionOperations {

    private Object filterObject;
    private Object returnObject;
    private Object target;

    CustomMethodSecurityExpressionRoot(Authentication authentication) {
        super(authentication);
    }

    @Override
    public void setFilterObject(Object filterObject) {
        this.filterObject = filterObject;
    }

    @Override
    public Object getFilterObject() {
        return filterObject;
    }

    @Override
    public void setReturnObject(Object returnObject) {
        this.returnObject = returnObject;
    }

    @Override
    public Object getReturnObject() {
        return returnObject;
    }

    void setThis(Object target) {
        this.target = target;
    }

    @Override
    public Object getThis() {
        return target;
    }

    /**
     * Custom 'isAdmin()' expression
     */
    public boolean isAdmin() {
        // TODO: Implement
        return true;
    }
}

다음으로 DefaultMethodSecurityExpressionHandler 를 확장하고 CustomMethodSecurityExpressionRoot 를 사용하도록 만들어야합니다.

public class CustomMethodSecurityExpressionHandler extends DefaultMethodSecurityExpressionHandler {
    @Override
    protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication, MethodInvocation invocation) {
        CustomMethodSecurityExpressionRoot root = new CustomMethodSecurityExpressionRoot(authentication);
        root.setPermissionEvaluator(getPermissionEvaluator());
        root.setTrustResolver(new AuthenticationTrustResolverImpl());
        root.setRoleHierarchy(getRoleHierarchy());
        return root;
    }
}

마지막으로 구성에서 CustomMethodSecurityExpressionHandler 를 사용해야합니다.

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
    @Override
    protected MethodSecurityExpressionHandler createExpressionHandler() {
        return new CustomMethodSecurityExpressionHandler();
    }
}


 

 

 

 

출처 : https://stackoverflow.com/questions/59122271/custom-method-in-preauthorize-is-not-working-failed-to-evaluate-expression-isa

반응형

이 글을 공유합시다

facebook twitter googleplus kakaoTalk kakaostory naver band