我必须把@DeclareRoles 放在哪里?

raf*_*ael 7 java security jakarta-ee

我基本上了解@DeclareRolesand的功能@RolesAllowed,但我不确定在哪里@DeclareRoles正确添加。我在 glassfish 4 中使用带有 ejb 会话 bean 和 cdi 的 vaadin 应用程序进行测试。该应用程序被打包成战争而不是耳朵。

  • @DeclareRoles类:
    显然没有什么作品。HttpServletRequest.isUserInRole()并且SessionContext.isCallerInRole()总是返回false。@RolesAllowed总是拒绝访问。
  • @DeclareRoles在 Servlet 上:
    @RolesAllowed并且HttpServletRequest.isUserInRole()按预期工作。SessionContext.isCallerInRole()总是返回false。
  • @DeclareRoles在会话 bean: 上
    @RolesAllowedHttpServletRequest.isUserInRole()并按SessionContext.isCallerInRole()预期工作。即使SessionContext.isCallerInRole()在与使用不同的会话 bean 中调用@DeclareRoles

我现在的问题是:

  1. 放在哪里合适@DeclareRoles
  2. 可以只设置一次还是应该注释每个使用SessionContext.isCallerInRole()or 的bean @RolesAllowed

小智 4

可以在类、类的业务方法或两者上指定方法权限。可以在 bean 类的方法上指定方法权限,以覆盖在整个 bean 类上指定的方法权限值。以下注释用于指定方法权限:

  • @DeclareRoles:指定应用程序将使用的所有角色,包括@RolesAllowed注释中未明确指定的角色。应用程序使用的安全角色集是 @DeclareRoles 和@RolesAllowed注释中定义的安全角色的总和。

@DeclareRoles注释在 bean 类上指定,用于声明可以从注释类的方法中测试的角色(例如,通过调用 isCallerInRole)声明用作方法参数的角色名称时isCallerInRole(String roleName),声明的名称必须与参数值相同。

以下示例代码演示了 @DeclareRoles 注释的使用:

@DeclareRoles("BusinessAdmin")
public class Calculator {
    ...
}
Run Code Online (Sandbox Code Playgroud)

声明多个角色的语法如下例所示:

@DeclareRoles({"Administrator", "Manager", "Employee"})
Run Code Online (Sandbox Code Playgroud)
  • @RolesAllowed("list-of-roles"):指定允许访问应用程序中的方法的安全角色。可以在类或一个或多个方法上指定此注释。当在类级别指定时,注释适用于类中的所有方法。当在方法上指定时,注释仅适用于该方法并覆盖在类级别指定的任何值。

要指定任何角色都无权访问应用程序中的方法,请使用 @DenyAll 注释。要指定任何角色的用户都有权访问应用程序,请使用@PermitAll 注释。

当与 @DeclareRoles 注释结合使用时,应用程序将使用安全角色的组合集。

以下示例代码演示了@RolesAllowed注释的使用:

@DeclareRoles({"Administrator", "Manager", "Employee"})
public class Calculator {

    @RolesAllowed("Administrator")
    public void setNewRate(int rate) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)
  • @PermitAll:指定允许所有安全角色执行指定的一个或多个方法。不会根据数据库检查用户以确保他或她有权访问此应用程序。

可以在类或一个或多个方法上指定此注释。在类上指定此注释意味着它适用于该类的所有方法。在方法级别指定它意味着它仅适用于该方法。

以下示例代码演示了@PermitAll注释的使用:

import javax.annotation.security.*;
@RolesAllowed("RestrictedUsers")
public class Calculator {

    @RolesAllowed("Administrator")
    public void setNewRate(int rate) {
        //...
    }
    @PermitAll
    public long convertCurrency(long amount) {
        //...
    }
}
Run Code Online (Sandbox Code Playgroud)
  • @DenyAll:指定不允许安全角色执行指定的一个或多个方法。这意味着这些方法被排除在 Java EE 容器中执行之外。

以下示例代码演示了 @DenyAll 注释的使用:

import javax.annotation.security.*;
@RolesAllowed("Users")
public class Calculator {
    @RolesAllowed("Administrator")
    public void setNewRate(int rate) {
        //...
    }
    @DenyAll
    public long convertCurrency(long amount) {
        //...
    }
}
Run Code Online (Sandbox Code Playgroud)

以下代码片段演示了@DeclareRoles注释与isCallerInRole方法的用法。在此示例中,@DeclareRoles注释声明了一个角色,企业 Bean PayrollBean 使用该角色来进行安全检查,isCallerInRole("payroll")以验证调用者是否有权更改工资数据:

@DeclareRoles("payroll")
@Stateless 
public class PayrollBean implements Payroll {

    @Resource SessionContext ctx;

    public void updateEmployeeInfo(EmplInfo info) {

        oldInfo = ... read from database;

        // The salary field can be changed only by callers
        // who have the security role "payroll"
        Principal callerPrincipal = ctx.getCallerPrincipal();
        if (info.salary != oldInfo.salary && !ctx.isCallerInRole("payroll")) {
            throw new SecurityException(...);
        }
        ...
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

以下示例代码说明了@RolesAllowed注释的用法:

@RolesAllowed("admin")
public class SomeClass {
    public void aMethod () {...}
    public void bMethod () {...}
    ...
}

@Stateless 
public class MyBean extends SomeClass implements A  {

    @RolesAllowed("HR")
    public void aMethod () {...}

    public void cMethod () {...}
    ...
}
Run Code Online (Sandbox Code Playgroud)

更多信息:

保护 Enterprise Bean 的安全