【问题标题】:Validate access rights on method call验证方法调用的访问权限
【发布时间】:2014-05-08 18:40:29
【问题描述】:

我正在开发一个 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() 的同时被调用的方法,以检查被调用的方法是否有注释并解析它们。

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

【问题讨论】:

  • 它是一个 Web 应用程序吗?如果是这样,您可以使用会话和过滤器。如果你想进行关注点分离(模式),你应该使用带有自定义注释的 CDI。
  • 另外,java EE 服务器通过角色实现用户管理。这些角色由容器管理,您可以在代码上分配角色。
  • 是的,它是一个网络应用程序。 Java EE 的角色管理不够灵活(我没有提到它,但我需要管理灵活数量的角色),我更喜欢“代码级访问控制”而不是仅基于过滤器的访问控制(它检查网址。)

标签: java jakarta-ee


【解决方案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>

我希望这能让您了解它是如何工作的。 :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-21
    • 1970-01-01
    • 2013-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多