验证方法调用的访问权限

时间:2014-05-08 18:40:30

标签: java java-ee

我正在开发一个Java EE应用程序,它允许登录用户根据他们的角色(例如“管理员”或“访客”)在系统上执行操作。

为此,我需要一种简单而优雅的方法来检查当前登录的用户是否被允许执行方法,而不必在每个方法的最开头放置if语句来检查用户是否具有特权。

我的想法是在应该限制使用的方法之前放置一个自定义注释,并在调用它时评估该注释:

@RestrictAccessToUserGroups("admin")
private void doSomethingAwesome() {

  // If the currently logged in user is not member 
  // of "admin" user group, this method doesn't get called
}

对我而言,这看起来非常灵活和优雅。

不幸的是,我不知道如何触发一个被调用的方法doSomethingAwesome()被调用,以检查被调用的方法是否有注释并解析它们。

知道如何实现(不使用第三方库)?

1 个答案:

答案 0 :(得分:1)

那么你应该研究CDI和拦截器。这是一个很小的例子:

bean可以有多个带注释的实现,这些实现将依赖于用户角色。首先,定义用户注释:

@Qualifier
@Target({TYPE, METHOD, PARAMETER, FIELD})
@Retention(RUNTIME)
public @interface RestrictAccessToUserGroups {
    UserGroup value();
}

public enum UserGroup {
    ADMIN,
    SECOND_LEVEL
}

然后,您可以在bean的不同实现中使用此批注:

@RestrictAccessToUserGroups(ADMIN)
@RequestScoped
public class AdminAwesomeBeanImpl implements AwesomeBean{

public void doSomethingAwesome() {
//some stuff
}

}

然后,您可以在JSF页面,JAX-RS服务等中注入此bean实现。

@Inject
@RestrictAccessToUserGroups(ADMIN)
private AwesomeBean awesomeBean;

如果你想要"触发一个同时调用的方法",那么你需要的是拦截器。我们假设您要对方法调用执行用户验证(doSomethingAwesome)。首先,您必须定义拦截器注释绑定:

@Inherited 
@InterceptorBinding 
@Target({TYPE,METHOD})
@Retention(RUNTIME)
public @interface RestrictAccessToUserGroupsValidator {
    UserGroup value(); 
}

然后你实现你的拦截器,它将在方法调用上验证用户:

@RestrictAccessToUserGroups(ADMIN)
@Interceptor
public class AdminValidator {
@AroundInvoke
    public Object validate(InvocationContext ctx) throws NoSuchMethodException, Exception{
//some user validation
}
}

然后,在业务bean上添加拦截器注释:

@RestrictAccessToUserGroupsValidator(ADMIN)
@RestrictAccessToUserGroups(ADMIN)
@RequestScoped
public class AdminAwesomeBeanImpl implements AwesomeBean{

public void doSomethingAwesome() {
//some stuff
}       
}

不要忘记将拦截器添加到beans.xml文件中:

<interceptors>
        <class>the.package.AdminValidator</class>
    </interceptors>

我希望这可以让你了解它的运作方式。 :)