gpt4 book ai didi

java - Hibernate Spring 安全修改设计如何

转载 作者:行者123 更新时间:2023-12-01 13:32:26 27 4
gpt4 key购买 nike

我正在设计一个我想要的数据库模型:

  • 用户(id、role_id)(用户详细信息)
  • 权限(role_id,权限)(GrantedAuthority)
  • 角色(ID、描述)

我正在使用 Hibernate 和 Spring 安全性。我希望每个角色都拥有使用 role_id 的权限列表(GrantedAuthorities),而不是特定用户拥有该权限。我有点迷失了设计。这是我到目前为止想到的:

public class User implements UserDetails, Serializable {

@Id
@GeneratedValue
@Column(name = "id")
private int id;
@Column(name = "role_id", insertable = true, updatable = false)
private int roleId;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "user", cascade = CascadeType.ALL)
private List<Permission> permissions;

}

public class Permission implements GrantedAuthority, Serializable {

@Id
@GeneratedValue
@Column(name = "id")
private int id;
@Column(name = "role_id", insertable = false, updatable = false)
private int roleId;
@Column(name = "permission")
private String permission;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "role_id", nullable = false, insertable = false, updatable = false)
private User user;

}

我省略了不太重要的代码。 Role 类对于 Spring 安全性并不重要。

我知道我在某个地方犯了一个巨大的错误,但我似乎不知道如何修复它。问题是它使用 user.id 而不是 user.roleId 连接这两个对象。我尝试了不同的注释,但我就是无法正确连接它。

所以原始问题可能是我试图使用一个对象的属性和另一个对象的 PK 来连接 2 个对象,这可能是一个错误。

编辑:我还尝试在 Permission 类上指定referencedColumnName,但它也不起作用。用户无法登录。

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "role_id", nullable = false, insertable = false, updatable = false, referencedColumnName = "role_id")
private User user;

最佳答案

为什么你想要一个在未来会适得其反的设计?您确实必须提前思考并在您的项目中应用良好的设计实践。这个话题几乎每天都会出现。

在 Spring 上下文中,角色实际上就是权限。我不知道为什么他们的设计如此复杂。您可以采用 1) 非常简单的方法,即分配一个实际上是用户权限的角色,或者 2) 更复杂的解决方案,其中包括用户角色和<强>许可。这个想法是将权限分配给角色并将角色分配给用户。在此解决方案中,角色实体仅用于将授予的权限分组为一个 bundle ,但通过身份验证管理器,您可以通过角色分配权限 .

注意:我为我的实体使用公共(public)基础@MappedSuperclass

首先,有一个用户实体:

@Entity
@Table(name = "user_t")
public class User extends BaseEntity {

@Column(name = "username", nullable = false, unique = true)
private String userName;

@Column(name = "password", nullable = false)
private String password;

@ManyToMany
@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private Set<Role> role = new HashSet<Role>();

// builder/getters/setters
}

角色实体

@Entity(name = "role_t")

@Column(name = "role_name", nullable = false)
private String roleName;

@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "role_permission", joinColumns = @JoinColumn(name = "role_id"), inverseJoinColumns = @JoinColumn(name = "permission_id"))
private Set<Permission> permissions;

// getters/setters
}

权限实体

@Entity(name = "permission_t")
public class Permission extends BaseEntity implements GrantedAuthority {

@Column (name = "permission_name", nullable = false)
private String permissionName;

public String getPermissionName() {
return permissionName;
}

public void setPermissionName(String permissionName) {
this.permissionName = permissionName;
}

@Override
public String getAuthority() {
return permissionName;
}

@Override
public int hashCode() {
return permissionName.hashCode();
}

@Override
public boolean equals(Object obj) {
if(obj == null) return false;
if(!(obj instanceof Permission)) return false;
return ((Permission) obj).getAuthority().equals(permissionName);
}

现在,在您的 AuthenticationManager 或您决定使用的任何内容中,您可以循环遍历角色,并将分配给角色的权限分配给用户(如果有意义的话)。

自定义身份验证提供程序

public class AppAuthProvider implements AuthenticationProvider {

private static final String PERMISSION_PREFIX = "ROLE_PERMISSION_";
// get the logging user info

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {


Collection<GrantedAuthority> permissions = new HashSet<GrantedAuthority>();
for (Role role : user.getRole()) {
for (Permission perm : role.getPermissions()) {
GrantedAuthority permission = new SimpleGrantedAuthority(PERMISSION_PREFIX + perm.getPermissionName());
permissions.add(permission);
}
}

UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(user, null, permissions); // user object you get from service/repository

return authToken;
}
}

关于java - Hibernate Spring 安全修改设计如何,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21487014/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com