2

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」に割り当てられます。

最初の(マスター管理者)アカウント「adminadmin」を作成すると、データベースのコンテンツは次のようになります。

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」は割り当てられていません。これは、セキュリティで保護されたページの1つにアクセスしようとすることで確認できます。

ここに私のアプリケーションと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>

一部の情報が見つかったという事実に少し戸惑っています(作成したアカウントでのみログインでき、正しいパスワードでのみログインできます)が、ログインしたとき、ユーザーコンテキストは役割を持っていないようです。

私はどこでも検索して、ほぼ1日試しましたが、ここでエラーを見つけることができません。接続しているユーザーが現在持っている役割を一覧表示できるようにすることも役立ちますが、役割を確認する唯一の方法は、を使用してその名前を知ることです。

FacesContext.getCurrentInstance().getExternalContext().
    isUserInRole("AdminRole"));

この問題の助けをいただければ幸いです:)

ありがとう、

パトリック

編集:

UserRole.nameをUserNameとして、PersonAccount_Userrole.usernameをUserNameとして含むビューUSER_ACCOUNTSを作成し、それに応じてレルムマッピングを変更しましたが、それでも同じ結果が得られます。ユーザー名がセキュリティロールマッピングのプリンシパル名と等しい場合、ユーザーは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>
4

1 に答える 1

0

auth-realmあなたの定義(今のところ有効だと思います)を考えると、 2つのテーブル(最小限の情報は次のようなもの)が表示されると思います。

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列は両方のテーブルで同じ(列)名を持っていることに注意してください。


3つのテーブルがあるようです。

PERSONACCOUNT
PERSONACCOUNT_USERROLE
USERROLE

その構造を保持したい場合は、とテーブルを上記のグループテーブルのようなものviewにマップするためのを作成し、そのビューをにします。PERSONACCOUNT_USERROLEUSERROLEgroup-table

このビューベースの戦略がGlassfish3.1.XおよびMySQLで機能することを確認できます。他のアプリサーバーに移植できない場合があります。


security-role-mappingJDBCレルムから欠落しているロールを回避しようとする以外は、プリンシパル名を含めて何を達成しようとしているのかわからない。


同様に、レルムプロパティの目的は、assign-groupsすべてのユーザーに対して常に定義されるグループのセットを確立することです。後のコメントから、この動作は予期しないものでした。これが明らかに原因です。

于 2012-08-10T03:08:13.487 に答える