shiro权限管理mysql_Shiro通过数据库配置后台管理项目权限

本文介绍了如何使用SpringBoot结合Shiro通过数据库配置实现后台管理项目的权限控制。通过创建用户、角色、权限、菜单等数据库表,利用Freemarker模板引擎动态生成前端菜单,以及Shiro配置动态添加权限标识,实现权限的动态管理。这种方式避免了手动添加Shiro标签和混淆权限标识的问题。
摘要由CSDN通过智能技术生成

前言

SpringBoot整合Shiro配置后台管理项目权限,普遍的方式是通过添加shiro标签在html文件里面,然后判断当前用户是否拥有当前权限,来确认是否展示当前菜单,shiro标签类似如下:

add用户

没有权限

权限与判断

这种方式缺点是需要手写所有菜单标签,也要加上对应的权限标识,在菜单列表比较多的时候,index页面会显得很臃肿,而且自己也容易混淆其中的权限标识。上次看了同事管理权限的方式,感觉很精妙,他是通过在数据库里面创建菜单表,关联权限表用户表,然后在进入index页面的时候,通过freemarker模板引擎,循环创建菜单表,这样一来,进入index页面之后,只会显示当前用户拥有权限的菜单。而且这种方式,在搭建好了后台配置之后,只需要手动的在数据库里面写入菜单名,index页面就会直接显示,这样不容易搞混淆。

后台搭建

数据库表

1.user表

e3c8a1e405e4

2.user_role表

e3c8a1e405e4

3.role表

e3c8a1e405e4

4.permission表

e3c8a1e405e4

5.role_permission表

e3c8a1e405e4

6.menu表

e3c8a1e405e4

代码

1.Controller

@GetMapping("/index")

public String login(Model model) {

//获取当前用户名得到菜单

Subject subject = SecurityUtils.getSubject();

if(!subject.isAuthenticated()) {

return "/login";

}

//根据当前登录账号来获取当前当前账号所拥有权限的菜单列表

String username = subject.getPrincipal().toString();

List menuTree = menuService.findMenuTreeByUsername(username);

model.addAttribute("menuTree",menuTree);

return "index";

}

2.Service

public interface MenuService extends IService

List findMenuTreeByUsername(String username);

}

3.ServiceImpl

@Service

public class MenuServiceImpl extends ServiceImpl implements MenuService {

@Autowired

private MenuMapper menuMapper;

@Override

public List findMenuTreeByUsername(String username) {

return menuMapper.findMenuTreeByUsername(username);

}

}

4.Mapper

public interface MenuMapper extends BaseMapper

/***

* 根据用户名获取菜单树

* @param username

* @return

*/

List findMenuTreeByUsername(@Param("username")String username);

}

5.Xml

select pm.id,pm.menu_name,pm.menu_icon,m.id mid,m.menu_name mname,m.menu_url murl

from user u

inner join user_role ur on u.id=ur.user_id

inner join role role on ur.role_id=role.id

inner join role_permission rp on role.id=rp.role_id

inner join permission p on rp.permission_id=p.id

inner join menu m on p.menu_id=m.id

inner join menu pm on m.menu_id=pm.id

where u.username=#{username}

6.VO对象

@Data

public class Menus {

private Long menuId;

private String menuName;

private String menuUrl;

private String menuIcon;

private List subMenus;

}

前端页面生成菜单列表

//此处是通过freemarker模板引擎生成,用thymeleaf的话也是可以的

menuTree

${menus.menuName}

${s.menuName}

#list><

/dl>

#list>

Shiro配置

1.ShiroConfig添加权限标识

ShiroConfig文件里面,通过查询在数据库里配置的全选标识,给所有的需要权限的资源添加权限标识,同时,通过这种方式,直接省略了在每个接口上面添加@RequiresPermissions("user:add")类似的注解。

/**

* 定义shiroFilter过滤器并注入securityManager

* @param manager

* @return

*/

@Bean("shiroFilter") //必须叫这个。

public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager) {

ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();

//设置securityManager

bean.setSecurityManager(manager);

//设置登录页面

bean.setLoginUrl("/login");

bean.setSuccessUrl("/index");

bean.setUnauthorizedUrl("/auth.html");

//定义过滤器

LinkedHashMap filterChainDefinitionMap = new LinkedHashMap<>();

//配置记住我或认证通过可以访问的地址

filterChainDefinitionMap.put("/index", "anon");

filterChainDefinitionMap.put("/login", "anon");

filterChainDefinitionMap.put("/static/**", "anon");

filterChainDefinitionMap.put("/swagger-ui.html", "anon");

filterChainDefinitionMap.put("/swagger-resources", "anon");

filterChainDefinitionMap.put("/swagger-resources/configuration/security", "anon");

filterChainDefinitionMap.put("/swagger-resources/configuration/ui", "anon");

filterChainDefinitionMap.put("/api/**", "anon");

//通过查询在数据库里面的权限标识,循环给自己设定的字段添加标识权限

List list = permissionMapper.getAll();

for (Permission permission : list) {

filterChainDefinitionMap.put(permission.getResource(), "perms["+permission.getSn()+"]");

}

//需要登录访问的资源 , 一般将/**放在最下边

filterChainDefinitionMap.put("/**", "anon"); // , 不需要认证。

bean.setFilterChainDefinitionMap(filterChainDefinitionMap);

return bean;

}

permissionMapper

public interface PermissionMapper extends BaseMapper {

List getPermissionsByUserName(@Param("username")String username);

List getAll();

}

Xml

select * from permission

2.AuthRealm授权

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

log.info("Shiro开始授权操作");

String username = SecurityUtils.getSubject().getPrincipal().toString();

SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

Set roles=new HashSet<>();

//得到一个用户的所有角色

List rolesList = roleMapper.getRolesByUserName(username);

for (Role role : rolesList) {

roles.add(role.getRoleName());

}

//得到一个用户的所有权限,给当前用户授权

List permissionsList = permissionMapper.getPermissionsByUserName(username);

for (Permission permission : permissionsList) {

authorizationInfo.addStringPermission(permission.getSn());

}

authorizationInfo.setRoles(roles);

return authorizationInfo;

}

Mapper

public interface RoleMapper extends BaseMapper {

List getRolesByUserName(@Param("username")String username);

}

Xml

select

r.id,

r.role_name,

r.remake

from role r

left join user_role ur on ur.role_id=r.id

left join user u on u.id=ur.user_id

where u.username=#{username}

Xml

select

p.id id,

p.permission_name,

p.resource resource,

p.sn sn,

p.menu_id

from permission p

left join role_permission rp on rp.permission_id=p.id

left join role r on r.id=rp.role_id

left join user_role ur on ur.role_id=r.id

left join user u on u.id=ur.user_id

where u.username=#{username}

总结

参考表数据

menu

e3c8a1e405e4

permission表

e3c8a1e405e4

role_permission

e3c8a1e405e4

role

e3c8a1e405e4

role_user

e3c8a1e405e4

user

e3c8a1e405e4

前端页面效果

e3c8a1e405e4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值