Java Tomcat 7嵌套结合了realm、LockoutRealm和DataSourceALM

Java Tomcat 7嵌套结合了realm、LockoutRealm和DataSourceALM,java,security,tomcat,realm,Java,Security,Tomcat,Realm,我试图在Tomcat 7.0.32中嵌套领域,如下所示(在这里用伪XML编写): 背后的想法是,web服务有一些关键用户不能被锁定(例如作为DOS)和一些普通用户,这些用户可能具有较弱的密码,其中lockoutRealm应该处于活动状态。我相信其他人也遇到过这种情况 如果有其他方法可以实现这一点(例如锁定领域的白名单),请让我知道 还需要单点登录 我想扩展现有的LockoutRealm代码,添加一个永不锁定的帐户列表是一种选择,但我不太热衷于编写自己的领域,我宁愿不在Tomcat中添加该级别的自

我试图在Tomcat 7.0.32中嵌套领域,如下所示(在这里用伪XML编写):

背后的想法是,web服务有一些关键用户不能被锁定(例如作为DOS)和一些普通用户,这些用户可能具有较弱的密码,其中lockoutRealm应该处于活动状态。我相信其他人也遇到过这种情况

如果有其他方法可以实现这一点(例如锁定领域的白名单),请让我知道

还需要单点登录

我想扩展现有的LockoutRealm代码,添加一个永不锁定的帐户列表是一种选择,但我不太热衷于编写自己的领域,我宁愿不在Tomcat中添加该级别的自定义代码,因为这将使其他人的设置复杂化,并且随着Tomcat的每次更新,它可能会中断等等

谢谢你的帮助

以下是我的测试配置的server.xml的相关部分:

<Engine name="Catalina" defaultHost="localhost">

  <Realm className="org.apache.catalina.realm.CombinedRealm">

    <!-- Lockout realm for the DB users -->
    <Realm className="org.apache.catalina.realm.LockOutRealm">
      <!-- PRIMARY: DataSourceRealm with user DB -->
      <Realm className="org.apache.catalina.realm.DataSourceRealm"
         dataSourceName="jdbc/authority"
         userTable="user" userNameCol="username" 
         userCredCol="password" digest="SHA"
         userRoleTable="user_role" roleNameCol="rolename" />
    </Realm>

    <!-- FALLBACK:
         This Realm uses the UserDatabase configured in the global JNDI
         resources under the key "UserDatabase".  Any edits
         that are performed against this UserDatabase are immediately
         available for use by the Realm.  -->
    <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
           resourceName="UserDatabase"/>

  </Realm>

  <Host name="localhost"  appBase="webapps"
        unpackWARs="true" autoDeploy="true">

    <!-- SingleSignOn valve, share authentication between web applications
         Documentation at: /docs/config/valve.html -->
    <Valve className="org.apache.catalina.authenticator.SingleSignOn" />

    <!-- Access log processes all example.
         Documentation at: /docs/config/valve.html
         Note: The pattern used is equivalent to using pattern="common" -->
    <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
           prefix="localhost_access_log." suffix=".txt"
           pattern="%h %l %u %t &quot;%r&quot; %s %b" />

  </Host>
</Engine>

Apache commons digester用于解析配置文件,因此我怀疑这个特定用例根本不是预期的

Tomcat的
org.apache.catalina.startup.RealmRuleSet.addRuleInstances
似乎被操纵成只对
领域进行两级配置。看起来很简单,可以在其中添加另一层

我必须看看如何配置消化池,看看是否可以支持任意级别,或者是否需要手动配置某些子集


请随时前往请求更改。

现在新的答案是:

更新到Tomcat 7.0.33或更高版本。然后它就可以正常工作了

Christopher Schultz非常友好地将我的问题转发到Tomcat用户列表。伟大的Tomcat开发人员已经立即解决了这个问题,并将其放在下一个版本中。非常感谢

因此,您现在可以使用类似问题中的结构或类似的结构,并具有不同的顺序/“优先级”:

。。。
...
...
当然,你也可以使用其他领域和其他组合


