如何使用带有用户、组和权限的简单权限系统的 JPA?

发布于 2024-12-02 15:14:51 字数 347 浏览 3 评论 0原文

我想构建一个简单的 ORM/数据库权限系统,其中我有用户、组和权限:

  • 每个用户可以是多个组的成员,每个组可以有多个用户作为成员。
  • 用户和组之间的每个关系都有一条附加信息:权限。

这个想法是每个用户在每个组中可以拥有不同的权限。

我的实体应该是什么样子,这样我就可以

  • 从“组视图”(例如“检索该组的所有成员”)
  • 和“用户视图”(例如“检索该用户所属的所有组”)
  • 以及“给定这个” 中查询内容用户和这个组,用户有哪些权限”?

我使用带有 JPA2 注释和 EclipseLink 的 Java 6。

I would like to build a simple ORM/database permission system where I have users, groups and rights:

  • Each user can be a member of multiple groups, every group can have multiple users as members.
  • Each relationship between user and group has an additional piece of information: rights.

The idea is that each user can have different rights in each group.

How should my entities look like so I can query things

  • from the "group view" like "retrieve all members of this group"
  • and the "user view" like "retrieve all groups this user is a member in"
  • as well as "given this user and this group, which rights does the user have"?

I'm using Java 6 with JPA2 annotations and EclipseLink.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

遇到 2024-12-09 15:14:51

我想您可能想看看应用程序服务器社区已经提供的实现。一般来说,您所描述的是基于表单的身份验证的定义。

http://tomcat.apache.org/tomcat-5.5-doc/config /realm.html

基本上来说,关系是:

    User
      + Role[]

配置完成后,它允许诸如 JSF 之类的框架(但您会注意到我正在此处访问 Tomcat 会话)查询特定角色。下面的代码取自我在一个小型网络应用程序上的基于表单的基本身份验证方案,它迫切需要重构,我只是有更高的优先级

public boolean isUserInRole(Roles role)
  {
    return FacesContext.getCurrentInstance().getExternalContext().isUserInRole(role.getRoleValue()); 
  }

在这种情况下,角色是一个(命名不佳)枚举类型存储在我的“角色”实体中:

@Entity
@Table(name = "role", uniqueConstraints = @UniqueConstraint(columnNames = { "user_user", "role" }))
public class Role implements Serializable
{
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @ManyToOne(targetEntity = User.class, fetch = FetchType.LAZY)
    private User user;
    private String role;

    public Long getId()
    {
        return id;
    }

    public void setId(Long id)
    {
        this.id = id;
    }

    public User getUser()
    {
        return user;
    }

    public void setUser(User user)
    {
        this.user = user;
    }

    public String getRole()
    {
        return role;
    }

    public void setRole(String role)
    {
        this.role = role;
    }
}

这最终会创建表(如我指定的字段),以便我可以向配置提供 SQL 查询并创建一个领域。如果你谷歌“j_security_check”,有很多关于这方面的好文档。

至于团体?对我来说,一个组听起来像是角色的集合,因此修改对第三个表的查询或简单地提供一个枚举并不困难。

(读完本文后,唯一需要澄清的是,我的角色存储在一个枚举中,其中包含角色的字符串值,因此 Roles.getValue() 返回一个类似“administrators”的字符串。

I think you might want to look at implementations already provided by the application server community. Typically speaking, what you've described is a definition of form based authentication.

http://tomcat.apache.org/tomcat-5.5-doc/config/realm.html

Basically speaking, the relationship is:

    User
      + Role[]

Once configured this allows frameworks such as JSF (but you'll notice I'm accessing the Tomcat session here) to query for a specific role. The code below is taken from a basic form-based authentication scheme I have on a small web-app, and it is in dire need of refactoring, I've just had higher priorities

public boolean isUserInRole(Roles role)
  {
    return FacesContext.getCurrentInstance().getExternalContext().isUserInRole(role.getRoleValue()); 
  }

In this case Roles is a (poorly named) enum type that is stored in my "Role" Entity:

@Entity
@Table(name = "role", uniqueConstraints = @UniqueConstraint(columnNames = { "user_user", "role" }))
public class Role implements Serializable
{
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @ManyToOne(targetEntity = User.class, fetch = FetchType.LAZY)
    private User user;
    private String role;

    public Long getId()
    {
        return id;
    }

    public void setId(Long id)
    {
        this.id = id;
    }

    public User getUser()
    {
        return user;
    }

    public void setUser(User user)
    {
        this.user = user;
    }

    public String getRole()
    {
        return role;
    }

    public void setRole(String role)
    {
        this.role = role;
    }
}

This ends up creating the tables (as I specified the fields) so I can provide an SQL query to the configuration and create a realm. There's a lot of good documentation on this if you Google "j_security_check".

As to a group? A group sounds like a collection of roles to me--so it isn't a stretch to modify the query to a third table, or simply provide an enum.

(after reading this, the only clarification is that my roles are stored in an enum which contains the string value of the role, so roles.getValue() returns a string like "administrators".

峩卟喜欢 2024-12-09 15:14:51

我正在考虑

用户表
组表
User_is_in_group 链接表

权限表。
User_in_group_has_Rights 表。

然后将所有链接映射到 JPA 中的相关字段。

我可以做更多细节,但也许这足以让您创建实体,因为它还取决于您想要的字段。

I'm thinking

A User table
A Group table
A User_is_in_group link table

A Rights table.
A User_in_group_has_Rights table.

Then map all the links to the relevant fields in JPA.

I can do more detail, but maybe this is enough for you to create your entities, as it will also depend on what fields you want.

思慕 2024-12-09 15:14:51

下面是一个包含三个表(user、group 和 user_group)的示例:

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

    private static final long serialVersionUID = 1L;

    private Long id;
    private String name;
    private String email;
    private String password;
    private List<Grupo> groups; //-> a lot of rules and permissions

    public Usuario(){
    }

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Column
    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Column
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    /** Here is the third table **/
    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name="user_group", joinColumns = @JoinColumn(name="user_id"),
                              inverseJoinColumns = @JoinColumn(name="group_id"))
    public List<Grupo> getGroups() {
        return groups;
    }

    public void setGroups(List<Grupo> groups) {
        this.groups = groups;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Usuario other = (Usuario) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }

}

//////////////////////

@Entity
@Table(name="group")
public class Group {

    private Long id;
    private String name;
    private String description;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Grupo other = (Grupo) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }

}

Here goes a example with three tables (user, group and user_group):

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

    private static final long serialVersionUID = 1L;

    private Long id;
    private String name;
    private String email;
    private String password;
    private List<Grupo> groups; //-> a lot of rules and permissions

    public Usuario(){
    }

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Column
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Column
    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Column
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    /** Here is the third table **/
    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name="user_group", joinColumns = @JoinColumn(name="user_id"),
                              inverseJoinColumns = @JoinColumn(name="group_id"))
    public List<Grupo> getGroups() {
        return groups;
    }

    public void setGroups(List<Grupo> groups) {
        this.groups = groups;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Usuario other = (Usuario) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }

}

//////////////////////

@Entity
@Table(name="group")
public class Group {

    private Long id;
    private String name;
    private String description;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Grupo other = (Grupo) obj;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        return true;
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文