Jamison Jiang
Jamison Jiang

Reputation: 53

How to customize annotation have the same SPeL capability like @PreAuthorize?

I know we can write some complicate SPeL expression in @PreAuthorize and it also can parse the method parameter name and use the bean name as the variables, but how to implemented the same SPeL capability like @PreAuthorize when define customize annotation? e.g.: I want to extract parameter value like @PreAuthorize

@Param(key = "p1", value = "#userId")
public void test(String userId) {}

The @PreAuthorize can use the parameter name as the SPeL execute context:

@PreAuthorize("@acl.auth(#userId)")
public void test(String userId) {}

So if the customize annotation declare on controller method and I can extract parameter name from HttpServletRequest as variable

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
  StandardEvaluationContext ctx = new StandardEvaluationContext();
  ctx.setVariable(param.key(), request.getParameterValues(param.value()));
  ExpressionParser expressionParser = new SpelExpressionParser();
  Expression expression = expressionParser.parseExpression(param.value());
}

But I want to reuse the mechanism of @PreAuthorize SPeL parse ability to implemented the customize annotation parameter extraction.

I read the code from MethodSecurityExpressionHandler#createEvaluationContext, so I realize can reuse this method to generate the EvaluationContext to reached @PreAuthorize SPeL execute function:

public final EvaluationContext createEvaluationContext(Authentication authentication,
            T invocation) {
        SecurityExpressionOperations root = createSecurityExpressionRoot(authentication,
                invocation);
        StandardEvaluationContext ctx = createEvaluationContextInternal(authentication,
                invocation);
        ctx.setBeanResolver(br);
        ctx.setRootObject(root);

        return ctx;
    }

The key problem is invocation is a MethodInvocation and spring-security generate the proxy class of original class by Aspect, and I do not know how to generate the same proxy class if I customize annotation so I can not reuse MethodSecurityExpressionHandler#createEvaluationContext to generate the context to run SPeL, anyone have any ideas? Thanks in advance.

Implemented the same SPeL capability of @PreAuthorize

Upvotes: 0

Views: 23

Answers (0)

Related Questions