Glassfish 3.1默认主体到角色的映射

19

我正在使用Glassfish和JAAS模块。

我以这种方式配置了我的web.xml。

<security-constraint>
    <web-resource-collection>
        <web-resource-name>ALL Page for admin</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>user</role-name>
    </auth-constraint>
</security-constraint>
<login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>file</realm-name>
</login-config>
<security-role>
    <description>Administrator</description>
    <role-name>user</role-name>
</security-role>

这意味着所有想要访问我的 Web 应用程序的用户都需要属于用户组。

然后在 Glassfish 控制台中,我需要在以下选项中打钩: Configuration -> server-config -> security -> Default Principal To Role Mapping

我的问题是为什么我需要选中 Default Principal to Role Mapping?我如何更改我的 web.xml 以避免选中它?

非常感谢。

Loic

1个回答

38
当您在web.xml中指定角色和职责时,您正在使用声明性安全性,这基本上依赖于使用JAAS来强制执行以声明方式指定的身份验证和授权要求。
部署描述符中指定的角色仅是应用程序中使用的角色的表示。这些角色不需要与运行时使用的用户标识数据库(或身份验证域)中存在的角色相同,并且通常可能不同,因为应用程序的开发可能没有考虑到实际用户和组。
通常,使用容器特定的部署描述符,在web.xml中指定的声明性角色与用户标识数据库中存在的主体或组之间进行映射。在Glassfish 3.1中,这是glassfish-web.xml文件。每个这样的映射将把应用程序中的声明性角色映射到JAAS领域中的主体或组,方式如下,在glassfish-web.xml(用于WAR文件部署)或glassfish-application.xml(用于EAR文件部署)或glassfish-ejb-jar.xml(用于EJB JAR文件部署)中:

glassfish-web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
...
    <security-role-mapping>
        <role-name>user</role-name>
        <principal-name>Root</principal-name> <!-- Map a principal to the role 'user' -->
        <group-name>Administrators</group-name> <!-- Map a group to the role 'user' -->
    </security-role-mapping>
...
</glassfish-web-app>

glassfish-application.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-application PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Java EE Application 6.0//EN" "http://glassfish.org/dtds/glassfish-application_6_0-1.dtd">
<glassfish-application>
...
    <security-role-mapping>
        <role-name>user</role-name>
        <principal-name>Root</principal-name> <!-- Map a principal to the role 'user' -->
        <group-name>Administrators</group-name> <!-- Map a group to the role 'user' -->
    </security-role-mapping>
...
</glassfish-application>

glassfish-ejb-jar.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-ejb-jar PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 EJB 3.1//EN" "http://glassfish.org/dtds/glassfish-ejb-jar_3_1-1.dtd">
<glassfish-ejb-jar>
...
    <security-role-mapping>
        <role-name>user</role-name>
        <principal-name>Root</principal-name> <!-- Map a principal to the role 'user' -->
        <group-name>Administrators</group-name> <!-- Map a group to the role 'user' -->
    </security-role-mapping>
...
</glassfish-ejb-jar>

上述描述符将角色“用户”映射到具有名称“Root”的个人身份的主体,并将其映射到领域中名称为“管理员”的用户组。您可以省略这些映射中的任何一个,仅保留角色到主体映射或角色到组映射。您还可以将多个主体映射到同一角色,或将多个组映射到同一角色,甚至将多个主体和组映射到同一角色。
了解JAAS领域中主体和组的概念非常重要-主体表示系统中Subject(登录应用程序的用户)的身份,它可以是单个用户的个人身份,也可以是用户组的组身份。通过将声明性角色映射到实际的主体或组,可以对任何用户身份数据库(即任何领域)执行在web.xml中指定的规则,并且可以动态地执行此操作而不需要更改代码库。毕竟,这样的更改需要重新映射声明性角色到可能不同的领域中的新的主体和组集。您可以在Java EE 6教程中的安全章节中找到有关Java EE安全和JAAS如何协同工作的基本教程。
Glassfish允许一种简化的映射方案,即只要声明角色的名称与主体或组的名称相似,就无需对容器特定部署描述符(在本例中为glassfish-web.xml)中的所有声明性角色执行映射。这是默认的主体到角色映射方案。在您的情况下,您领域中的主体/组与web.xml中指定的声明性角色相同,因此您将避免显式地将角色映射到主体和组。简而言之,如果角色user与JAAS领域中的主体user或用户组user相同(其他标识类似),则可以使用Glassfish的默认角色到主体映射方案,而无需为web.xml文件中的每个角色进行映射。
如果您希望避免勾选默认主体到角色映射的部署选项,则必须在容器特定部署描述符中提供角色到主体/组映射,就像通常为其他应用服务器所做的那样。
您可以通过阅读blogs.oracle.com上描述Glassfish此功能的文章之一来了解更多有关此主题的信息。

谢谢你的回答。实际上,我的想法是创建一个名为“用户”的组,所有的用户都属于这个组。也就是说,无论谁在我的应用程序(它是一场战争)中有一个帐户,都可以使用密码和用户名连接。然后,我会自己管理谁可以访问应用程序中的什么内容。 - user789148
如果我使用您提供的glassfish-web.xml代码,尝试连接我的应用程序时会出现以下错误:访问指定资源(已拒绝访问所请求的资源)被禁止。它甚至不会给我登录屏幕。 - user789148
根据您的第二条评论,我推断您在域中没有名为“user”的组;如果是这样,您需要创建这样一个包含所有用户的组。此外,您可以在 glassfish-web.xml 中删除角色到主体的映射,而只使用角色到组的映射。 - Vineet Reynolds
在web.xml中使用角色,您正在使用声明性安全性,这基本上依赖于JAAS的使用-总体而言,这是不正确的。GF使用具有JAAS LoginModule接口的标识存储,但在那里的一切都是完全GF特定的。其他服务器根本不必使用JAAS中的任何内容。通常,在web.xml中使用角色,您依赖于Servlet安全性的使用,该安全性可能使用身份存储的任何专有工件。请参见http://arjan-tijms.omnifaces.org/2015/10/how-servlet-containers-all-implement.html#glassfish - Arjan Tijms
“使用JAAS以声明方式强制执行身份验证和授权要求。” - 如果服务器在专有方式下使用JAAS,则始终仅用于LoginModule接口,因此JAAS仅用于简单的角色提供程序,因此仅执行身份验证。如果使用JACC(所有EE服务器都应该使用,但只有GF真正使用),则会使用一些类似于JAAS的类型,但其中大多数(如java.security.Permission)实际上是预先存在的Java安全模型。 - Arjan Tijms
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接