Java EE 声明性安全性,无法加载 JDBC 领域用户的组

2023-11-23

这是我在这里发表的第一篇文章。关于声明式 Java EE 安全性,我有两个问题:(1) 基于文件的身份验证和 (2) 基于数据库的身份验证。我附上了两个问题的配置的相关部分。我在 Glassfish 3.1.1 上运行代码。也提前感谢您的帮助。

我也在寻找我的问题的答案,并找到了一些有用的示例,我也将它们放在了消息的底部。我尝试遵循它们,以便配置的当前状态可以包含这些示例的详细信息,但它们没有解决问题。

- 如果勾选了“默认主体到角色映射”,则基于文件的身份验证可以正常工作,否则即使将主体添加到映射中,它也无法工作。我可能以不正确的方式配置了一些东西。

-基于数据库的身份验证。就授权而言,它不起作用,因为无法读取组名称。请参阅下面的详细信息。身份验证工作正常,即用户被识别。我什至尝试重命名表以避免与 Glassfish 的一些内部内容发生潜在的名称冲突......

(1) 基于文件的认证:文件领域,2 个用户:用户、管理员已添加并分配给组:用户和管理员 (配置/服务器配置/安全/领域/文件 - >管理用户)

配置/服务器配置/安全 默认主体到角色映射“勾选”-> 它有效 默认主体到角色映射“未勾选”-> 即使将其添加到安全映射,它也不起作用。

web.xml

[...]
    <security-constraint>
        <display-name>Admin Pages</display-name>
        <web-resource-collection>
            <web-resource-name>Protected Admin Area</web-resource-name>
            <description/>
            <url-pattern>/faces/admin/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
            <http-method>HEAD</http-method>
            <http-method>PUT</http-method>
            <http-method>OPTIONS</http-method>
            <http-method>TRACE</http-method>
            <http-method>DELETE</http-method>
        </web-resource-collection>
        <auth-constraint>
            <description/>
            <role-name>admin</role-name>
        </auth-constraint>
    </security-constraint>
    <security-constraint>
        <display-name>User Pages</display-name>
        <web-resource-collection>
            <web-resource-name>Protected Users Area</web-resource-name>
            <description/>
            <url-pattern>/faces/users/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
            <http-method>HEAD</http-method>
            <http-method>PUT</http-method>
            <http-method>OPTIONS</http-method>
            <http-method>TRACE</http-method>
            <http-method>DELETE</http-method>
        </web-resource-collection>
        <auth-constraint>
            <description/>
            <role-name>user</role-name>
        </auth-constraint>
    </security-constraint>
    <login-config>  
        <auth-method>FORM</auth-method>
        <realm-name>file</realm-name>
        <form-login-config>
            <form-login-page>/faces/loginForm.xhtml</form-login-page>
            <form-error-page>/faces/loginError.xhtml</form-error-page>
        </form-login-config>
    </login-config>

[...]

glassfish-web.xml:

<glassfish-web-app>
    <security-role-mapping>
        <role-name>admin</role-name>
        <group-name>admin</group-name>
    </security-role-mapping>
    <security-role-mapping>
        <role-name>user</role-name>
        <group-name>user</group-name>
    </security-role-mapping>  
</glassfish-web-app>

没有默认主体映射的记录错误:

  1. 没有主体映射到角色 [用户]。
  2. 没有主体映射到角色 [admin]。

Log without the default principal mapping:
    <security-role-mapping>
        <role-name>admin</role-name>
        <group-name>admin</group-name>
        <principal-name>admin</principal-name>
    </security-role-mapping>
    <security-role-mapping>
        <role-name>user</role-name>
        <group-name>user</group-name>
        <principal-name>user</principal-name>
    </security-role-mapping> 

没有默认主体映射的记录错误: 1. 没有主体映射到角色 [用户]。 2. 没有主体映射到角色 [admin]。


(2)基于数据库的认证:

Realm 在 web.xml 中将上面的 Realm 改为 jdbcRealm

  • 1)m-n(用户和组表之间的多对多关系)

    SEC1111,无法加载 JDBC 领域用户 [tamas] 的组。

  • 2) 1-n 相同(用户和组表之间的一对多关系)

    SEC1111,无法加载 JDBC 领域用户 [tamas] 的组。

  • 3)组名与用户名和密码同表

    SEC1111,无法加载 JDBC 领域用户 [tamas] 的组。

领域配置:(我也尝试将“分配组”留空或填写“默认”,但结果是相同的。)

