十二、Shiro使用数据库表配置权限

本文详细介绍了如何在SpringBoot框架中使用Shiro进行权限管理,包括数据库授权、超级用户初始化及系统功能模块的管理。从数据库设计、权限类定义、Mybatis操作到控制器的模块跳转代码,全面展示了Shiro在实际项目中的应用。

Shiro作为权限控制框架,权限信息需要开发人员维护到数据库中,系统管理员根据需要将这些权限分配使用者,系统需要提供功能方便开发人员添加模块权限,系统管理员将权限分配给角色,再将角色分配给用户,用户登录系统时就可以使用自己分配的权限了。

Shiro硬编码测试权限过滤

GfShiroRealm中的权限过滤方法
	//角色权限和对应权限添加
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection)
	{
		//获取登录用户名
		String loginId= (String) principalCollection.getPrimaryPrincipal();
		//查询用户名称
		IUser user = orgmodel.getUserByLoginId(loginId);
		
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		//判断是否为超级管理员
//		if(IConstants.I_SYSTEM_USERID.equals(user.getId()))
//		{
//			for (Permission perm:orgmodel.getAdminPerm()) {
//				//添加权限
//				simpleAuthorizationInfo.addStringPermission(perm.getPermission());
//			}
//		}
//		else
		{
			
			//添加角色和权限
			//部门与角色,用户与角色关系表对应实体类IOrgUserRole
			List<DefaultOrgUserRole> roles = orgmodel.getOrgUserRoleByEntityId(user.getId());
			System.out.println("##############################doGetAuthorizationInfo roles==="+roles);
			simpleAuthorizationInfo.addStringPermission("url:org.action");
			simpleAuthorizationInfo.addStringPermission("url:orgroot.action");
			simpleAuthorizationInfo.addStringPermission("url:orgchild.action");
			
//			for (DefaultOrgUserRole role:roles) {
//				System.out.println("##############################roleid==="+role.getRoleId());
//				System.out.println("##############################orgmodel.getPermByRoleId(role.getRoleId())==="+orgmodel.getPermByRoleId(role.getRoleId()));
//				for (String perm:orgmodel.getPermByRoleId(role.getRoleId())) {
//					System.out.println("##############################perm==="+perm);
//					//添加权限
//					simpleAuthorizationInfo.addStringPermission(perm);
//				}
//			}
		}
		return simpleAuthorizationInfo;
	}

在这里插入图片描述
如果去掉硬编码
simpleAuthorizationInfo.addStringPermission(“url:org.action”);
simpleAuthorizationInfo.addStringPermission(“url:orgroot.action”);
simpleAuthorizationInfo.addStringPermission(“url:orgchild.action”);
再次访问,就出现非法访问
在这里插入图片描述

基于数据库授权

在这里插入图片描述

创建权限表

create table gf_permission(id varchar(32),
	modulename varchar(100),
	name varchar(100),
	permission varchar(100));

初始化数据(模块的权限数据需要开发人员提供到系统)

insert into gf_permission(id,modulename,name,permission)
	values('1','组织机构(部门)','部门页面','url:org.action');
insert into gf_permission(id,modulename,name,permission)
	values('2','组织机构(部门)','加载根部门','url:orgroot.action');
insert into gf_permission(id,modulename,name,permission)
	values('3','组织机构(部门)','加载下一级部门','url:orgchild.action');

创建角色权限中间表

create table gf_perm2role(id varchar(32),
	permid varchar(32),
	roleid varchar(32));

分配角色权限数据(生产环境系统管理员通过系统功能模块授权)

查出等于用户所具有的角色ID

insert into gf_perm2role(id,permid,roleid) values('role1','1','role5263d75084e7');
insert into gf_perm2role(id,permid,roleid) values('role2','2','role5263d75084e7');
insert into gf_perm2role(id,permid,roleid) values('role3','3','role5263d75084e7');

权限类

import org.apache.shiro.authz.annotation.RequiresPermissions;

