登录Glassfish JDBC-Realm后缺少用户角色

时间:2012-08-09 15:12:12

标签: authentication java-ee jdbc glassfish jdbcrealm

我在Glassfish上配置了jdbc-realm,我正在尝试为具有多个角色的用户实施身份验证。我正在使用JPA来管理数据库表,JDK 1.7,Glassfish3 +和EclipseLink(JPA 2.0)。

我已经可以使用基于FORM的身份验证成功登录,但作为登录用户,我没有分配任何已定义的角色。

我在相关课程上的实体映射是

PersonAccount.java:

@Entity
@Table(name="PersonAccount") 
public class PersonAccount implements Serializable {

@Id
@NotNull
private String userName;       
private String passwordHash;        

@ManyToMany(cascade={CascadeType.PERSIST})
private Set<UserRole> userRoles = new HashSet<UserRole>();;

...

UserRole.java:

@Entity
@Table(name="UserRole") 
public class UserRole extends NamedEntity implements Serializable {

@Enumerated(EnumType.ORDINAL)
private persons.util.RoleType roleType = RoleType.StudentRole;

@ManyToMany(mappedBy="userRoles", cascade=
    {CascadeType.PERSIST, CascadeType.REMOVE})
private Set<PersonAccount> personAccounts = new HashSet<PersonAccount>(); 

...

其中基类NamedEntity定义主键“id”和值“name”,“PersonAccount”本身分配给“Person”。

创建第一个(主管理员)帐户“admin admin”时,我的数据库内容如下所示:

PERSONACCOUNT:
.USERNAME = admin
.PASSWORDHASH = 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
.PERSON_ID = 220002

PERSONACCOUNT_USERROLE:
.PERSONACCOUNTS_USERNAME admin
.USERROLES_ID = 220001

USERROLE:
.ID = 220001
.NAME = AdminRole
.ROLETYPE = 3

创建帐户后,我可以使用基于表单的身份验证登录。返回的主体名称是“admin”,但没有分配用户角色“AdminRole”,“FacultyRole”,“TeacherRole”或“StudentRole”。我可以通过尝试访问其中一个受安全保护的页面进行验证。

这里是我的应用程序和glassfish的配置:

的web.xml:

<login-config>
    <auth-method>FORM</auth-method>
    <realm-name>klops</realm-name>
    <form-login-config>
        <form-login-page>/login.xhtml</form-login-page>
        <form-error-page>/login.xhtml?error=true</form-error-page>
    </form-login-config>
</login-config>
<security-role>
    <description>Administrators</description>
    <role-name>AdminRole</role-name>
</security-role>
<security-role>
    <description>Faculty</description>
    <role-name>FacultyRole</role-name>
</security-role>    
<security-role>
    <description>Teachers</description>
    <role-name>TeacherRole</role-name>
</security-role>
<security-role>
    <description>Students</description>
    <role-name>StudentRole</role-name>
</security-role>

的glassfish-web.xml中

<security-role-mapping>
    <principal-name>admin</principal-name>      
    <role-name>AdminRole</role-name>
    <group-name>AdminRole</group-name>
</security-role-mapping>
<security-role-mapping>
    <principal-name>teacher</principal-name>
    <role-name>TeacherRole</role-name>
    <group-name>TeacherRole</group-name>
</security-role-mapping>
<security-role-mapping>
    <role-name>StudentRole</role-name>
    <group-name>StudentRole</group-name>
    <principal-name>student</principal-name>
</security-role-mapping>
<security-role-mapping>
    <principal-name>faculty</principal-name>
    <role-name>FacultyRole</role-name>
    <group-name>FacultyRole</group-name>
</security-role-mapping>

最后,领域配置:

    <auth-realm name="myjdbcrealm" classname="com.sun.enterprise.security.auth.realm.jdbc.JDBCRealm">
      <property name="jaas-context" value="jdbcRealm"></property>
      <property name="password-column" value="passwordhash"></property>
      <property name="assign-groups" value="AdminRole,FacultyRole,TeacherRole,StudentRole"></property>
      <property name="datasource-jndi" value="jdbc/__default"></property>
      <property name="user-table" value="personaccount"></property>
      <property name="group-table" value="userrole"></property>
      <property name="user-name-column" value="username"></property>
      <property name="group-name-column" value="name"></property>
      <property name="digest-algorithm" value="SHA-256"></property>
    </auth-realm>

我对某些信息被发现感到困惑(我只能使用创建的帐户登录,并且只能使用正确的密码登录),但是当我登录时,用户上下文似乎不具备任何角色。

我到处搜索并尝试了将近一天,但我在这里找不到错误。 它甚至可以帮助列出当前连接用户所拥有的角色,但似乎检查角色的唯一方法是使用

知道其名称。
FacesContext.getCurrentInstance().getExternalContext().
    isUserInRole("AdminRole"));

非常感谢有关此问题的帮助:)

谢谢,

帕特里克

修改

我创建了一个视图USER_ACCOUNTS,其中包含UserRole.name作为UserName,PersonAccount_Userrole.username作为UserName并相应地更改了域映射,但我仍然得到相同的结果。 如果用户名等于安全角色映射中的principal-name,则用户具有所有4个角色。如果我从映射中删除了主体名称,则用户在登录后根本没有任何角色。

现在表的内容和配置是:

PERSONACCOUNT: (Table)
.USERNAME = admin
.PASSWORDHASH = 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
.PERSON_ID = 220002

USER_ACCOUNTS: (View)
.USERNAME = admin
.ROLENAME = AdminRole

  <property name="password-column" value="passwordhash"></property>
  <property name="assign-groups" value="AdminRole,FacultyRole,TeacherRole,StudentRole"></property>
  <property name="user-table" value="personaccount"></property>
  <property name="group-table" value="user_accounts"></property>
  <property name="user-name-column" value="username"></property>
  <property name="group-name-column" value="rolename"></property>
  <property name="digest-algorithm" value="SHA-256"></property>

1 个答案:

答案 0 :(得分:0)

考虑到你的auth-realm定义(我假设它目前有效),我希望看到两个表(最小信息类似):

CREATE TABLE `personaccount` (
  `username` varchar(32) NOT NULL,
  `passwordhash` varchar(64) DEFAULT NULL,
  PRIMARY KEY (`username`)
);

CREATE TABLE `userrole` (
  `username` varchar(32) NOT NULL,
  `name` varchar(32) DEFAULT NULL, -- role name
  PRIMARY KEY (`username`,`name`) -- allow multiple roles per user
);

请注意,username列在两个表中都具有相同的(列)名称。


我看到你有三张桌子:

PERSONACCOUNT
PERSONACCOUNT_USERROLE
USERROLE

如果要保留该结构,请创建view以将PERSONACCOUNT_USERROLEUSERROLE表映射到类似于上面显示的组表的内容,并使该视图成为您的{ {1}}。

我可以确认这种基于视图的策略适用于Glassfish 3.1.X和MySQL;它可能无法移植到其他应用服务器。


除了可能尝试解决JDBC领域中缺少的角色之外,不确定您使用group-table包括主体名称要完成的任务。


同样,领域属性security-role-mapping的目的是建立一组始终为所有用户定义的组。我从后来的评论中收集到这种行为是出乎意料的;这显然是原因。