【问题标题】:JAAS Forbidden Error (403) when accessing a protected URL访问受保护的 URL 时出现 JAAS 禁止错误 (403)
【发布时间】:2015-01-31 03:29:06
【问题描述】:

我刚刚开始在 GlassFish 服务器上使用 JSF、JPA 和 EJB 开展一个宠物项目,目前我正在使用 JAAS 设置身份验证模块。现在差不多完成了,除了一个我无法找到解决方案的错误。

我的前提

我在数据库中有一个表 users,我在其中存储了所有 emailpasswordrole(暂时未标准化)。我对团体没有任何规定。用户只需分配一个角色。

我的数据是这样的:

username        |   role   |      password
mannyee            Member        (sha-256 value)  

我在 GlassFish 服务器中设置了一个 JDBC 领域 (findRoomieRealm)。属性设置有:

JAAS Context    :   jdbcRealm
JNDI        :   jdbc/sample
User Table  :   users
User Name Column:   email 
Password Column :   password
Group Table :   users
Group Name Column:  role
Password Encryption Algorithm:  SHA-256
Group Table User Name Column: (empty)

然后我在 web.xml 中设置以下内容

<welcome-file-list>
    <welcome-file>pages/user/dashboard.xhtml</welcome-file>
</welcome-file-list>