public class PermissionInfo {
	private String id = null;
	private String moduleName = null;//组织机构部门
	private String name = null;//权限名称
	private String permission = null;//对应到Controller上的注解名称 @RequiresPermissions("url:orgsave.action")
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getModuleName() {
		return moduleName;
	}
	public void setModuleName(String moduleName) {
		this.moduleName = moduleName;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPermission() {
		return permission;
	}
	public void setPermission(String permission) {
		this.permission = permission;
	}	
}

权限角色中间表类

public class Perm2RoleInfo {
	private String id = null;
	private String permId = null;
	private String roleId = null;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPermId() {
		return permId;
	}
	public void setPermId(String permId) {
		this.permId = permId;
	}
	public String getRoleId() {
		return roleId;
	}
	public void setRoleId(String roleId) {
		this.roleId = roleId;
	}
	
}

Mybatis SQL

<!-- 权限表操作 -->
	<insert id="savePermission" parameterType="com.gf.statusflow.def.PermissionInfo">
		insert into gf_permission(id,modulename,name,permission)
			values(#{id},#{moduleName},#{name},#{permission})
	</insert>
	<update id="updatePermission" parameterType="com.gf.statusflow.def.PermissionInfo">
		update gf_permission set modulename=#{moduleName},name=#{name},permission=#{permission}
			where id=#{id}
	</update>
	<delete id="deletePermById" parameterType="String">
		delete from gf_permission where id=#{id}
	</delete>
	<delete id="deletePermByModule" parameterType="String">
		delete from gf_permission where modulename=#{moduleName}
	</delete>
	<select id="getPermission" resultType="com.gf.statusflow.def.PermissionInfo">
		select * from gf_permission
	</select>
	
	<!-- 权限与角色中间表 -->
	<insert id="savePerm2Role" parameterType="com.gf.statusflow.def.Perm2RoleInfo">
		insert into gf_perm2role(id,permid,roleid)
			values(#{id},#{permId},#{roleId})
	</insert>
	<delete id="deletePerm2RoleById" parameterType="String">
		delete from gf_perm2role where id=#{id}
	</delete>
	<delete id="deletePerm2RoleByRoleId" parameterType="String">
		delete from gf_perm2role where roleid=#{roleId}
	</delete>
	<select id="getPermByRoleId" resultType="String">
		select p.permission from gf_perm2role p2r,gf_permission p 
			where p2r.permid=p.id and p2r.roleid=#{roleId}
	</select>

Mapper层相关方法

/**
	 * Shiro权限相关Mybatis方法
	 */
	public void savePermission(PermissionInfo permission);
	public void updatePermission(PermissionInfo permission);
	public void deletePermById(@Param("id") String id);
	public void deletePermByModule(@Param("moduleName") String id);
	public List<PermissionInfo> getPermission();
	
	/**
	 * 角色与权限中间表Mybatis方法
	 */
	public void savePerm2Role(Perm2RoleInfo p2r);
	public void deletePerm2RoleById(@Param("id") String id);
	public void deletePerm2RoleByRoleId(@Param("roleId") String roleId);
	public List<String> getPermByRoleId(@Param("roleId") String roleId);

在OrgModelCtrl添加模块跳转代码

@RequestMapping("/module.action")
	public String module()
	{
		return "/orgmodel/module";
	}
	
	@RequestMapping("/moduleload.action")
	@ResponseBody
	public Map loadmodule(Integer page,Integer rows)
	{
		PageHelper.startPage(page, rows);
		List<PermissionInfo> lists = orgmodel.getPermission();
		PageInfo pi = new PageInfo(lists);
		Long total = pi.getTotal();
		List<PermissionInfo> perms = pi.getList();
		Map m = new HashMap();
		m.put("total", total);
		m.put("rows", perms);
		return m;
	}
	
	@RequestMapping("/modulesave.action")
	@ResponseBody
	public Boolean modulesave(PermissionInfo perm)
	{
		String id = perm.getId();
		if("".equals(Util.fmtStr(id)))
		{
			perm.setId(UUID.create("perm"));
			orgmodel.savePermission(perm);
		}
		else
			orgmodel.updatePermission(perm);
		return true;
	}
	
	@RequestMapping("/moduledelete.action")
	@ResponseBody
	public Boolean moduledelete(String[] id)
	{
		if(id != null)
		{
			for(String id2:id)
			{
				orgmodel.deletePermById(id2);
			}
		}
		return true;
	}

模块权限页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<script type="text/javascript" src="/static/easyui/jquery.min.js"></script>
<script type="text/javascript" src="/static/easyui/jquery.easyui.min.js"></script>
<script type="text/javascript" src="/static/easyui/easyui-lang-zh_CN.js"></script>
<link rel="stylesheet" href="/static/easyui/themes/default/easyui.css"/>
<link rel="stylesheet" href="/static/easyui/themes/icon.css"/>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>财务报销系统</title>
<script>

function addperm()
{
	$('#win').window('open');
}
function closeperm()
{
	$('#win').window('close');
}
function saveperm()
{
	var rtn = $('#frm').form('validate');
	if(rtn)
	{
		$('#frm').form('submit', {    
		    url:'/modulesave.action',    
		    onSubmit: function(){    
	  
		    },    
		    success:function(data){    
		    	$('#permdg').datagrid('reload');
		    	closeperm();
		    }    
		});
	}
}
function deleteperm()
{
	var objs = $('#permdg').datagrid('getChecked');
	var id = '';
	for(i=0;i<objs.length;i++)
		id = id + objs[i].id+ ',';
	$.ajax({
		url:'/moduledelete.action?id='+id,
		success:function(data)
		{
			$('#permdg').datagrid('reload');
		}
	})
}

$(document).ready(
		function()
		{
			$('#win').window('close');
		}
	);		
</script>
</head>
<body class="easyui-layout">
    <div data-options="region:'center',title:'模块维护'" style="padding:5px;">
		<table id="permdg" class="easyui-datagrid" style="width:100%;height:100%"   
		        data-options="url:'/moduleload.action',fitColumns:true,pagination:true,
		        pageSize:10,pageList:[10,50,100,200],toolbar:'#tb'">   
		    <thead>   
		        <tr>
		        	<th data-options="field:'id',width:100,checkbox:true">ID</th>   
		            <th data-options="field:'moduleName',width:100">模块名称</th>   
		            <th data-options="field:'name',width:100">权限名称</th>
		            <th data-options="field:'permission',width:100">权限代码</th>
		        </tr>   
		    </thead>   
		</table>
		<div id="tb">
			<a id="btn" onclick="addperm()" class="easyui-linkbutton" data-options="iconCls:'icon-add'">添加权限</a>
			<a id="btn" onclick="deleteperm()" class="easyui-linkbutton" data-options="iconCls:'icon-remove'">删除权限</a>
		</div>

		<div id="win" class="easyui-window" title="模块权限窗口" style="width:400px;height:280px"   
		        data-options="iconCls:'icon-save',modal:true">   
		    <div class="easyui-layout" data-options="fit:true">      
		        <div data-options="region:'center'">   
					<form id="frm" method="post">
						<input type="hidden" id="id" name="id"/>
					    <div style="margin-left:50px;margin-top:10px">      
					        <input class="easyui-textbox" type="text" id="moduleName" name="moduleName" data-options="width:250,label:'模块名称:'" />   
					    </div>
					    <div style="margin-left:50px;margin-top:10px">    
					        <input class="easyui-textbox" type="text" id="name" name="name" data-options="width:250,label:'权限名称:'" />
					    </div>
					    <div style="margin-left:50px;margin-top:10px">    
					        <input class="easyui-textbox" type="text" id="permission" name="permission" data-options="width:250,label:'权限代码:'" />
					    </div>
			  		    <div style="margin-left:50px;margin-top:30px"> 
							<a id="btn" onclick="saveperm()" class="easyui-linkbutton" data-options="iconCls:'icon-search'">保存</a>  
							<a id="btn" onclick="closeperm()" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-search'">关闭</a>    
					    </div>
					</form>
		        </div>   
		    </div>   
		</div>  
    </div>
</body>
</html>

在这里插入图片描述

系统超级用户初始化

系统超级用户通过硬编码实现初始化。

public interface IOrgModel
{
	public String I_SYSADMIN = "sysadmin";
	
	public void initDb();


@Component
public class DefaultOrgModel implements IOrgModel{
	private Logger log = LoggerFactory.getLogger(DefaultOrgModel.class);
	@Autowired
	private WorkflowMapper mapper;
	@Value("${orgmodel.sysadmin.pwd}")
	private String sysAdminPwd = null;
	
	public void initDb()
	{
		DefaultUser sysUser = mapper.getUserByLoginId(I_SYSADMIN);
		if(sysUser == null)
		{
			sysUser = new DefaultUser();
			sysUser.setId("1");
			sysUser.setLoginId(I_SYSADMIN);
			sysUser.setPassword(Util.getMD5(sysAdminPwd));
			sysUser.setName("系统管理员");
			mapper.saveUser(sysUser);
		}
		
	}

SpringBoot系统启动事件中初始化超级用户

package com.gf;

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

import com.gf.statusflow.IOrgModel;

public class ApplicationStartup implements ApplicationListener<ContextRefreshedEvent> {

	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
		IOrgModel orgmodel = event.getApplicationContext().getBean(IOrgModel.class);
		orgmodel.initDb();
		orgmodel.initFunc();
	}

}

启动类中配置事件监听

package com.gf;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Starter 
{
    public static void main( String[] args )
    {
    	SpringApplication springApplication = new SpringApplication(Starter.class);
    	springApplication.addListeners(new ApplicationStartup());
    	springApplication.run(args);
    }
}

Shiro超级用户添加全部权限

//角色权限和对应权限添加
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection)
	{
		//获取登录用户名
		String loginId= (String) principalCollection.getPrimaryPrincipal();
		//查询用户名称
		IUser user = orgmodel.getUserByLoginId(loginId);
		
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		//判断是否为超级管理员
		if(IOrgModel.I_SYSADMIN.equals(loginId))
		{
			for (PermissionInfo perm:orgmodel.getPermission()) {
				//添加权限
				simpleAuthorizationInfo.addStringPermission(perm.getPermission());
			}
		}
		else//普通用户获取权限列表
		{
			//添加角色和权限
			//部门与角色,用户与角色关系表对应实体类IOrgUserRole
			List<DefaultOrgUserRole> roles = orgmodel.getOrgUserRoleByEntityId(user.getId());
			for(DefaultOrgUserRole dour:roles)
			{
				for (String perm:orgmodel.getPermByRoleId(dour.getRoleId())) {
					//添加权限
					simpleAuthorizationInfo.addStringPermission(perm);
				}
			}
		}
		return simpleAuthorizationInfo;
	}

系统初始化默认功能模块

/**
	 * 初始化系统功能模块,包括(系统管理,用户管理,部门管理等模块)
	 * @return
	 */
	public FunctionInfo initFunc();
	/**
	 * 根据模块ID删除此模块,系统功能模块不可删除
	 * @param id
	 */
	public void deleteFunc(String id);
	public FunctionInfo getFuncById(String id);
}


	/**
	 * 初始化系统功能模块,包括(系统管理,用户管理,部门管理等模块)
	 * @return
	 */
	public FunctionInfo initFunc()
	{
		String rootId = "root";
		FunctionInfo root = getFuncById(rootId);
		if(root == null)
		{
			root = new FunctionInfo();
			root.setId(rootId);
			root.setName("功能模块");
			root.setParentId(null);
			this.saveFunc(root);
		}
		String sysId = "system";
		FunctionInfo sys = getFuncById(sysId);
		if(sys == null)
		{
			sys = new FunctionInfo();
			sys.setId(sysId);
			sys.setName("系统管理");
			sys.setIcon("pic_1");
			sys.setParentId(root.getId());
			sys.setPriority(1);
			this.saveFunc(sys);
		}
		String functionId = "function";
		FunctionInfo funmgr = getFuncById(functionId);
		if(funmgr == null)
		{
			funmgr = new FunctionInfo();
			funmgr.setId(functionId);
			funmgr.setName("功能管理");
			funmgr.setIcon("pic_2");
			funmgr.setParentId(sys.getId());
			funmgr.setUrl("/function.action");
			funmgr.setPriority(1);
			this.saveFunc(funmgr);
		}
		String orgmodelId = "orgmodel";
		FunctionInfo orgmodel = getFuncById(orgmodelId);
		if(orgmodel == null)
		{
			orgmodel = new FunctionInfo();
			orgmodel.setId(orgmodelId);
			orgmodel.setName("组织机构");
			orgmodel.setIcon("pic_3");
			orgmodel.setParentId(sys.getId());
			orgmodel.setPriority(2);
			this.saveFunc(orgmodel);
		}
		String orgId = "orgmodel_org";
		FunctionInfo org = getFuncById(orgId);
		if(org == null)
		{
			org = new FunctionInfo();
			org.setId(orgId);
			org.setName("部门管理");
			org.setIcon("pic_4");
			org.setParentId(orgmodel.getId());
			org.setUrl("/org.action");
			org.setPriority(2);
			this.saveFunc(org);
		}
		String userId = "orgmodel_user";
		FunctionInfo user = getFuncById(userId);
		if(user == null)
		{
			user = new FunctionInfo();
			user.setId(userId);
			user.setName("用户管理");
			user.setIcon("pic_5");
			user.setParentId(orgmodel.getId());
			user.setUrl("/user.action");
			user.setPriority(2);
			this.saveFunc(user);
		}
		String roleId = "orgmodel_role";
		FunctionInfo role = getFuncById(roleId);
		if(role == null)
		{
			role = new FunctionInfo();
			role.setId(roleId);
			role.setName("角色管理");
			role.setIcon("pic_5");
			role.setParentId(orgmodel.getId());
			role.setUrl("/role.action");
			role.setPriority(2);
			this.saveFunc(role);
		}
		String userroleId = "orgmodel_userrole";
		FunctionInfo userrole = getFuncById(userroleId);
		if(userrole == null)
		{
			userrole = new FunctionInfo();
			userrole.setId(userroleId);
			userrole.setName("角色分配");
			userrole.setIcon("pic_6");
			userrole.setParentId(orgmodel.getId());
			userrole.setUrl("/roleuser.action");
			userrole.setPriority(2);
			this.saveFunc(userrole);
		}
		String moduleId = "module";
		FunctionInfo module = getFuncById(moduleId);
		if(module == null)
		{
			module = new FunctionInfo();
			module.setId(moduleId);
			module.setName("模块权限");
			module.setIcon("pic_11");
			module.setParentId(sys.getId());
			module.setUrl("/module.action");
			module.setPriority(3);
			this.saveFunc(module);
		}
		return root;
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值