如何为Web应用程序中的摘要身份验证配置JBoss DatabaseServerLoginModule

如何为Web应用程序中的摘要身份验证配置JBoss DatabaseServerLoginModule,jboss,passwords,md5,digest-authentication,Jboss,Passwords,Md5,Digest Authentication,在一句话中,我想配置JBoss 4.2.2以使用DatabaseServerLoginModule作为Web应用程序的登录模块,该应用程序通过摘要身份验证进行保护。我遇到的问题是密码无法验证。我怀疑问题要么在于我如何定义应用程序策略,要么在于密码如何存储在数据库中 以下是所有相关文件。我有一个MySQL数据库,其中的用户和角色使用以下模式定义: CREATE TABLE SR_USER ( ID BIGINT(19) NOT NULL AUTO_INCREMENT, USERNAME V

在一句话中,我想配置JBoss 4.2.2以使用DatabaseServerLoginModule作为Web应用程序的登录模块,该应用程序通过摘要身份验证进行保护。我遇到的问题是密码无法验证。我怀疑问题要么在于我如何定义应用程序策略,要么在于密码如何存储在数据库中

以下是所有相关文件。我有一个MySQL数据库,其中的用户和角色使用以下模式定义:

CREATE TABLE SR_USER (
  ID BIGINT(19) NOT NULL AUTO_INCREMENT,
  USERNAME VARCHAR(20) NOT NULL,
  PASSWORD VARCHAR(255) NOT NULL,
  PRIMARY KEY (ID)
)
CHARACTER SET utf8;

CREATE TABLE SR_ROLE (
  ID BIGINT(19) NOT NULL AUTO_INCREMENT,
  ROLE_NAME VARCHAR(20) NOT NULL,
  PRIMARY KEY (ID)
)
CHARACTER SET utf8;

CREATE TABLE SR_USER_ROLE (
  FK_USER_ID BIGINT(19) NOT NULL,
  FK_ROLE_ID BIGINT(19) NOT NULL,
  FOREIGN KEY (FK_USER_ID) REFERENCES SR_USER (ID),
  FOREIGN KEY (FK_ROLE_ID) REFERENCES SR_ROLE (ID)
)
CHARACTER SET utf8;
对于login-config.xml文件中的应用程序策略,我定义了以下内容:

<application-policy name="secrest">
    <authentication>
        <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule"
            flag="required">
            <module-option name="dsJndiName">java:/SecRestDS</module-option>
            <module-option name="principalsQuery">
                SELECT PASSWORD FROM SR_USER WHERE USERNAME=?
                </module-option>
            <module-option name="rolesQuery">
                SELECT r.ROLE_NAME FROM SR_ROLE r, SR_USER_ROLE ur, SR_USER u WHERE
                u.USERNAME=? AND u.ID=ur.FK_USER_ID AND ur.FK_ROLE_ID=r.ID 
                </module-option>
            <module-option name="hashAlgorithm">MD5</module-option>
            <module-option name="hashEncoding">hex</module-option>
        </login-module>
    </authentication>
</application-policy>

如上所述,所有三个用户(例如user1、user2、user3)都有相同的密码;但在每种情况下,密码都是使用MD5哈希进行编码(或不编码)。然而,以上这些都不起作用。我认为这是问题的核心。

在所有示例中,我都看到角色查询看起来有点不同,总是返回两列:

select userRoles,'Roles' from UserRoles where username=? 
您的查询只返回一列


我在我的应用程序中进行了测试,删除这一列后,身份验证停止工作。

所以我最终找到了这一列。关键是:

<application-policy name="secrest">
<authentication>
    <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
        <module-option name="dsJndiName">java:/SecRestDS</module-option>
        <module-option name="principalsQuery">
            SELECT PASSWORD FROM SR_USER WHERE USERNAME=?
        </module-option>
        <module-option name="rolesQuery">
            SELECT r.ROLE_NAME, 'Roles' FROM SR_ROLE r, SR_USER_ROLE ur, SR_USER u WHERE
            u.USERNAME=? AND u.ID=ur.FK_USER_ID AND ur.FK_ROLE_ID=r.ID
        </module-option>    
        <module-option name="hashAlgorithm">MD5</module-option>
        <module-option name="hashEncoding">rfc2617</module-option>
        <module-option name="ignorePasswordCase">false</module-option>
        <module-option name="hashStorePassword">true</module-option>
        <module-option name="hashUserPassword">false</module-option>
        <module-option name="storeDigestCallback">org.jboss.security.auth.spi.RFC2617Digest</module-option>
    </login-module>
</authentication>

java:/SecRestDS
从SR_用户中选择密码,其中用户名=?
从SR_角色r、SR_用户r、SR_用户u中选择r.ROLE_名称“Roles”
u、 用户名=?u.ID=ur.FK\u用户ID和ur.FK\u角色ID=r.ID
MD5
rfc2617
假的
真的
假的
org.jboss.security.auth.spi.rfc2617摘要

像这样的事情可能吗

SELECT PASSWORD FROM SR_USER WHERE USERNAME=? AND IDCOMPANIA=?

SELECT r.ROLE_NAME, 'Roles'
FROM
  SR_ROLE r, SR_USER_ROLE ur, SR_USER u
WHERE
  u.USERNAME=? AND u.ID=ur.FK_USER_ID AND ur.FK_ROLE_ID=r.ID AND u.IDCOMPANIA?

你能这样做吗

<application-policy name="secrest">
<authentication>
    <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
        <module-option name="dsJndiName">java:/SecRestDS</module-option>
        <module-option name="principalsQuery">
            SELECT PASSWORD FROM SR_USER WHERE USERNAME=? AND IDCOMPANIA=? 
        </module-option>
        <module-option name="rolesQuery">
            SELECT r.ROLE_NAME, 'Roles' FROM SR_ROLE r, SR_USER_ROLE ur, SR_USER u WHERE
            u.USERNAME=? AND  u.IDCOMPANIA=? AND u.ID=ur.FK_USER_ID AND ur.FK_ROLE_ID=r.ID
        </module-option>    
        <module-option name="hashAlgorithm">MD5</module-option>
        <module-option name="hashEncoding">rfc2617</module-option>
        <module-option name="ignorePasswordCase">false</module-option>
        <module-option name="hashStorePassword">true</module-option>
        <module-option name="hashUserPassword">false</module-option>
        <module-option name="storeDigestCallback">org.jboss.security.auth.spi.RFC2617Digest</module-option>
    </login-module>
</authentication>

java:/SecRestDS
从SR_用户中选择密码,其中用户名=?IDCOMPANIA=?
从SR_角色r、SR_用户r、SR_用户u中选择r.ROLE_名称“Roles”
u、 用户名=?和u.IDCOMPANIA=?u.ID=ur.FK\u用户ID和ur.FK\u角色ID=r.ID
MD5
rfc2617
假的
真的
假的
org.jboss.security.auth.spi.rfc2617摘要

我理解你的观点,但我确信这不是问题所在,因为当我在web.xml文件中使用BASIC而不是DIGEST时,上面的方法是有效的。我强烈怀疑原因与数据库中密码的存储方式有关。我怀疑它们一定是散列存储的。但我不清楚该怎么做。不幸的是,我从未使用过摘要授权,但也许你可以检查这些URL(如果你以前不知道的话):。你可以在那里找到摘要散列是如何创建的,也许它会有所帮助。很抱歉,你关于在查询中包含“角色”的需要是正确的。这似乎是JBoss的一个要求。完整的答案有点复杂,我会尝试添加一个答案作为一个单独的帖子。祝贺你把这个工作做好。我想知道你是否愿意看看这个问题。我正在为类似的事情挣扎:
<application-policy name="secrest">
<authentication>
    <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
        <module-option name="dsJndiName">java:/SecRestDS</module-option>
        <module-option name="principalsQuery">
            SELECT PASSWORD FROM SR_USER WHERE USERNAME=?
        </module-option>
        <module-option name="rolesQuery">
            SELECT r.ROLE_NAME, 'Roles' FROM SR_ROLE r, SR_USER_ROLE ur, SR_USER u WHERE
            u.USERNAME=? AND u.ID=ur.FK_USER_ID AND ur.FK_ROLE_ID=r.ID
        </module-option>    
        <module-option name="hashAlgorithm">MD5</module-option>
        <module-option name="hashEncoding">rfc2617</module-option>
        <module-option name="ignorePasswordCase">false</module-option>
        <module-option name="hashStorePassword">true</module-option>
        <module-option name="hashUserPassword">false</module-option>
        <module-option name="storeDigestCallback">org.jboss.security.auth.spi.RFC2617Digest</module-option>
    </login-module>
</authentication>
SELECT PASSWORD FROM SR_USER WHERE USERNAME=? AND IDCOMPANIA=?

SELECT r.ROLE_NAME, 'Roles'
FROM
  SR_ROLE r, SR_USER_ROLE ur, SR_USER u
WHERE
  u.USERNAME=? AND u.ID=ur.FK_USER_ID AND ur.FK_ROLE_ID=r.ID AND u.IDCOMPANIA?
<application-policy name="secrest">
<authentication>
    <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
        <module-option name="dsJndiName">java:/SecRestDS</module-option>
        <module-option name="principalsQuery">
            SELECT PASSWORD FROM SR_USER WHERE USERNAME=? AND IDCOMPANIA=? 
        </module-option>
        <module-option name="rolesQuery">
            SELECT r.ROLE_NAME, 'Roles' FROM SR_ROLE r, SR_USER_ROLE ur, SR_USER u WHERE
            u.USERNAME=? AND  u.IDCOMPANIA=? AND u.ID=ur.FK_USER_ID AND ur.FK_ROLE_ID=r.ID
        </module-option>    
        <module-option name="hashAlgorithm">MD5</module-option>
        <module-option name="hashEncoding">rfc2617</module-option>
        <module-option name="ignorePasswordCase">false</module-option>
        <module-option name="hashStorePassword">true</module-option>
        <module-option name="hashUserPassword">false</module-option>
        <module-option name="storeDigestCallback">org.jboss.security.auth.spi.RFC2617Digest</module-option>
    </login-module>
</authentication>