【问题标题】:Programmatic authorization in JAASJAAS 中的编程授权
【发布时间】:2015-05-09 03:13:40
【问题描述】:

我有一个要求以编程方式添加授权(权限)约束(此处不是身份验证)。我有一个应用程序范围的 CDI 托管 bean,如下所示。

@Named
@ApplicationScoped
public class Bean {
    @Inject
    private Service service;
    private List<Entity>list;

    public Bean() {}

    @PostConstruct
    private void init() {
        initialize();
    }

    private void initialize() {
        // Initialize the list on application start up.
        // The service.getList() method in an EJB is authenticated anonymously
        // for the first time on application start up.
        list=service.getList();

        // Do something programmatically to enforce the authority ROLE_ADMIN afterwords.
    }

    // This method is only invoked by an admin (ROLE_ADMIN) as and when required.
    // The @PostConstruct method may however be invoked by an anonymous user on start up.
    public void action() {
        initialize();
    }
}

是否可以在用@PostConstruct 装饰的方法完成之前以编程方式强制执行权限/角色,以便service.getList() EJB 方法仅由具有所述ROLE_ADMIN 权限的用户调用一次该方法用@PostConstruct装饰完成它的工作了吗?

换句话说,它的行为完全如下所示 - 一旦@PostConstruct 完成它的工作?

@Stateless
@DeclareRoles(value = {"ROLE_ADMIN", "ROLE_USER"})
@RolesAllowed(value = {"ROLE_ADMIN"})
public class Skeleton implements Service {

    @Override
    public List<Entity> getList() {
        return entityManager.createQuery("SELECT e FROM Entity e").getResultList();
    }
}

我目前使用的是 GlassFish Server 4.1,但如果答案与容器无关,那就更好了。

【问题讨论】:

  • 我认为这在 @ApplicationScoped bean 的上下文中没有多大意义。
  • @peeskillet :整个页面仅描述了@DeclareRoles@RolesAllowed@RunAs 的用法。它没有说明在运行时动态分配权限/角色,即“programmatically”。
  • @SteveC:我完全没能找到你。
  • 这个 bean 是 @ApplicationScoped。所有用户都将访问同一个实例,并且它的 @PostConstruct 方法只会被调用一次(每个应用程序节点)。您要求根据第一个访问它的用户所拥有的角色对其进行初始化。

标签: jakarta-ee glassfish jaas java-ee-7 glassfish-4.1


【解决方案1】:

我不确定是否会起作用,但您可以尝试以下方法。创建一个接收SessionContext的EJB Bean,然后使用方法isCallerInRole(role)。

@Stateless
public class AuthorizationBean {
    @Resource
    private SessionContext sessionContext;

    public Boolean isCallerInRole(String role){
     return this.sessionContext.isCallerInRole(role);
    }
}

在你的类中注入这个bean,然后检查角色。这里的问题是它的类(ApplicationScoped)的范围,因为这不确定它是否会起作用。

【讨论】:

  • 问题的性质完全不同。它与用户的权限检查或权限检查无关。 getList() 方法所在的 EJB 在第一次被调用时被匿名验证,因为它是在应用程序启动时调用的(在 @PostConstruct 方法中,每个应用程序范围只懒惰地或急切地调用一次) .如果方法本身或有问题的 EJB 以声明方式(使用@RolesAllowed(value = {"ROLE_ADMIN"}))分配了角色/权限并且匿名尝试,它将失败并出现安全异常。
  • 这里的重点是ROLE_ADMIN的权限应该在@PostConstruct方法完成之前分配,以便之后可以为方法或EJB授予ROLE_ADMIN的权限,即EJB方法@987654328 @ 应在第一次加载应用程序范围 bean 时匿名调用,但应在之后/然后在每次调用该方法时授予它权限 ROLE_ADMIN,但从 @PostConstruct 方法的第一次调用除外。这是一个非常特殊的情况,并不总是需要。
  • 顺便说一下,这个检查sessionContext.isCallerInRole(role);也可以在web层本身上模拟,如果需要使用HttpServletRequest#isUserInRole("ROLE_ADMIN")。无需使用SessionContextEjbContext 即可在Web 层上使用。
  • 好的@Tiny,真的不明白你的问题。事实上,用户的角色可以在 web 层和 ejb 中看到,但后来认为精确地制作 EJB 是合适的,因为您可以删除 RolesAllowed 注释,然后通过 SessionContext 查看用户是谁及其权限在同一方法内。如果您的要求不允许您删除 RollesAllowed,那么可以尝试使用反射、aop 或字节码操作 (javaassist) 来尝试在运行时添加或删除注解,例如添加 PermitAll 注解然后将其删除。
  • 我不知道这是否可行,因为 EJB 已经完全由服务器处理,但这是一种尝试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-25
  • 2014-04-08
  • 2014-05-11
  • 2011-11-10
  • 2011-08-09
  • 2017-04-20
  • 2015-10-12
相关资源
最近更新 更多