Image had to be omitted, summary:
JAAS context: jdbcRealm
JNDI: jdbc/securityDataSource
User Table: TBLUSERS
User Name Column: USERNAME
Password Column: PASSWORD
Group Table: TBLGROUPS
Group Name Column: GROUPNAME
Assign Groups: default
Digest Algorithm: none 

m-n 关系的 DB ER 图:

必须省略图像,但作为补偿:-) 您可以在下面找到 SQL 脚本。

SQL Script:
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';

CREATE SCHEMA IF NOT EXISTS `jdbcrealm` ;
USE `jdbcrealm` ;

-- -----------------------------------------------------
-- Table `jdbcrealm`.`TBLUSERS`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `jdbcrealm`.`TBLUSERS` ;
CREATE  TABLE IF NOT EXISTS `jdbcrealm`.`TBLUSERS` (
  `USERID` INT NOT NULL AUTO_INCREMENT ,
  `USERNAME` VARCHAR(30) NOT NULL ,
  `PASSWORD` VARCHAR(45) NOT NULL ,
  UNIQUE INDEX `USERNAME_UNIQUE` (`USERNAME` ASC) ,
  PRIMARY KEY (`USERID`) )

ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `jdbcrealm`.`TBLGROUPS`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `jdbcrealm`.`TBLGROUPS` ;
CREATE  TABLE IF NOT EXISTS `jdbcrealm`.`TBLGROUPS` (
  `GROUPID` INT NOT NULL AUTO_INCREMENT ,
  `GROUPNAME` VARCHAR(30) NOT NULL ,
  PRIMARY KEY (`GROUPID`) )

ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `jdbcrealm`.`USERS_GROUPS`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `jdbcrealm`.`USERS_GROUPS` ;
CREATE  TABLE IF NOT EXISTS `jdbcrealm`.`USERS_GROUPS` (
  `USER_USERID` INT NOT NULL ,
  `GROUP_GROUPID` INT NOT NULL ,
  PRIMARY KEY (`USER_USERID`, `GROUP_GROUPID`) ,

  INDEX `fk_USER_has_GROUP_GROUP1` (`GROUP_GROUPID` ASC) ,
  INDEX `fk_USER_has_GROUP_USER` (`USER_USERID` ASC) ,
  CONSTRAINT `fk_USER_has_GROUP_USER`
    FOREIGN KEY (`USER_USERID` )
    REFERENCES `jdbcrealm`.`TBLUSERS` (`USERID` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_USER_has_GROUP_GROUP1`
    FOREIGN KEY (`GROUP_GROUPID` )
    REFERENCES `jdbcrealm`.`TBLGROUPS` (`GROUPID` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)

ENGINE = InnoDB;

SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

我在这里复制了一些关于该主题的有趣的、谷歌搜索的链接,这些链接对我有帮助。本来我是跟着第二个走的。也许其他人也会发现它们很有用。

  • http://docs.oracle.com/javaee/6/tutorial/doc/bnbxj.html
  • http://blog.eisele.net/2011/01/jdbc-security-realm-and-form-b​​ased.html
  • ...还有一些我不得不省略,因为第一篇文章中可能只包含两个链接。

感谢您到目前为止的阅读。最好的祝愿,

Tamas



Part 2感谢您的回复。我创建了 2 个具有一对多关系的新表用户和组。在领域配置页面上,我设置了表名称以及用户名、密码和组的列。马特的评论也符合链接(见下文我不能在这里发布)

[...] 这里有趣的部分是我使用的用户表和组表 v_user_role 作为属性的值。 v_user_role 是一个数据库 包含用户和组信息的视图。原因是我 没有直接使用用户表是因为 glassfish 假设 用户表和组表都包含一列,其中包含 用户名,这会导致重复数据。 [...]

-- -----------------------------------------------------
-- Table `jdbcrealm`.`user`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `jdbcrealm`.`user` ;
CREATE  TABLE IF NOT EXISTS `jdbcrealm`.`user` (
  `userid` VARCHAR(30) NOT NULL ,
  `password` VARCHAR(45) NOT NULL ,
  PRIMARY KEY (`userid`) )
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `jdbcrealm`.`group`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `jdbcrealm`.`group` ;
CREATE  TABLE IF NOT EXISTS `jdbcrealm`.`group` (
  `groupid` VARCHAR(30) NOT NULL ,
  `userid` VARCHAR(30) NOT NULL ,
  INDEX `fk_group_user1` (`userid` ASC) ,
  CONSTRAINT `fk_group_user1`
    FOREIGN KEY (`userid` )
    REFERENCES `jdbcrealm`.`user` (`userid` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

出现同样的错误。我还尝试在组表中的列 groupid 上放置主键,但从问题的角度来看,我没有遇到任何变化。同样有趣的是,我尝试对用户名、密码、组所在的 1 个表执行相同的操作,但出现了相同的错误。



走向解决方案和解决方案

马特的评论很有帮助,感谢这篇精彩的帖子。总之,在我开始写有关基于数据库的身份验证的问题时,很明显无法加载用户组。 server.log 中的错误消息表明了这一点。

然而,我的怀疑转向了表及其列名之间的链接。然而,在简化了用户组实体的数据模型之后,我无法解释为什么即使使用包含用户、密码和组的简单表它也不起作用。我继续朝这个方向进行调查。我认为列名称也会影响这一点。当我应用 Matt 的配置时,“无法加载组”消息从 server.log 中消失,但现象仍然相同。因此我假设这些组已经可以加载,但也存在一个不同的问题。然后我采用了 Matt 的配置,并开始逐步将列名称更改回原始配置,但“无法加载组”消息没有出现在日志中。当我用原始设置重现该案例并且日志消息不存在时,我知道日志记录有问题,它已以某种方式关闭。所以我开始研究整个配置。

当我查看已部署的应用程序时,我选择了部署描述符并通过 glassfish 控制台加载它们。 web.xml 没问题,它的内容与我写的相同,但是glassfish-web.xml 有完全不同的内容!它的生成就好像我没有 glassfish-web.xml 一样。然后我注意到我的glassfish-web.xml没有放在WEB-INF目录中。我将其移到那里并进行了“全部清理,构建”并部署了该应用程序。之后我回到 db 视图,它以多对多关系表示 TBLUSERS 和 TBLGROUPS 之间的数据。我最喜欢这个解决方案,因为它从数据的角度显示了最清晰的图片。我在领域配置页面上设置了适当的列。我用两个用户“tamas”和“arpi”对其进行了测试。 “tamas”被添加到用户组和管理员组,同时“arpi”被添加到用户组。角色和用户组之间的映射位于 glassfish-web.xml 中。 “tamas”获得了对用户和管理资源的访问权限,而“arpi”仅获得了对用户资源的访问权限。

感谢您的帮助。塔马斯


第一眼我就会发现你的表列名称。

根据我自己的经验,我记得用户表中的用户列需要与用户表中的用户列具有完全相同的名称。USER_GROUPS桌子。匹配是通过列名完成的。

So your USER_GROUPS表需要一列USERNAME与来自的用户名相匹配TBLUSERS table.

请注意,您必须为此更改表关系。

可能还有很多其他原因,但您可以尝试一下。

这是我的本地配置:

CREATE TABLE `user` (
  `LOGIN` varchar(32) NOT NULL,
  `password` varchar(256) DEFAULT NULL,
  PRIMARY KEY (`LOGIN`)
)

CREATE TABLE `group` (
  `IDGROUP` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`IDGROUP`)
)

CREATE TABLE `group_has_user` (
  `IDGROUP` int(11) NOT NULL,
  `LOGIN` varchar(32) NOT NULL,
  PRIMARY KEY (`IDGROUP`,`LOGIN`),
  KEY `fk_group_has_user_user1` (`LOGIN`),
  CONSTRAINT `fk_group_has_user_user1` FOREIGN KEY (`LOGIN`) 
     REFERENCES `user` (`LOGIN`) 
     ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `fk_group_has_user_group1` FOREIGN KEY (`IDGROUP`) 
     REFERENCES `group` (`IDGROUP`) 
     ON DELETE NO ACTION ON UPDATE NO ACTION
)

在 GF 管理控制台中进行以下设置:

enter image description here

这是来自 sun-web.xml(现在的 glassfish-web.xml)的安全角色映射:

<security-role-mapping>
    <role-name>user</role-name>
    <group-name>1</group-name>
  </security-role-mapping>
  <security-role-mapping>
    <role-name>sponsor</role-name>
    <group-name>2</group-name>
  </security-role-mapping>
  <security-role-mapping>
    <role-name>admin</role-name>
  <group-name>3</group-name>
</security-role-mapping>

我在 web.xml 中直接在登录配置下面定义了以下安全角色:

<security-role>
   <description/>
   <role-name>user</role-name>
</security-role>
<security-role>
   <description/>
   <role-name>sponsor</role-name>
</security-role>
<security-role>
   <description/>
   <role-name>admin</role-name>
</security-role>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java EE 声明性安全性,无法加载 JDBC 领域用户的组 的相关文章

随机推荐