【问题标题】:Conditional behavior of Spring-AOP Before AdviceSpring-AOP Before Advice 的条件行为
【发布时间】:2012-09-03 13:20:01
【问题描述】:

我对 AOP 有点陌生,对我面临的问题感到困惑。我有注释@AuthorizeUser,它作用于表示层上的方法。我需要检查用户是否有权执行该方法。这是AuthorizeUserAspect 的代码:

@Aspect
public class AuthorizeUserAspect {
    @AuthoWired
    private UserService service;

    @Before(value = "@annotation(com.company.annotation.AuthorizeUser)")
    public void isAuthorized(JoinPoint jp) {
        // Check if the user has permission or not
        // executing some Service Layer services and 
        // Persistence Layer, corresponding to that
        service.checkUser();

        // Is there a way I can make this method Conditional. something like:
        if ( /* User has permission */ ) {
            // do nothing, so the method will be executed after this
        }
        else {
            // 1) Prevent the Method to be executed [and/or]
            // 2) Pass some Parameters to the method for checking [and/or]
            // 3) Execute another method on that class [e.g showAccessDenied()]
        }
    }
}

有点类似于这个问题Spring MVC + Before Advice check security。但它建议返回一些字符串(即“不好”)。我的应用程序中有两种类型的 UI(Struts 和 Jersey),因此会有两种返回类型(分别为 StringResponse)。所以我想这可能不是最好的方法。

如果您能告诉我一个解决方法,我将非常高兴。
这是不是一个好方法?

【问题讨论】:

    标签: java spring security aspectj spring-aop


    【解决方案1】:

    首先,你看过Spring Security吗?它是完全声明性的,不需要您自己编写方面。如果用户未通过身份验证或没有所需的权限,它会通过引发异常来保护方法。

    关于两种不同返回类型的问题:

    第一个选项:创建两种不同类型的通知,特定于方法的返回类型:

    @Before("@annotation(com.company.annotation.AuthorizeUser) && execution(String *.*(..))")
    public void isAuthorizedString(JoinPoint jp) {
        ...
    }
    
    @Before("@annotation(com.company.annotation.AuthorizeUser) && execution(Response *.*(..))")
    public void isAuthorizedResponse(JoinPoint jp) {
        ...
    }
    

    第二种选择:通过反射找出建议方法的返回类型,并据此返回不同的值:

    @Before("@annotation(com.company.annotation.AuthorizeUser")
    public void isAuthorized(JoinPoint jp) {
        Class<?> returnType = ((MethodSignature)jp.getStaticPart()
                .getSignature()).getReturnType();
        if(returnType == String.class)
            ...
        else
            ...
    }
    

    【讨论】:

    • 感谢您的回复,不,我没有考虑过 Spring Security。我会检查一下。我在上面代码的else 块中提到的第三个选项呢?是否可以?或对此有任何赞成/反对?
    • 这当然是可能的。您可以使用jp.getThis() 获取执行对象。当然,现在您必须知道必须将其转换为哪个类(或使用反射来调用该方法)。但我会推荐更简单的方法:使用引发异常的@Around 建议并设计客户端类以捕获该异常并显式调用showAccessDenied()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-23
    • 2016-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多