1.登录
1.1准备登录页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>源码智销系统</title>
<%@ include file="/WEB-INF/views/head.jsp"%>
</head>
<body>
<div align="center" style="margin-top: 100px;">
<div class="easyui-panel" title="智销系统用户登陆" style="width: 350px; height: 240px;">
<form id="loginForm" class="easyui-form" method="post">
<table align="center" style="margin-top: 15px;">
<tr height="20">
<td>用户名:</td>
</tr>
<tr height="10">
<td><input name="username" class="easyui-validatebox" required="true" value="admin" /></td>
</tr>
<tr height="20">
<td>密 码:</td>
</tr>
<tr height="10">
<td><input name="password" type="password" class="easyui-validatebox" required="true" value="0" /></td>
</tr>
<tr height="40">
<td align="center"><a href="javascript:;" class="easyui-linkbutton" οnclick="submitForm();">登陆</a> <a
href="javascript:;" class="easyui-linkbutton" οnclick="resetForm();">重置</a></td>
</tr>
</table>
</form>
</div>
</div>
</body>
</html>
1.2LoginController
@Controller
public class LoginController {
//用于完成跳转
@RequestMapping(value="/login",method = RequestMethod.GET)
public String index(){
return "login";
}
//用于完成登录
@RequestMapping(value="/login",method = RequestMethod.POST)
public String login(String username,String password){
1.3修改applicationContext-shiro.xml
<!-- 5.shiro的真实过滤器(注:这个名称必需和web.xml的代表过滤器【DelegatingFilterProxy】名称一样) -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager"/>
<!-- 登录的url,如果没有登录,你访问的路径会跳到这个页面 -->
<property name="loginUrl" value="/login"/>
<!-- 登录成功的url,如果登录成功,会跳转到这个页面 -->
<property name="successUrl" value="/main"/>
<!-- 没有权限时跳转到这个位置 -->
<property name="unauthorizedUrl" value="/s/unauthorized.jsp"/>
<!-- 这个配置我们可以直接给一个map(动态的可以从代码中获取) -->
<property name="filterChainDefinitionMap" ref="filterChainDefinitionMap"></property>
</bean>
1.4设置静态放行
public class FilterChainDefinitionMapBuilder {
public Map<String,String> createFilterChainDefinitionMap(){
Map<String, String> filterChainDefinitionMap = new LinkedHashMap();
//注:对于一些不登录也可以放行的设置(大家可以根据实际情况添加)
filterChainDefinitionMap.put("/login","anon");
filterChainDefinitionMap.put("*.js","anon");
filterChainDefinitionMap.put("*.css","anon");
filterChainDefinitionMap.put("/css/**","anon");
filterChainDefinitionMap.put("/js/**","anon");
filterChainDefinitionMap.put("/easyui/**","anon");
filterChainDefinitionMap.put("/images/**","anon");
//这个值之后从数据库中查询到【用户-角色-权限-资源】
//filterChainDefinitionMap.put("/s/permission.jsp","perms[user:*]");
//filterChainDefinitionMap.put("/s/employee.jsp","perms[employee:*]");
filterChainDefinitionMap.put("/**","authc");
return filterChainDefinitionMap;
}
}
1.5密码加密
MD5加密
MD5Util:要有一套自己的密码规则(md5,10次,盐值:abc)
public class MD5Util {
public static final String SALT = "abc";
public static final Integer HASHITERATIONS = 10;
//密码加密
public static String changePwd(String password){
SimpleHash hash = new SimpleHash("MD5",password,SALT,HASHITERATIONS);
return hash.toHex();
}
}
添加用户密码加密
controller或者service中都可以进行[我们选择service]
@Override
public void save(Employee employee) {
if(employee.getId()==null){
//添加功能就进行密码修改
employee.setPassword(MD5Util.changePwd(employee.getPassword()));
}
employeeRepository.save(employee);
}
加密的判断必需和规则一致
applicationContext-shiro.xml(编码方式与次数)
<!-- 被引用的realm(一定会写一个自定义realm) -->
<bean id="jpaRealm" class="cn.itsource.aisell.shiro.JpaRealm">
<!-- 为这个realm设置相应的匹配器 -->
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!-- 设置加密方式 -->
<property name="hashAlgorithmName" value="md5"/>
<!-- 设置加密次数 -->
<property name="hashIterations" value="10" />
</bean>
</property>
</bean>
JpaRealm(加盐一致)
//身份认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//1.拿用户名与密码
UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
String username = token.getUsername();
//2.根据用户名拿到相应的对象
Employee loginUser = employeeService.findByUsername(username);
if(loginUser==null){
return null; //如果用户用空代表用户名不存在
}
String password = loginUser.getPassword();
//返回认证信息
//准备盐值
//传的第一个值就是主体(username名称做的主体)
ByteSource salt = ByteSource.Util.bytes(MD5Util.SALT);
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(username,password,salt,getName());
return authenticationInfo;
}
2.角色管理
先使用代码生成器生成Role,Permission
设置多对多的关系
role.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<%--引入相应的css与js--%>
<%@include file="/WEB-INF/views/head.jsp" %>
<script src="/js/model/role.js"></script>
</head>
<body>
<%--pagination:分页条支持--%>
<table id="roleGrid" class="easyui-datagrid"
data-options="url:'/role/page',fitColumns:true,singleSelect:true,fit:true,pagination:true,toolbar:'#gridTools'">
<thead>
<tr>
<th data-options="field:'name',width:20">姓名</th>
<th data-options="field:'sn',width:20">编码</th>
<th data-options="field:'permissions',width:100,formatter:permsFormat">权限</th>
</tr>
</thead>
</table>
<%--grid顶部工具栏--%>
<div id="gridTools" style="padding:5px;height:auto">
<%--功能条--%>
<div style="margin-bottom:5px">
<a href="#" data-method="add" class="easyui-linkbutton" iconCls="icon-add" plain="true">添加</a>
<a href="#" data-method="update" class="easyui-linkbutton" iconCls="icon-edit" plain="true">修改</a>
<a href="#" data-method="del" class="easyui-linkbutton" iconCls="icon-remove" plain="true">删除</a>
</div>
<%--查询条--%>
<form id="searchForm">
名称: <input name="name" class="easyui-textbox" style="width:80px">
<a href="#" data-method="search" class="easyui-linkbutton" iconCls="icon-search">查询</a>
</form>
</div>
<%--添加与修改的表单对话框--%>
<div id="editDialog" class="easyui-dialog" title="功能编辑" style="width:900px;"
data-options="iconCls:'icon-save',resizable:true,modal:true,closed:true">
<form id="editForm" method="post">
<input id="roleId" type="hidden" name="id"/>
<%--<table cellpadding="5">
<tr>
<td>--%>
名称:
<input class="easyui-validatebox" type="text" name="name"
data-options="required:true" />
编码:
<input class="easyui-validatebox" type="text" name="sn"
data-options="required:true" />
<%-- </td>
</tr>
<tr>
<td>--%>
<div id="cc" class="easyui-layout" style="width:100%;height:400px;">
<div data-options="region:'west'" style="width:440px;">
<table id="userPermissionGrid"></table>
</div>
<div data-options="region:'center'">
<table id="allPermissionGrid"></table>
</div>
</div>
<%-- </td>
</tr>
</table>--%>
</form>
<div style="text-align:center;padding:5px">
<a href="javascript:void(0)" class="easyui-linkbutton" data-method="save">提交</a>
<a href="javascript:void(0)" class="easyui-linkbutton" data-method="closeDialog">关闭</a>
</div>
</div>
</body>
</html><table id="roleGrid" class="easyui-datagrid" data-options="fit:true,fixed:true,fitColumns:true,toolbar:'#tb',singleSelect:true";
url="/role/page"
iconCls="icon-save"
rownumbers="true" pagination="true">
<thead>
<tr>
<th width="20" field="name" >名称</th>
<th width="20" field="sn" >编码</th>
<th width="20" field="permissions" data-options="formatter:formatperms">权限</th>
</tr>
</thead>
</table>
role.js
//对权限进行相应的格式化
function permsFormat(val){
var permsStr = "";
for (let o of val){
permsStr += o.name + " ";
}
return permsStr
}
$(function () {
//获取一些组件
var roleGrid = $("#roleGrid");
var searchForm = $("#searchForm");
var editDialog = $("#editDialog");
var editForm = $("#editForm");
//绑定事件
$("*[data-method]").on("click", function () {
var methodName = $(this).data("method");
window.work[methodName]();
});
work = {
//添加
add(){
//显示密码框
$("*[data-edit]").show();
$("*[data-edit] input").validatebox("enable");
//清空数据
editForm.form("clear");
//清空左边Grid角色的数据
userPermissionGrid.datagrid("loadData",[]);
//弹框居中
editDialog.dialog("center").dialog("open");
},
//修改
update(){
//获取到选中行数据
let row = roleGrid.datagrid("getSelected");
//若没有选中,给出提示,后面的代码不再执行
if(!row){
$.messager.alert('警告','没有选中行',"warning");
return ;
}
//清空form中的数据
editForm.form("clear");
//让密码框失效且隐藏起来
$("*[data-edit]").hide();
$("*[data-edit] input").validatebox("disable");
//结果回显
/*if(row.department){
row["department.id"] = row.department.id;
}*/
editForm.form("load",row);
//打开弹出框(居中)
editDialog.dialog("center").dialog("open");
//回显角色的权限,但是要拷贝一个数组,不然会修改原数据
var permissions = [...row.permissions];
userPermissionGrid.datagrid("loadData",permissions);
},
//保存
save(){
var url = "/role/save";
//获取ID
var roleId = $("#roleId").val();
if (roleId) {
url = "/role/update?cmd=_update"
}
//easyui的form提交
editForm.form('submit',{
url: url,
onSubmit: function (param) {
//获取左边角色的权限数据
var rows = userPermissionGrid.datagrid("getRows");
//遍历,拼接出响应的结构
for (var i = 0; i < rows.length; i++){
var row = rows[i];
param[`permissions[${i}].id`] = row.id;
}
return $(this).form('validate');
},
success:function(data){
var result = JSON.parse(data);
if(result.success){
roleGrid.datagrid("reload");
}else{
$.messager.alert('错误',`失败,原因: ${result.msg}`,"error");
}
//关闭弹出框
work.closeDialog();
}
});
},
// 删除
del(){
//获取选中行的数据
let row = roleGrid.datagrid("getSelected");
//若没有选中,给出提示,终止代码运行
if (!row){
$.messager.alert('警告','没有选中目标','warning');
return;
}
//确定是否删除
$.messager.confirm('确认','确定删除该选项吗',function (r) {
if(r){
//传选中行数据到后台
$.get('/role/delete',{id:row.id},function (res) {
//后台返回的数据
//根据后台返回数据,进行对应操作
if (res.success){
roleGrid.datagrid('reload')
}else {
$.messager.alert('错误',`删除失败,原因: ${res.msg}`,'warning');
}
})
}
})
},
//查询
search(){
var params = searchForm.serializeObject();
roleGrid.datagrid("load", params)
},
//关闭窗口
closeDialog(){
editDialog.dialog("close");
},
//双击添加权限
addPermission(index, row){
//获取左边角色权限的所有数据
var rows = userPermissionGrid.datagrid("getRows");
//循环,若和传来的row值一样就不执行后面代码
for (let o of rows){
if (o.id == row.id){
$.messager.show({
title:'提示',
msg:'角色已有该权限',
timeout:1000,
showType:'slide',
style:{
right:'',
top:document.body.scrollTop+document.documentElement.scrollTop,
bottom:''
}
});
return;
}
}
userPermissionGrid.datagrid("appendRow", row);
},
//双击删除权限
removePermission(index){
userPermissionGrid.datagrid("deleteRow", index);
}
};
//获取两个Grid
var userPermissionGrid = $("#userPermissionGrid");
var allPermissionGrid = $("#allPermissionGrid");
//创建角色对应的权限框
userPermissionGrid.datagrid({
fit:true,
fitColumns:true,
singleSelect:true,
columns:[[
{field:'name',title:'名称',width:100},
{field:'sn',title:'权限',width:100},
{field:'url',title:'资源',width:100}
]],
onDblClickRow:work.removePermission
});
//创建服务器有的权限框
allPermissionGrid.datagrid({
fit:true,
url:'/permission/page',
fitColumns:true,
singleSelect:true,
pagination:true,
columns:[[
{field:'name',title:'名称',width:100},
{field:'sn',title:'权限',width:100},
{field:'url',title:'资源',width:100}
]],
onDblClickRow:work.addPermission
});
});