繁体   English   中英

如何使用jdbcRealm获取request.login方法?

[英]How can I get the request.login method working with a jdbcRealm?

我试图使用Servlet 3.0 request.login(用户名,密码)方法来处理jdbcRealm,但似乎有些错误。 有很多关于如何使jdbcRealm使用FORM身份验证的文章,还有很多关于如何使用新的request.login方法的文章,但我还没有看到任何显示两者一起工作。

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

我很感谢社区提供的一些帮助,帮助我们开展这项工作。 提前致谢!

首先,我正在向我的SignInService servlet发送一个jquery ajax调用。 我在发送之前使用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:尝试对用户进行身份验证时抛出异常:admin
警告:DPL5032:web.xml描述符中未定义身份验证方法。 使用默认BASIC进行登录配置。
警告:没有Principal映射到Role [User]。

现在,关于配置......

这是我的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]

连接池已经过测试,工作正常。 Realm是在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)

如果有人可以告诉我哪个文件存储了Realm和Connection Pool配置,我会将这些文件作为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 = FINE

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

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

你正在登录

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

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

作为旁注,通常认为在客户端散列密码是不好的做法,它应该通过ssl以纯文本形式发送。 数据库中的散列(+ salt)用于防止黑客如果他们破坏了您的数据库,就像另一个用户一样登录。 存储散列密码会阻止此操作,但前提是您的服务器接受纯文本密码。 如果它接受哈希密码,那么他们就拥有了他们所需要的一切。

我在评论中提到本教程非常好,非常完整: http//www.nabisoft.com/tutorials/glassfish/securing-java-ee-6-web-applications-on-glassfish-using-jaas

我决定按照这些步骤进行操作,并将其改为一点,基本上使用JSF / Managed Beans / CDI ...这里有我的更改的全部细节: 密切关注步骤8和9以正确设置你的Realm 。

http://www.jaider.net/archives/825-securing-java-ee-6-on-glassfish-using-jaas/

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

request.login(username, password);

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

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

Password Encryption Algorithm: SHA-256
Digest Algorithm: SHA-256
Charset: UTF-8

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM