简易版数据库设计
关于权限的数据库设计:
1.用户与角色绑定,角色与权限绑定,权限与资源绑定
2.不想基于权限字符串管理:用户与角色绑定
3.不想基于角色管理:用户与权限绑定
4.不想让角色和权限关联:用户与角色绑定,用户与权限绑定
这里使用第一种,用户与角色多对多,角色与权限多对多,权限与资源一对一
用户表
角色表
权限表
用户角色表
角色权限表
实体类User
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private long id;
private String name;
private String pass;
private String salt;
//用户角色
private List<Role> roles;
}
mapper
//根据用户名查角色
User findRolesByName(String name);
<select id="findRolesByName" resultMap="userMap" >
SELECT
u.id,
u. NAME,
r.id rid,
r.`name` rname
FROM
test u
LEFT JOIN t_user_role ur ON u.id = ur.userid
LEFT JOIN t_role r ON r.id = ur.roleid
WHERE
u. name = #{name}
</select>
<resultMap id="userMap" type="cn.xx.shiroboot.entity.User">
<id column="id" property="id"/>
<result column="name" property="name"/>
<collection property="roles" javaType="list" ofType="cn.xx.shiroboot.entity.Role">
<id column="rid" property="name"/>
<result column="rname" property="name"></result>
</collection>
</resultMap>
service略
实体类Role
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Role {
private long id;
private String name;
//权限集合
private List<Per> pers;
}
mapper
//根据角色id查权限集合
List<Per> findPersByRoleId(long id);
<select id="findPersByRoleId" resultType="cn.xx.shiroboot.entity.Role">
SELECT
*
FROM
role r
LEFT JOIN t_role_per rp ON r.id = rp.roleid
LEFT JOIN t_per p ON p.id = rp.perid
WHERE
r.id = #{id}
</select>
service略
全部的自定义realm(授权角色信息和字符串权限控制)
public class CustomerRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
@Autowired
private RoleService roleService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//获取身份信息
String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
//根据身份信息获取角色和授权信息
User user = userService.findRolesByName(primaryPrincipal);
//授权角色信息
if (!CollectionUtils.isEmpty(user.getRoles())){
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//增加角色信息
user.getRoles().forEach(role->{
simpleAuthorizationInfo.addRole(role.getName());
//权限信息
List<Per> pers = roleService.findPersByRoleId(role.getId());
if (!CollectionUtils.isEmpty(pers)){
pers.forEach(per->{
simpleAuthorizationInfo.addStringPermission(per.getName());
});
}
});
return simpleAuthorizationInfo;
}
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String principal = (String) authenticationToken.getPrincipal();
//在工厂中获取service对象
/*UserService userService = (UserService) ApplicationContextUtil.getBean("userService");*/
System.out.println(userService);
User user = userService.findByName(principal);
if (!ObjectUtils.isEmpty(user)){
return new SimpleAuthenticationInfo(user.getName(),user.getPass(), ByteSource.Util.bytes(user.getSalt()),getName());
}
return null;
}
}
controller测试
/**
* 权限控制
*/
@RequestMapping("test")
//@RequiresRoles("admin")
@RequiresRoles(value = {"admin","user"}) //用来判断角色,同时具有
//@RequiresPermissions("user:update:shop") //用来判断权限字符串
public String test(){
/* //获取主体对象
Subject subject = SecurityUtils.getSubject();
//代码方式控制
if (subject.hasRole("admin")){
System.out.println("进去了");
}else {
System.out.println("没进去");
}
//权限字符串控制
if (subject.isPermitted("user:update:shop")){
System.out.println("进去了");
}else{
System.out.println("没进去");
}*/
return "redirect:/index.jsp";
}