【问题标题】:How to configure security restrictions for EJB methods in TomEE?如何在 TomEE 中为 EJB 方法配置安全限制?
【发布时间】:2017-10-03 13:52:02
【问题描述】:

基本上,我无法让@RolesAllowed 注释工作。容器似乎完全忽略了它。

但是,isCallerInRole() 方法可以正常工作。

只有管理员才能调用下面的方法,但每次都会调用该方法,尽管用户只有“访客”角色。

@Remote
public interface SomeManager {
    void performImportantTask();
}

@Stateless
@DeclareRoles({"guest", "admin"})
public class SomeManagerBean implements SomeManager {    
    @Resource private EJBContext context;

    @RolesAllowed({"admin"})
    @Override public void performImportantTask() {
        logger.info(context.getCallerPrincipal().getName()); // prints the correct user name

        if (context.isCallerInRole("admin")) {
            logger.info("Is admin"); // doesn't print
        }

        if (context.isCallerInRole("guest")) {
            logger.info("Is guest"); // prints
        }
    }
}

即使容器清楚地知道用户不是管理员,为什么还要调用这个方法?

我还尝试将 @RolesAllowed 替换为 @DenyAll 并且这不否认 - 该方法仍在执行。

这是 server.xml 中的领域配置:

...
            <Realm className="org.apache.catalina.realm.LockOutRealm">
                <Realm className="org.apache.catalina.realm.DataSourceRealm"
                       dataSourceName="securityDS"
                       userTable="users"
                       userNameCol="user_name"
                       userCredCol="user_pass"
                       userRoleTable="user_roles"
                       roleNameCol="role_name"/>
            </Realm>
            ...            
        </Engine>
    </Service>
</Server>

很可能,我有一些配置问题,但我不知道该去哪里找。 或者我这里有什么误解?

我假设 tomcat_users.xml 文件与 DataSourceRealm 无关。 不过,考虑到我可能需要在这个文件中定义角色,我这样添加它们:

<tomcat-users ...>
  <role rolename="admin"/>
  <role rolename="guest"/>
</tomcat-users>

但这并没有改变上述情况。

相关文档:

TomEE Security Annotations

DataSourceRealm and TomEE DataSource

【问题讨论】:

    标签: java jakarta-ee apache-tomee


    【解决方案1】:

    请注意,一个应用程序服务器可能有多个应用程序和多个领域。每个应用程序都可以配置为使用特定领域并将领域用户和组映射到应用程序中的角色。

    在你的例子中:

    • server.xml 用于define one or more realms in the server。
    • tomcat_users.xml 允许您为默认的UserDatabaseRealm 定义用户,但不能为DataSourceRealm 定义用户。这些领域适用于 Web 应用程序。

    如何在 TomEE 中为 EJB 方法配置安全限制?

    我认为 TomEE 中的 EJB 使用 Java Authentication and Authorization (JAAS)。您必须在server.xml 或context.xml 中配置一个JAAS 领域,并使用login.config 文件配置该领域。您必须将java.security.auth.login.config 系统属性设置为指向该文件:


    示例: TomEE rest-jaas example 显示了一个使用 PropertiesLogin 模块的应用程序,即使用文件来存储用户和密码。

    1. 在命令行中,你可以运行类似:

      set CATALINA_OPTS="Djava.security.auth.login.config=$CATALINA_BASE/conf/login.config"
      

      如果您使用 maven 运行 TomEE,则可以在 &lt;build&gt; 中的 &lt;pluing&gt; 中定义变量 pom.xml

      <plugin>
        <groupId>org.apache.tomee.maven</groupId>
        <artifactId>tomee-maven-plugin</artifactId>
        <version>7.0.5-SNAPSHOT</version>
        <configuration>
          <systemVariables>
            <java.security.auth.login.config>${project.build.directory}/apache-tomee/conf/login.config</java.security.auth.login.config>
          </systemVariables>
          <context>ROOT</context>
        </configuration>
      </plugin>
      
    2. 在login.config 中配置JAAS 领域。 TomEE 示例通常使用PropertiesLogin 将用户和密码存储在.properties 文件中。

      PropertiesLogin {
          org.apache.openejb.core.security.jaas.PropertiesLoginModule required
          Debug=false
          UsersFile="users.properties"
          GroupsFile="groups.properties";
      };
      

      有一些使用其他登录模块的 OpenEJB 示例,例如 SQLLogin:

      SQLLogin {
          org.apache.openejb.core.security.jaas.SQLLoginModule required
          jdbcURL="jdbc:hsqldb:mem:sqltest"
          userSelect="SELECT username, password FROM users WHERE username = ?"
          groupSelect="SELECT username, grp FROM groups WHERE username = ?";
      };
      

      如果您定义多个领域。您可以更改自定义名称的 PropertiesLogin 或 SQLLogin 根名称。

    3. 最后,您必须在server.xml(或context.xml)中配置JAAS 领域。例如,您可以在server.xml 的&lt;Engine&gt; 中包含&lt;Realm&gt;。

      <Realm className="org.apache.catalina.realm.JAASRealm" appName="PropertiesLogin"
           userClassNames="org.apache.openejb.core.security.jaas.UserPrincipal"
           roleClassNames="org.apache.openejb.core.security.jaas.GroupPrincipal">
      

      appName 取决于您在上述login.config 文件中定义的名称。 userClassNames 和 roleClassNames 因 JAAS 提供程序而异。


    其他模块:您可以使用其他兼容 JAAS 的登录模块。有许多包含在标准 java 和 OpenEJB 中。您可以检查:

    • LoginConfig file 的 java 文档了解有关标准 JndiLoginModule、KeyStoreLoginModule、Krb5LoginModule、NTLoginModule 和 UnixLoginModule 模块的信息。
    • OpenEJB 有other login modules,包括上面提到的两个(PropertiesLogin 或SQLLogin)。
    • 您可以查看the JAAS documentation 并创建自己的登录模块。

    示例:有一些TomEE examples(maven 项目)展示了如何配置和测试使用 JAAS(Java 身份验证和授权)注释的组件,您可以查看:

    • ejb-examples 包括安全 EJB 等。
    • moviefun 包括与特定用户一起运行的单元测试,并且
    • rest-jaas 向您展示如何保护 REST 端点。

    【讨论】:

    • 你的意思是DataSourceRealm不应该和Tomee一起使用吗?我使用 Tomcat 文档对其进行了配置,认为 Tomee 只是使用了 Tomcat 已有的内容。
    • TomEE 将 Tomcat 用于 Web servlet/JSP,将 OpenEJB 用于 EJB。根据this old forum,您可以使用基于Tomcat 的领域(上下文领域)来保护Web 应用程序而不是EJB。您需要 JAAS 来保护 EJB。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    • 2014-06-08
    • 1970-01-01
    相关资源
    最近更新 更多