最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - How to intervene in the method security evaluation of Spring Security 6? - Stack Overflow

programmeradmin4浏览0评论

I am a Spring Security novice. If the question description is unprofessional and inaccurate, please help me improve it.

I want to intervene in the method security evaluation process of Spring Security 6 and insert a piece of code:

If the current logged-in user has "SYSTEM" permissions, skip the method security evaluation (including @PreAuthorize, @Secured, jsr250 annotations, and any SpEL).

I tried to customize PermissionEvaluator. I provide a DefaultMethodSecurityExpressionHandler Bean with setPermissionEvaluator(myCustomPermissionEvaluator). It only takes effect in the case of @PreAuthorize("hasPermission"), and other SpEL expressions or @PreAuthorize("isAuthenticated()"), will not take effect.

After some debugging, I found that the invoke method or attemptAuthorization method of AuthorizationManagerBeforeMethodInterceptor is my ideal insertion place, but this class is final:

/**
 * A {@link MethodInterceptor} which uses a {@link AuthorizationManager} to determine if
 * an {@link Authentication} may invoke the given {@link MethodInvocation}
 *
 * @author Evgeniy Cheban
 * @author Josh Cummings
 * @since 5.6
 */
public final class AuthorizationManagerBeforeMethodInterceptor implements AuthorizationAdvisor {

    // ...

    /**
     * Determine if an {@link Authentication} has access to the {@link MethodInvocation}
     * using the configured {@link AuthorizationManager}.
     * @param mi the {@link MethodInvocation} to check
     * @throws AccessDeniedException if access is not granted
     */
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        return attemptAuthorization(mi);
    }

    // ...

    private Object attemptAuthorization(MethodInvocation mi) throws Throwable {
        this.logger.debug(LogMessage.of(() -> "Authorizing method invocation " + mi));
        AuthorizationResult result;
        try {
            result = this.authorizationManager.authorize(this::getAuthentication, mi);
        }
        catch (AuthorizationDeniedException denied) {
            return handle(mi, denied);
        }
        this.eventPublisher.publishAuthorizationEvent(this::getAuthentication, mi, result);
        if (result != null && !result.isGranted()) {
            this.logger.debug(LogMessage.of(() -> "Failed to authorize " + mi + " with authorization manager "
                    + this.authorizationManager + " and result " + result));
            return handle(mi, result);
        }
        this.logger.debug(LogMessage.of(() -> "Authorized method invocation " + mi));
        return proceed(mi);
    }

    // ...

}

My understanding (not necessarily correct) is that in the entire method call chain of the framework, the this.authorizationManager.authorize of the attemptAuthorization method enters the implementation of various (PreAuthorize, Secured, Jsr250) AuthorizationManagers, so I must insert my code before this. The front of the AuthorizationManagerBeforeMethodInterceptor seems to be the AOP aspect, and there is no opportunity for me to intervene.

Is there any feasible way for me to do this?

Any suggestions are welcome and grateful.

发布评论

评论列表(0)

  1. 暂无评论