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

被折叠的 条评论
为什么被折叠?