请注意,日志中有一点可能会产生误导:在这种结构中,如果为存储在主域中的一个关键用户提供了错误的密码,则主域拒绝访问,然后尝试通过锁定域访问辅助域,并拒绝访问,最终锁定用户名。锁定域将此记录为警告“试图验证锁定用户…”。仍然使用正确的密码,access通过主域继续工作,因为它不通过锁定域。也就是说,所有工作都按预期进行,仅日志消息可能会导致混乱(当然这是无法避免的)

克里斯托弗,非常感谢你的回答!此外,我还将查看用户列表(可能是我在那里订阅的时候了,只是我必须一直使用太多不同的技术才能订阅所有的用户列表…)。听起来我将无法避免更改/扩展Tomcat代码,除非官方代码在不久的将来支持任意嵌套的级别。如果我需要开始更改Tomcat代码,我可能更愿意使用用户名排除选项扩展LockoutRealm,或者您知道是否存在类似的情况吗?谢谢我已经登录了。太好了,谢谢克里斯托弗!很抱歉我自己没有这么做,现在这里有点紧张……嘿,看看这个:已经修好了。我预计它将在一个月左右的时间内发布到下一个7.0.x版本中。如果您需要将其向后移植到6.0.x,请重新打开该bug并请求向后移植。酷!非常感谢伟大的Tomcat团队!将等待下一个版本(直到那时我才能接受我现在拥有的东西)。对于我来说,不需要向后移植到6.0,我们所有的关键服务器都在7.0.x上。
No rules found matching 'Server/Service/Engine/Realm/Realm/Realm'.
<Engine name="Catalina" defaultHost="localhost">

  <Realm className="org.apache.catalina.realm.CombinedRealm">

    <!-- Lockout realm for the DB users -->
    <Realm className="org.apache.catalina.realm.LockOutRealm">
      <!-- PRIMARY: DataSourceRealm with user DB -->
      <Realm className="org.apache.catalina.realm.DataSourceRealm"
         dataSourceName="jdbc/authority"
         userTable="user" userNameCol="username" 
         userCredCol="password" digest="SHA"
         userRoleTable="user_role" roleNameCol="rolename" />
    </Realm>

    <!-- FALLBACK:
         This Realm uses the UserDatabase configured in the global JNDI
         resources under the key "UserDatabase".  Any edits
         that are performed against this UserDatabase are immediately
         available for use by the Realm.  -->
    <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
           resourceName="UserDatabase"/>

  </Realm>

  <Host name="localhost"  appBase="webapps"
        unpackWARs="true" autoDeploy="true">

    <!-- SingleSignOn valve, share authentication between web applications
         Documentation at: /docs/config/valve.html -->
    <Valve className="org.apache.catalina.authenticator.SingleSignOn" />

    <!-- Access log processes all example.
         Documentation at: /docs/config/valve.html
         Note: The pattern used is equivalent to using pattern="common" -->
    <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
           prefix="localhost_access_log." suffix=".txt"
           pattern="%h %l %u %t &quot;%r&quot; %s %b" />

  </Host>
</Engine>
...

<Engine name="Catalina" defaultHost="localhost">

  <Realm className="org.apache.catalina.realm.CombinedRealm">

    <!-- PRIMARY: tomcat-users.xml with critical system users
                  that should always work, DB independent and without lockout
                  NOTE: If the wrong password is given, the secondary path with
                        lockout is still attempted, so that a lockout on that path
                        will still occur and be logged. Still the primary path is not 
                        locked for access by that happening.                           -->
    <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
           resourceName="UserDatabase"/>

    <!-- SECONDARY: DataSourceRealm with DB with lockout functionality -->
    <!-- (three level nesting of realms requires Tomcat >= 7.0.33)     -->
    <Realm className="org.apache.catalina.realm.LockOutRealm" 
      failureCount="5" lockOutTime="60" > <!-- note that when an account is locked correct password
                                               login is no longer possible (would otherwise defeat purpose of lockout),
                                               but also lockoutTime is still reset in each correct attempt -->

      <Realm className="org.apache.catalina.realm.DataSourceRealm"
         dataSourceName="jdbc/authority"
         userTable="user" userNameCol="username" 
         userCredCol="password" digest="SHA"
         userRoleTable="user_role" roleNameCol="rolename" />

    </Realm>

  </Realm>

  <Host >

    ...

  </Host>
</Engine>

...