<!-- Protected area definition -->
<security-constraint>
    <web-resource-collection>
        <web-resource-name>Restricted Area</web-resource-name>
        <url-pattern>/pages/user/*</url-pattern> 
    </web-resource-collection>

    <auth-constraint>
        <role-name>MEMBER</role-name>
    </auth-constraint>
</security-constraint>


<!-- Login page -->
<login-config>
    <auth-method>FORM</auth-method>
    <realm-name>findRoomieRealm</realm-name>
    <form-login-config>
        <form-login-page>/faces/login.xhtml</form-login-page>
        <form-error-page>/faces/error.xhtml</form-error-page>
    </form-login-config>
</login-config>

<!-- System roles -->
<security-role>
 <role-name>ADMIN</role-name>
</security-role>
<security-role>
 <role-name>MEMBER</role-name>
</security-role>

我的问题:

当我尝试访问受保护的页面时,登录页面会拦截我可以成功登录系统的请求。我可以通过服务器生成的日志来验证这一点:

Fine:   [Web-Security] Setting Policy Context ID: old = null ctxID = findRoomie/findRoomie
Fine:   [Web-Security] hasUserDataPermission perm: ("javax.security.jacc.WebUserDataPermission" "/j_security_check" "POST")
Fine:   [Web-Security] hasUserDataPermission isGranted: true
Finest:   Processing login with credentials of type: class com.sun.enterprise.security.auth.login.common.PasswordCredential 
Fine:   Logging in user [mannyee] into realm: findRoomieRealm using JAAS module: jdbcRealm
Fine:   Login module initialized: class com.sun.enterprise.security.ee.auth.login.JDBCLoginModule
Finest:   JDBC login succeeded for: mannyee groups:[Member]
Fine:   JAAS login complete.
Fine:   JAAS authentication committed.
Fine:   Password login succeeded for : mannyee
Fine:   Set security context as user: mannyee

但是我在请求的页面(登录后立即)和我得到的日志文件上得到了一个禁止状态:

Fine:   [Web-Security] Setting Policy Context ID: old = null ctxID = findRoomie/findRoomie
Fine:   [Web-Security] hasUserDataPermission perm: ("javax.security.jacc.WebUserDataPermission" "" "GET")
Fine:   [Web-Security] hasUserDataPermission isGranted: true
Fine:   [Web-Security] Policy Context ID was: findRoomie/findRoomie
Fine:   [Web-Security] Codesource with Web URL: file:/findRoomie/findRoomie
Fine:   [Web-Security] Checking Web Permission with Principals : null
Fine:   [Web-Security] Web Permission = ("javax.security.jacc.WebResourcePermission" "/pages/user/dashboard.xhtml" "GET")
Finest:   JACC Policy Provider: PolicyWrapper.implies, context (findRoomie/findRoomie)- result was(false) permission (("javax.security.jacc.WebResourcePermission" "/pages/user/dashboard.xhtml" "GET"))
Fine:   [Web-Security] hasResource isGranted: false
Fine:   [Web-Security] hasResource perm: ("javax.security.jacc.WebResourcePermission" "/pages/user/dashboard.xhtml" "GET")
Fine:   [Web-Security] Policy Context ID was: findRoomie/findRoomie
Fine:   [Web-Security] Generating a protection domain for Permission check.
Fine:   [Web-Security] Checking with Principal : mannyee
Fine:   [Web-Security] Checking with Principal : Member
Fine:   [Web-Security] Codesource with Web URL: file:/findRoomie/findRoomie
Fine:   [Web-Security] Checking Web Permission with Principals : mannyee, Member
Fine:   [Web-Security] Web Permission = ("javax.security.jacc.WebResourcePermission" "/pages/user/dashboard.xhtml" "GET")
Finest:   JACC Policy Provider: PolicyWrapper.implies, context (findRoomie/findRoomie)- result was(false) permission (("javax.security.jacc.WebResourcePermission" "/pages/user/dashboard.xhtml" "GET"))
Fine:   [Web-Security] hasResource isGranted: false

虽然具有 Member 角色的用户应该已经获得了访问权限,但服务器禁止来自用户 mannyee 的请求。所以我在 glassfish-web.xml (sun-web.xml) 上设置了以下内容

<security-role-mapping>
    <role-name>Member</role-name>
    <principal-name>mannyee</principal-name>
    <!--        <group-name>Member</group-name>-->
  </security-role-mapping>

但我仍然无法让该用户访问该页面。我认为问题出在角色分配的某个地方。 Sever 日志显示 GlassFish 尝试通过将 'mannyee' 和 'Member' 作为主体来进行授权,但两者都失败了。还有一行写着

    Fine:   [Web-Security] Checking Web Permission with Principals : null

我不太清楚这是什么意思。

谁能指出我在这里遗漏了什么?

谢谢!!

【问题讨论】:

  • 您是如何在 GlassFish 中创建领域的? GlassFish 服务器没有提供太大的灵活性。它需要在数据库中具有预定义结构的预定义表(除非您使用某些服务器版本中可用的灵活 JDBC 领域),而您在问题中只提到了一个表。
  • 我使用的是 Glassfish V 4.0.1,它提供了 GUI 管理模式。这很容易。
  • 好的。重点不在于 GUI 工具。与 WildFly 等其他一些服务器不同,WildFly 提供了更大的灵活性,允许开发人员编写 SQL 查询以进行身份​​验证/授权,GlassFish 要求数据库中的预定义表具有预定义的结构。例如,user_table 具有像 user_idpassword 这样的列以及其他列。其中user_id 是主键,基本上在列的每一行中都包含电子邮件地址等内容。
  • 另一个名为 user_role_table 的表具有类似 user_id 的列(它是在 user_table 中引用 user_id 的外键)和 group_id,其中包含用户的角色/权限(如 ADMIN 和会员在你的情况下)。 user_role_table 表的这两列,即user_idgroup_id 形成一个复合主键。这是一个特例。不要在表格中使用保留关键字。否则,可能会产生一些问题。 (选择您认为有意义的表和/或列名称)。
  • 要验证,配置的登录机制一定不能通过request.login(userName, password);方法抛出javax.servlet.ServletException,如果提供了正确的凭据并且request.isUserInRole("ADMIN")request.isUserInRole("MEMBER")必须返回true,具体取决于分配给正在登录的用户的权限。

标签: jakarta-ee glassfish jaas


【解决方案1】:

经过一番修改配置,我终于找到了解决方案。我对我的领域进行了以下更改

Assign Groups: ADMIN,MEMBER

然后在 glassfish-web.xml 中,

<security-role-mapping>
    <role-name>MEMBER</role-name>
    <principal-name>MEMBER</principal-name>
    <group-name>MEMBER</group-name>
</security-role-mapping>

我还有一个区分大小写的问题,我在表中将角色存储为 Member,但在我的所有配置中都使用了 MEMBER

【讨论】:

    猜你喜欢
    • 2015-01-09
    • 2018-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-14
    相关资源
    最近更新 更多