使用Tomcat 6.0上的角色设置客户端证书身份验证

时间:2011-02-23 02:41:59

标签: java authentication tomcat

我正在设置一个使用客户端证书身份验证的Web应用程序。目前,我只是设置了一个测试用户帐户和一个“用户”角色来测试身份验证和授权。我正在使用DataSourceRealm和postgreSQL数据库这样配置:

<Realm className="org.apache.catalina.realm.DataSourceRealm"
    dataSourceName="jdbc/postgres" localDataSource="true"
    userTable="users" userNameCol="username" userCredCol="password"
    userRoleTable="user_roles" roleNameCol="role" />

<Resource auth="Container" type="javax.sql.DataSource" name="jdbc/postgres"
    driverClassName="org.postgresql.Driver"
    url="jdbc:postgresql://localhost:5432/test"
    maxActive="100" maxIdle="30" maxWait="-1"
    username="test" password="test" />

当我第一次设置数据库和应用程序时,我在web.xml中使用了以下配置的FORM身份验证:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>Test</web-resource-name>
        <url-pattern>/*</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
    </web-resource-collection>

    <auth-constraint>
        <role-name>user</role-name>
    </auth-constraint>

    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

<login-config>
    <auth-method>FORM</auth-method>
    <form-login-config>
        <form-login-page>/login.jsp</form-login-page>
        <form-error-page>/login-failed.jsp</form-error-page>
    </form-login-config>
</login-config>

数据库包含用户:testuser并分配了角色:user。使用FORM身份验证登录按预期工作。

然后我将FORM身份验证方法更改为CLIENT-CERT并设置必要的证书,CA等.server.xml中的连接器配置如下:

   <Connector SSLEnabled="true" clientAuth="true"
    maxThreads="150" port="8443" protocol="HTTP/1.1" scheme="https"
    keystoreFile="C:\Workspace\Test\keystore.jks"
    keystorePass="changeit"
    truststoreFile="C:\Workspace\Test\truststore.jks"
    truststorePass="changeit"
    secure="true" sslProtocol="TLS"/>

用户在数据库中被标识为“CN = testuser,O = Internet Widgits Pty Ltd,ST = Some-State,C = AU”

如果我保留指定“用户”角色的auth-constraint,我会收到403权限被拒绝访问任何页面的错误。看起来身份验证成功但无法从数据库中确定用户的角色。如果我注释掉auth-constraint,则身份验证成功,我可以访问受保护的页面。

看起来它无法在数据库中查找用户的角色,尽管我更改的db中唯一的内容是如何表示用户名。验证后,使用以下代码:

X500Principal p = certs[0].getSubjectX500Principal();
out.println (p.getName());

生成“CN = testuser,O = Internet Widgits Pty Ltd,ST = Some-State,C = AU”,这是存储在数据库中的用户名列中的值,该值也映射到数据库中的“用户”角色user_roles表。

test=> select * from users;
                         username                          | password
-----------------------------------------------------------+----------
 CN=testuser,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU |
(1 row)

test=> select * from user_roles;
                         username                          | role
-----------------------------------------------------------+------
 CN=testuser,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU | user
(1 row)

我还应该做些什么才能查找用户角色?从目前为止我看到的一切看起来应该可行。谢谢你的帮助。

1 个答案:

答案 0 :(得分:1)

我找到了问题的答案。

即使

X500Principal p = certs[0].getSubjectX500Principal();
out.println (p.getName());

将主题DN返回为“CN = testuser,O = Internet Widgits Pty Ltd,ST = Some-State,C = AU”,打开详细记录数据库显示“CN = testuser,O = Internet Widgits Pty Ltd ,ST = Some-State,C = AU“(在字段之间插入空格)被提交到查询中的数据库。

LOG:  ... execute <unnamed>: SELECT null FROM users WHERE username = $1
parameters: $1 = 'CN=testuser, O=Internet Widgits Pty Ltd, ST=Some-State, C=AU'
LOG:  ... execute <unnamed>: SELECT role FROM user_roles WHERE username = $1
parameters: $1 = 'CN=testuser, O=Internet Widgits Pty Ltd, ST=Some-State, C=AU'

似乎X509Principal.getName()返回getName(X500Principal.RFC2253),其中tomcat似乎正在使用getName(X500Principal.RFC1779)。更新数据库以使用RFC 1779格式解决了我的问题。