3

我正在尝试使用 Servlet 3.0 request.login(username, password) 方法来处理 jdbcRealm,但似乎有些问题。有很多关于如何让 jdbcRealm 与 FORM 身份验证一起工作的文章,还有很多关于如何使用新的 request.login 方法的文章,但我还没有看到任何显示两者一起工作的文章。

应用程序服务器 - GlassFish 3.1.2
IDE - Netbeans 7.3
RDBMS - SQL Server 2008 R2
JDBC - Microsoft JDBC 4.0 驱动程序

我很感谢社区提供的有关如何使其正常工作的帮助。提前致谢!

首先,我将 jquery ajax 调用发送到我的 SignInService servlet。在发送之前,我正在使用 SHA-512 中的 jsSHA 库对密码进行编码:

var encodedPassword = new jsSHA($("#omSignInPassword").val(), "TEXT");

$.ajax({
      url: "SignInService",
      data: {
        username : $("#SignInUserName").val(),
        password : encodedPassword.getHash("SHA-512", "HEX")
      }
...
});

这是 Chrome 显示正在发送的内容:

username:admin
password:b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e07394c706a8bb980b1d7785e5976ec049b46df5f1326af5a2ea6d103fd07c95385ffab0cacbc86

servlet 只接受请求参数并尝试登录:

  username = request.getParameter(PARAM_USERNAME);
  password = request.getParameter(PARAM_PASSWORD);

  request.login(username, password);

这些是我在 GlassFish 控制台中看到的错误:

严重:jdbcrealm.invaliduserreason 警告:WEB9102:Web 登录失败:com.sun.enterprise.security.auth.login.common.LoginException:登录失败:安全异常
严重:Servlet 异常:javax.servlet.ServletException:尝试登录时抛出异常为用户进行身份验证:管理员
警告:DPL5032:未在 web.xml 描述符中定义身份验证方法。使用默认 BASIC 进行登录配置。
警告:没有映射到角色 [用户] 的主体。

现在,进入配置...

这是我的 web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <login-config>
        <realm-name>omRealm</realm-name>
    </login-config>
    <security-role>
        <description/>
        <role-name>User</role-name>
    </security-role>
</web-app>

用户表:

CREATE TABLE [OM_SECURITY].[User](
    [UserID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](32) NOT NULL,
    [Password] [char](128) NOT NULL,
    [LastName] [nvarchar](32) NULL,
    [FirstName] [nvarchar](32) NULL,
    [Email] [nvarchar](64) NULL
) ON [PRIMARY]

此表中存在一条记录:

1   admin   B109F3BBBC244EB82441917ED06D618B9008DD09B3BEFD1B5E07394C706A8BB980B1D7785E5976EC049B46DF5F1326AF5A2EA6D103FD07C95385FFAB0CACBC86    NULL    NULL    NULL

(密码现在只是“密码”)

这是用于将每个用户放入“用户”组的视图。这是非常基本的,一旦我有了核心功能就会改变。我预计不会使用 JAAS 角色,因为我的应用程序需求似乎比它们提供的要复杂得多。这可能是另一个讨论,除非这会影响身份验证:

CREATE VIEW [OM_SECURITY].[SignInGroup]
AS
SELECT     'User' AS GroupName, Name AS UserName
FROM         OM_SECURITY.[User]

连接池已经过测试,它工作得很好。领域是在 server-config 部分而不是 default-config 中设置的。

JAAS Context:  jdbcRealm
JNDI:  jdbc/omSecurity
User Table:  OM_SECURITY.User
User Name Column:  Name
Password Column:  Password
Group Table:  OM_SECURITY.SignInGroup
Group Table User Name Column:   UserName
Group Name Column:  GroupName
Assign Groups: (blank)
Database User:  (blank)
Database Password:  (blank)
Digest Algorithm: SHA-512
Password Encryption Algorithm:  AES
Encoding: Hex
Charset: (blank)

如果有人能告诉我哪个文件存储了领域和连接池配置,我将在此处将它们作为 XML 发布。

这也在这里发布到 GlassFish 论坛:

http://www.java.net/forum/topic/glassfish/glassfish-webtier/using-servlet-requestlogin-jdbcrealm

更新:我刚刚整理了一个基于表单的快速登录,但它也失败了,所以问题似乎出在我的领域。我调整了日志级别:

配置\
服务器配置\
日志记录\
日志级别\

javax.enterprise.system.core.security = FINE

com.microsoft.sqlserver.jdbc = 好

根据 SQL Server,查询运行良好,连接池没有抛出异常:

FINE: SQLServerPreparedStatement:3: calling sp_prepexec: PreparedHandle:0, SQL:SELECT Password FROM omUser WHERE Name = @P0 
4

2 回答 2

4

您正在登录

username = request.getParameter(PARAM_USERNAME);
password = request.getParameter(PARAM_PASSWORD);
request.login(username, password);

密码已经散列的地方。我相信 request.login() 采用纯文本版本,然后容器将其与数据库中的散列版本进行比较。

作为旁注,在客户端散列密码通常被认为是不好的做法,它应该通过 ssl 以纯文本形式发送。数据库中的哈希 (+salt) 用于防止黑客在入侵您的数据库时以其他用户身份登录。存储散列密码可以防止这种情况,但前提您的服务器接受纯文本密码。如果它接受散列密码,那么他们就拥有了他们需要的一切。

于 2012-11-05T02:15:13.497 回答
1

根据我使用 Glassfish 的 jdbcRealm 的经验,

request.login(username, password);

这里的密码应该包含用户输入的普通密码,而不是散列密码,因为这是 jdbcRealm 的工作。这可以解释为什么您会收到身份验证错误,因为您用作密码值的哈希密码仍将根据领域配置进行哈希处理。

这是我上次执行此操作时的 jdbcRealm 配置:

Password Encryption Algorithm: SHA-256
Digest Algorithm: SHA-256
Charset: UTF-8
于 2014-01-27T07:56:05.420 回答