SSM——用户、角色、权限操作
1. 数据库与表结构
1.1 用户表
1.1.1 用户表信息描述 users
1.1.2 sql语句
CREATE TABLE users(
id varchar2(32) default SYS_GUID() PRIMARY KEY,
email VARCHAR2(50) UNIQUE NOT NULL,
username VARCHAR2(50),
PASSWORD VARCHAR2(50),
phoneNum VARCHAR2(20),
STATUS INT
)
1.1.3 实体类
public class UserInfo {
private String id;
private String username;
private String email;
private String password;
private String phoneNum;
private int status;
private String statusStr;
private List<Role> roles;
}
1.2 角色表
1.2.1 角色表信息描述 role
1.2.2 sql语句
CREATE TABLE role(
id varchar2(32) default SYS_GUID() PRIMARY KEY,
roleName VARCHAR2(50) ,
roleDesc VARCHAR2(50)
)
1.2.3 实体类
public class Role {
private String id;
private String roleName;
private String roleDesc;
private List<Permission> permissions;
private List<User> users;
}
1.2.4 用户与角色关联关系
用户与角色之间是多对多关系,我们通过 user_role 表来描述其关联,在实体类中 User 中存在 List ,在 Role 中有 List.
而角色与权限之间也存在关系,我们会在后面介绍
CREATE TABLE users_role(
userId varchar2(32),
roleId varchar2(32),
PRIMARY KEY(userId,roleId),
FOREIGN KEY (userId) REFERENCES users(id),
FOREIGN KEY (roleId) REFERENCES role(id)
)
1.3 资源权限表
1.3.1 权限资源表描述 permission
1.3.2 sql语句
CREATE TABLE permission(
id varchar2(32) default SYS_GUID() PRIMARY KEY,
permissionName VARCHAR2(50) ,
url VARCHAR2(50)
)
1.3.3 实体类
public class Permission {
private String id;
private String permissionName;
private String url;
private List<Role> roles;
}
1.3.4. 权限资源与角色关联关系
权限资源与角色是多对多关系,我们使用 role_permission 表来描述。在实体类 Permission 中存在 List, 在 Role 类中有List
CREATE TABLE role_permission(
permissionId varchar2(32),
roleId varchar2(32),
PRIMARY KEY(permissionId,roleId),
FOREIGN KEY (permissionId) REFERENCES permission(id),
FOREIGN KEY (roleId) REFERENCES role(id)
)
2.Spring Security 概述
2.1 Spring Security 介绍
Spring Security 的前身是 Acegi Security ,是 Spring 项目组中用来提供安全认证服务的框架。
( https://projects.spring.io/spring-security/ ) Spring Security 为基于 J2EE 企业应用软件提供了全面安全服务。特别是使用领先的J2EE 解决方案 -Spring 框架开发的企业软件项目。人们使用 Spring Security 有很多种原因,不过通常吸引他们的是在J2EE Servlet 规范或 EJB 规范中找不到典型企业应用场景的解决方案。 特别要指出的是他们不能再WAR 或 EAR 级别进行移植。这样,如果你更换服务器环境,就要,在新的目标环境进行大量的工作,对你的应用系统进行重新配 置安全。使用Spring Security 解决了这些问题,也为你提供很多有用的,完全可以指定的其他安全特性。 安全包括两个主要操作。
“ 认证 ” ,是为用户建立一个他所声明的主体。主题一般式指用户,设备或可以在你系 统中执行动作的其他系统。
“ 授权 ” 指的是一个用户能否在你的应用中执行某个操作,在到达授权判断之前,身份的主题已经由 身份验证过程建立了。
这些概念是通用的,不是 Spring Security 特有的。在身份验证层面, Spring Security 广泛支持各种身份验证模式,这些验证模型绝大多数都由第三方提供,或则正在开发的有关标准机构提供的,例如 Internet Engineering Task Force.作为补充, Spring Security 也提供了自己的一套验证功能。
Spring Security 目前支持认证一体化如下认证技术: HTTP BASIC authentication headers ( 一个基于 IEFT RFC 的标准) HTTP Digest authentication headers ( 一个基于 IEFT RFC 的标准 ) HTTP X.509 client certifificate exchange(一个基于 IEFT RFC 的标准 ) LDAP ( 一个非常常见的跨平台认证需要做法,特别是在大环境 ) Form-based authentication (提供简单用户接口的需求 ) OpenID authentication Computer Associates Siteminder JA-SIG Central Authentication Service (CAS,这是一个流行的开源单点登录系统 ) Transparent authentication context propagation for Remote Method Invocation and HttpInvoker (一个 Spring 远程调用协议 )
Maven 依赖
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.0.1.RELEASE</version>
</dependency>
</dependencies>
2.2 Spring Security 快速入门
2.2.1 pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-
instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-
4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>spring_security_demo</groupId>
<artifactId>SpringSecurity_quickStart</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<spring.version>5.0.2.RELEASE</spring.version>
<spring.security.version>5.0.1.RELEASE</spring.security.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- java编译插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<!-- 指定端口 -->
<port>8080</port>
<!-- 请求路径 -->
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.2.2 web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-security.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.2.3 spring security 配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<security:http auto-config="true" use-expressions="false">
<!-- intercept-url定义一个过滤规则 pattern表示对哪些url进行权限控制,ccess属性表示在请求对应
的URL时需要什么权限,
默认配置时它应该是一个以逗号分隔的角色列表,请求的用户只需拥有其中的一个角色就能成功访问对应
的URL -->
<security:intercept-url pattern="/**" access="ROLE_USER" />
<!-- auto-config配置后,不需要在配置下面信息 <security:form-login /> 定义登录表单信息
<security:http-basic
/> <security:logout /> -->
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="user" password="{noop}user"
authorities="ROLE_USER" />
<security:user name="admin" password="{noop}admin"
authorities="ROLE_ADMIN" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
2.2.4 测试
我们在 webapp 下创建一个 index.html 页面,在页面中任意写些内容。
当我们访问 index.html 页面时发现会弹出登录窗口,可能你会奇怪,我们没有建立下面的登录页面,为什么 Spring Security会跳到上面的登录页面呢?这是我们设置 http 的 auto-confifig=”true” 时 Spring Security 自动为我们生成的。
2.2.5 使用自定义页面
2.2.5.1 spring-security.xml 配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd">
<!-- 配置不过滤的资源(静态资源及登录相关) -->
<security:http security="none" pattern="/login.html" />
<security:http security="none" pattern="/failer.html" />
<security:http auto-config="true" use-expressions="false">
<!-- 配置资料连接,表示任意路径都需要ROLE_USER权限 -->
<security:intercept-url pattern="/**" access="ROLE_USER" />
<!-- 自定义登陆页面,login-page 自定义登陆页面 authentication-failure-url 用户权限校验失败之
后才会跳转到这个页面,如果数据库中没有这个用户则不会跳转到这个页面。
default-target-url 登陆成功后跳转的页面。 注:登陆页面用户名固定 username,密码
password,action:login -->
<security:form-login login-page="/login.html"
login-processing-url="/login" username-parameter="username"
password-parameter="password" authentication-failure-url="/failer.html"
default-target-url="/success.html"
/>
<!-- 登出, invalidate-session 是否删除session logout-url:登出处理链接 logout-successurl:登出成功页面
注:登出操作 只需要链接到 logout即可登出当前用户 -->
<security:logout invalidate-session="true" logout-url="/logout"
logout-success-url="/login.jsp" />
<!-- 关闭CSRF,默认是开启的 -->
<security:csrf disabled="true" />
</security:http>
<security:authentication-manager>
<security:authentication-provider>
<security:user-service>
<security:user name="user" password="{noop}user"
authorities="ROLE_USER" />
<security:user name="admin" password="{noop}admin"
authorities="ROLE_ADMIN" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
</beans>
2.2.5.2 login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="login" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username" /></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password" /></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="登录" />
<input type="reset" value="重置" /></td>
</tr>
</table>
</form>
</body>
</html>
2.2.5.3 success.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
success html<br>
<a href="logout">退出</a>
</body>
</html>
2.2.5.4 failer.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>登录失败
</body>
</html>
2.3 Spring Security 使用数据库认证
在 Spring Security 中如果想要使用数据进行认证操作,有很多种操作方式,这里我们介绍使用 UserDetails 、 UserDetailsService来完成操作。
UserDetails
public interface UserDetails extends Serializable {
Collection<? extends GrantedAuthority> getAuthorities();
String getPassword();
String getUsername();
boolean isAccountNonExpired();
boolean isAccountNonLocked();
boolean isCredentialsNonExpired();
boolean isEnabled();
}
UserDetails 是一个接口,我们可以认为 UserDetails 作用是于封装当前进行认证的用户信息,但由于其是一个接口,所以我们可以对其进行实现,也可以使用Spring Security 提供的一个 UserDetails 的实现类 User 来完成操作
以下是 User 类的部分代码
public class User implements UserDetails, CredentialsContainer {
private String password;
private final String username;
private final Set<GrantedAuthority> authorities;
private final boolean accountNonExpired; //帐户是否过期
private final boolean accountNonLocked; //帐户是否锁定
private final boolean credentialsNonExpired; //认证是否过期
private final boolean enabled; //帐户是否可用
}
UserDetailsService
public interface UserDetailsService {
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}
上面将 UserDetails 与 UserDetailsService 做了一个简单的介绍,那么我们具体如何完成 Spring Security 的数据库认证操作哪,我们通过用户管理中用户登录来完成Spring Security 的认证操作。
3. 用户管理
3.1 用户登录
spring security 的配置
<security:authentication-manager>
<security:authentication-provider user-service-ref="userService">
<!-- 配置加密的方式
<security:password-encoder ref="passwordEncoder"/>
-->
</security:authentication-provider>
</security:authentication-manager>
3.1.1. 登录页面 login.jsp
<%@ 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>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"><title>数据 - AdminLTE2定制版 | Log in</title><metacontent="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"name="viewport"><link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css">
</head><body class="hold-transition login-page"><div class="login-box"><div class="login-logo"><a href="all-admin-index.html"><b>ITCAST</b>后台管理系统</a></div><!-- /.login-logo --><div class="login-box-body"><p class="login-box-msg">登录系统</p><form action="${pageContext.request.contextPath}/login.do" method="post"><div class="form-group has-feedback"><input type="text" name="username" class="form-control"placeholder="用户名"> <spanclass="glyphicon glyphicon-envelope form-control-feedback"></span></div><div class="form-group has-feedback"><input type="password" name="password" class="form-control"placeholder="密码"> <spanclass="glyphicon glyphicon-lock form-control-feedback"></span></div><div class="row"><div class="col-xs-8"><div class="checkbox icheck"><label><input type="checkbox"> 记住 下次自动登录</label></div></div><!-- /.col --><div class="col-xs-4"><button type="submit" class="btn btn-primary btn-block btn-flat">登录</button></div><!-- /.col --></div></form><a href="#">忘记密码</a><br></div><!-- /.login-box-body --></div><!-- /.login-box --><!-- jQuery 2.2.3 --><!-- Bootstrap 3.3.6 --><!-- iCheck --><scriptsrc="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/iCheck/icheck.min.js"></script><script>$(function() {$('input').iCheck({checkboxClass : 'icheckbox_square-blue',radioClass : 'iradio_square-blue',increaseArea : '20%' // optional});});</script>
</body></html>
3.1.2.Service
public interface IUserService extends UserDetailsService{
}
@Service("userService")
@Transactional
public class UserServiceImpl implements IUserService {
@Autowired
private IUserDao userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserInfo userInfo = userDao.findByUsername(username);
List<Role> roles = userInfo.getRoles();
List<SimpleGrantedAuthority> authoritys = getAuthority(roles);
User user = new User(userInfo.getUsername(), "{noop}" + userInfo.getPassword(),
userInfo.getStatus() == 0 ? false : true, true, true, true, authoritys);
return user;
}
private List<SimpleGrantedAuthority> getAuthority(List<Role> roles) {
List<SimpleGrantedAuthority> authoritys = new ArrayList();
for (Role role : roles) {
authoritys.add(new SimpleGrantedAuthority(role.getRoleName()));
}
return authoritys;
}
}
3.1.3.IUserDao
public interface IUserDao {
@Select("select * from user where id=#{id}")
public UserInfo findById(Long id) throws Exception;
@Select("select * from user where username=#{username}")
@Results({
@Result(id = true, property = "id", column = "id"),
@Result(column = "username", property = "username"),
@Result(column = "email", property = "email"),
@Result(column = "password", property = "password"),
@Result(column = "phoneNum", property = "phoneNum"),
@Result(column = "status", property = "status"),
@Result(column = "id", property = "roles", javaType = List.class, many =
@Many(select = "com.itheima.ssm.dao.IRoleDao.findRoleByUserId")) })
public UserInfo findByUsername(String username);
}
3.2 用户退出
使用 spring security 完成用户退出,非常简单
配置
<security:logout invalidate-session="true" logout-url="/logout.do" logout-successurl="/login.jsp" />
页面中
<a href="${pageContext.request.contextPath}/logout.do"
class="btn btn-default btn-flat">注销</a>
3.3 用户查询
3.3.1. 用户查询页面 user-list.jsp
请在资料中查看具体代码
3.3.2.UserControlle
@Controller
@RequestMapping("/user")
public class UserControlller {
@RequestMapping("/findAll.do")
public ModelAndView findAll() throws Exception {
List<UserInfo> users = userService.findAll();
ModelAndView mv = new ModelAndView();
mv.addObject("userlist", users);
mv.setViewName("user-list");
return mv;
}
}
3.3.3.Dao
@Select("select * from user")
public List<UserInfo> findAll();
3.4 用户添加
3.4.1. 用户添加页面 user-add.jsp
<%@ 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>
<head>
<!-- 页面meta -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>数据 - AdminLTE2定制版</title>
<meta name="description" content="AdminLTE2定制版">
<meta name="keywords" content="AdminLTE2定制版"><!-- Tell the browser to be responsive to screen width -->
<metacontent="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"name="viewport"><link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/morris/morris.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/select2/select2.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/css/style.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.css">
</head><body class="hold-transition skin-purple sidebar-mini"><div class="wrapper"><!-- 页面头部 --><jsp:include page="header.jsp"></jsp:include><!-- 页面头部 /--><!-- 导航侧栏 --><jsp:include page="aside.jsp"></jsp:include><!-- 导航侧栏 /--><!-- 内容区域 --><div class="content-wrapper"><!-- 内容头部 --><section class="content-header"><h1>用户管理 <small>用户表单</small></h1><ol class="breadcrumb"><li><a href="${pageContext.request.contextPath}/index.jsp"><iclass="fa fa-dashboard"></i> 首页</a></li><li><ahref="${pageContext.request.contextPath}/user/findAll.do">用户管理</a></li><li class="active">用户表单</li></ol></section><!-- 内容头部 /--><form action="${pageContext.request.contextPath}/user/save.do"method="post"><!-- 正文区域 --><section class="content"> <!--产品信息--><div class="panel panel-default"><div class="panel-heading">用户信息</div><div class="row data-type"><div class="col-md-2 title">用户名称</div><div class="col-md-4 data"><input type="text" class="form-control" name="username"placeholder="用户名称" value=""></div><div class="col-md-2 title">密码</div><div class="col-md-4 data"><input type="password" class="form-control" name="password"placeholder="密码" value=""></div><div class="col-md-2 title">邮箱</div><div class="col-md-4 data"><input type="text" class="form-control" name="email"placeholder="邮箱" value=""></div><div class="col-md-2 title">联系电话</div><div class="col-md-4 data"><input type="text" class="form-control" name="phoneNum"placeholder="联系电话" value=""></div><div class="col-md-2 title">用户状态</div><div class="col-md-4 data"><select class="form-control select2" style="width: 100%"name="status"><option value="0" selected="selected">关闭</option><option value="1">开启</option></select></div></div></div><!--订单信息/--> <!--工具栏--><div class="box-tools text-center"><button type="submit" class="btn bg-maroon">保存</button><button type="button" class="btn bg-default"onclick="history.back(-1);">返回</button></div><!--工具栏/--> </section><!-- 正文区域 /--></form></div><!-- 内容区域 /--><!-- 底部导航 --><footer class="main-footer"><div class="pull-right hidden-xs"><b>Version</b> 1.0.8</div><strong>Copyright © 2014-2017 <ahref="http://www.itcast.cn">研究院研发部</a>.</strong> All rights reserved. </footer><!-- 底部导航 /--></div><scriptsrc="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/jQueryUI/jquery-ui.min.js"></script><script>$.widget.bridge('uibutton', $.ui.button);</script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/raphael/raphael-min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/morris/morris.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/sparkline/jquery.sparkline.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/knob/jquery.knob.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/daterangepicker/moment.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.zh-CN.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/datepicker/bootstrap-datepicker.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/slimScroll/jquery.slimscroll.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/fastclick/fastclick.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/iCheck/icheck.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/adminLTE/js/app.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/select2/select2.full.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/markdown.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/to-markdown.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/ckeditor/ckeditor.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.date.extensions.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.extensions.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/datatables/jquery.dataTables.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/chartjs/Chart.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/flot/jquery.flot.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/flot/jquery.flot.resize.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/flot/jquery.flot.pie.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/flot/jquery.flot.categories.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-slider/bootstrap-slider.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"></script><script>$(document).ready(function() {// 选择框$(".select2").select2();// WYSIHTML5编辑器$(".textarea").wysihtml5({locale : 'zh-CN'});});// 设置激活菜单function setSidebarActive(tagUri) {var liObj = $("#" + tagUri);if (liObj.length > 0) {liObj.parent().parent().addClass("active");liObj.addClass("active");}}</script></body></html>
3.4.2.UserController
@Controller
@RequestMapping("/user")
public class UserControlller {
@Autowired
private IUserService userService;
@RequestMapping("/save.do")
public String save(UserInfo user) throws Exception {
userService.save(user);
return "redirect:findAll.do";
}
}
3.4.3.Service
@Service("userService")
@Transactional
public class UserServiceImpl implements IUserService {
@Autowired
private IUserDao userDao;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public void save(UserInfo user) throws Exception {
user.setPassword(passwordEncoder.encode(user.getPassword()));
userDao.save(user);
}
}
前期我们的用户密码没有加密,现在添加用户时,我们需要对用户密码进行加密
<!-- 配置加密类 -->
<bean id="passwordEncoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
3.4. 4.Dao
@Insert("insert into user(email,username,password,phoneNum,status) value(#{email},#
{username},#{password},#{phoneNum},#{status})")
public void save(UserInfo user) throws Exception;
3.5 用户详情
3.5.1. 用户详情页面 user-show.jsp
请在资料中查看页面详细代码
注意:需要添加 js
$("#collapse-table").treetable({ expandable : true });
3.5.2.UserController
@Controller
@RequestMapping("/user")
public class UserControlller {
@Autowired
private IUserService userService;
@RequestMapping("/findById.do")
public ModelAndView findById(@RequestParam(name = "id", required = true) Long id) throws
Exception {
UserInfo user = userService.findById(id);
ModelAndView mv = new ModelAndView();
mv.addObject("user", user);
mv.setViewName("user-show");
return mv;
}
}
3.5.3.Dao
@Select("select * from user where id=#{id}")
@Results({ @Result(id = true, property = "id", column = "id"), @Result(column = "username",
property = "username"),
@Result(column = "email", property = "email"), @Result(column =
"password", property = "password"),
@Result(column = "phoneNum", property = "phoneNum"), @Result(column =
"status", property = "status"),
@Result(column = "id", property = "roles", javaType = List.class, many =
@Many(select = "com.itheima.ssm.dao.IRoleDao.findRoleByUserId")) })
public UserInfo findById(Long id) throws Exception;
@Select("select * from role where id in( select roleId from user_role where userId=#{userId})")
@Results(
{
@Result(id=true,column="id",property="id"),
@Result(column="roleName",property="roleName"),
@Result(column="roleDesc",property="roleDesc"),
@Result(column="id",property="permissions",javaType=List.class,many=@Many(select="com.itheima.ssm
.dao.IPermissionDao.findByRoleId"))
})
public List<Role> findRoleByUserId(Long userId);
我们需要将用户的所有角色及权限查询出来所以需要调用 IRoleDao 中的 fifindRoleByUserId, 而在 IRoleDao 中需要调用IPermissionDao 的 fifindByRoleId
@Select("select * from permission where id in (select permissionId from role_permission where
roleId=#{roleId})")
public List<Permission> findByRoleId(Long roleId);
4. 角色管理
4.1 角色查询
4.1.1. 角色页面 role-list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<!-- 页面meta -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"><title>数据 - AdminLTE2定制版</title>
<meta name="description" content="AdminLTE2定制版">
<meta name="keywords" content="AdminLTE2定制版"><!-- Tell the browser to be responsive to screen width -->
<metacontent="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"name="viewport"><link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/morris/morris.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/select2/select2.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/css/style.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css">
</head><body class="hold-transition skin-blue sidebar-mini"><div class="wrapper"><!-- 页面头部 --><jsp:include page="header.jsp"></jsp:include><!-- 页面头部 /--><!-- 导航侧栏 --><jsp:include page="aside.jsp"></jsp:include><!-- 导航侧栏 /--><!-- 内容区域 --><div class="content-wrapper"><!-- 内容头部 --><section class="content-header"><h1>角色管理 <small>全部角色</small></h1><ol class="breadcrumb"><li><a href="${pageContext.request.contextPath}/index.jsp"><iclass="fa fa-dashboard"></i> 首页</a></li><li><ahref="${pageContext.request.contextPath}/role/findAll.do">角色管理</a></li><li class="active">全部角色</li></ol></section><!-- 内容头部 /--><!-- 正文区域 --><section class="content"> <!-- .box-body --><div class="box box-primary"><div class="box-header with-border"><h3 class="box-title">列表</h3></div><div class="box-body"><!-- 数据表格 --><div class="table-box"><!--工具栏--><div class="pull-left"><div class="form-group form-inline"><div class="btn-group"><button type="button" class="btn btn-default" title="新建" onclick="location.href='${pageContext.request.contextPath}/pages/role-add.jsp'"><i class="fa fa-file-o"></i> 新建</button><button type="button" class="btn btn-default" title="刷新"><i class="fa fa-refresh"></i> 刷新</button></div></div></div><div class="box-tools pull-right"><div class="has-feedback"><input type="text" class="form-control input-sm"placeholder="搜索"> <spanclass="glyphicon glyphicon-search form-control-feedback"></span></div></div><!--工具栏/--><!--数据列表--><table id="dataList"class="table table-bordered table-striped table-hover dataTable"><thead><tr><th class="" style="padding-right: 0px"><inputid="selall" type="checkbox" class="icheckbox_square-blue"></th><th class="sorting_asc">ID</th><th class="sorting_desc">角色名称</th><th class="sorting_asc sorting_asc_disabled">描述</th> <th class="text-center">操作</th></tr></thead><tbody><c:forEach items="${roleList}" var="role"><tr><td><input name="ids" type="checkbox"></td><td>${role.id }</td><td>${role.roleName }</td><td>${role.roleDesc }</td> <td class="text-center"><a href="${pageContext.request.contextPath}/role/findById.do?id=${role.id}" class="btn bg-olive btn-xs">详情</a><a href="${pageContext.request.contextPath}/role/deleteRole.do?id=${role.id}" class="btn bg-olive btn-xs">删除角色</a><a href="${pageContext.request.contextPath}/role/findRoleByIdAndAllPermission.do?id=${role.id}" class="btn bg-olive btn-xs">添加权限</a></td></tr></c:forEach></tbody><!--<tfoot><tr><th>Rendering engine</th><th>Browser</th><th>Platform(s)</th><th>Engine version</th><th>CSS grade</th></tr></tfoot>--></table><!--数据列表/--></div><!-- 数据表格 /--></div><!-- /.box-body --><!-- .box-footer--><div class="box-footer"><div class="pull-left"><div class="form-group form-inline">总共2 页,共14 条数据。 每页 <select class="form-control"><option>1</option><option>2</option><option>3</option><option>4</option><option>5</option></select> 条</div></div><div class="box-tools pull-right"><ul class="pagination"><li><a href="#" aria-label="Previous">首页</a></li><li><a href="#">上一页</a></li><li><a href="#">1</a></li><li><a href="#">2</a></li><li><a href="#">3</a></li><li><a href="#">4</a></li><li><a href="#">5</a></li><li><a href="#">下一页</a></li><li><a href="#" aria-label="Next">尾页</a></li></ul></div></div><!-- /.box-footer--></div></section><!-- 正文区域 /--></div><!-- @@close --><!-- 内容区域 /--><!-- 底部导航 --><footer class="main-footer"><div class="pull-right hidden-xs"><b>Version</b> 1.0.8</div><strong>Copyright © 2014-2017 <ahref="http://www.itcast.cn">研究院研发部</a>.</strong> All rights reserved. </footer><!-- 底部导航 /--></div><script src="../plugins/jQuery/jquery-2.2.3.min.js"></script><script src="../plugins/jQueryUI/jquery-ui.min.js"></script><script>$.widget.bridge('uibutton', $.ui.button);</script><script src="../plugins/bootstrap/js/bootstrap.min.js"></script><script src="../plugins/raphael/raphael-min.js"></script><script src="../plugins/morris/morris.min.js"></script><script src="../plugins/sparkline/jquery.sparkline.min.js"></script><script src="../plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script><script src="../plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script><script src="../plugins/knob/jquery.knob.js"></script><script src="../plugins/daterangepicker/moment.min.js"></script><script src="../plugins/daterangepicker/daterangepicker.js"></script><script src="../plugins/daterangepicker/daterangepicker.zh-CN.js"></script><script src="../plugins/datepicker/bootstrap-datepicker.js"></script><scriptsrc="../plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script><scriptsrc="../plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script><script src="../plugins/slimScroll/jquery.slimscroll.min.js"></script><script src="../plugins/fastclick/fastclick.js"></script><script src="../plugins/iCheck/icheck.min.js"></script><script src="../plugins/adminLTE/js/app.min.js"></script><script src="../plugins/treeTable/jquery.treetable.js"></script><script src="../plugins/select2/select2.full.min.js"></script><script src="../plugins/colorpicker/bootstrap-colorpicker.min.js"></script><scriptsrc="../plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script><script src="../plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script><scriptsrc="../plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script><script src="../plugins/bootstrap-markdown/js/markdown.js"></script><script src="../plugins/bootstrap-markdown/js/to-markdown.js"></script><script src="../plugins/ckeditor/ckeditor.js"></script><script src="../plugins/input-mask/jquery.inputmask.js"></script><scriptsrc="../plugins/input-mask/jquery.inputmask.date.extensions.js"></script><script src="../plugins/input-mask/jquery.inputmask.extensions.js"></script><script src="../plugins/datatables/jquery.dataTables.min.js"></script><script src="../plugins/datatables/dataTables.bootstrap.min.js"></script><script src="../plugins/chartjs/Chart.min.js"></script><script src="../plugins/flot/jquery.flot.min.js"></script><script src="../plugins/flot/jquery.flot.resize.min.js"></script><script src="../plugins/flot/jquery.flot.pie.min.js"></script><script src="../plugins/flot/jquery.flot.categories.min.js"></script><script src="../plugins/ionslider/ion.rangeSlider.min.js"></script><script src="../plugins/bootstrap-slider/bootstrap-slider.js"></script><script>$(document).ready(function() {// 选择框$(".select2").select2();// WYSIHTML5编辑器$(".textarea").wysihtml5({locale : 'zh-CN'});});// 设置激活菜单function setSidebarActive(tagUri) {var liObj = $("#" + tagUri);if (liObj.length > 0) {liObj.parent().parent().addClass("active");liObj.addClass("active");}}$(document).ready(function() {// 激活导航位置setSidebarActive("admin-datalist");// 列表按钮 $("#dataList td input[type='checkbox']").iCheck({checkboxClass : 'icheckbox_square-blue',increaseArea : '20%'});// 全选操作 $("#selall").click(function() {var clicks = $(this).is(':checked');if (!clicks) {$("#dataList td input[type='checkbox']").iCheck("uncheck");} else {$("#dataList td input[type='checkbox']").iCheck("check");}$(this).data("clicks",!clicks);});});</script>
</body></html>
4.1.2.RoleControlller
@RequestMapping("/role")
@Controller
public class RoleController {
@Autowired
private IRoleService roleService;
@RequestMapping("/findAll.do")
public ModelAndView findAll() throws Exception {
List<Role> roleList = roleService.findAll();
ModelAndView mv = new ModelAndView();
mv.addObject("roleList", roleList);
mv.setViewName("role-list");
return mv;
}
4.1.3.Dao
@Select("select * from role")
public List<Role> findAll();
4.2 角色添加
4.2.1. 角色添加页面 role-add.jsp
请在页面中查看详细代码
4.2.2.RoleControlller
@RequestMapping("/role")
@Controller
public class RoleController {
@Autowired
private IRoleService roleService;
@RequestMapping("/save.do")
public String save(Role role) {
roleService.save(role);
return "redirect:findAll.do";
}
}
4.2.3.Dao
@Insert("insert into role(roleName,roleDesc) value(#{roleName},#{roleDesc})")
public void save(Role role);
5. 资源权限管理
5.1 资源权限查询
5.1.1. 权限资源页面 permission-list.jsp
请在资料中查看详细代码
5.1.2.PermissionControlle
@RequestMapping("/permission")
@Controller
public class PermissionController {
@Autowired
private IPermissionService permissionService;
@RequestMapping("/findAll.do")
public ModelAndView findAll() throws Exception {
List<Permission> permissionList = permissionService.findAll();
ModelAndView mv = new ModelAndView();
mv.addObject("permissionList", permissionList);
mv.setViewName("permission-list");
return mv;
}
}
5.1.3.Dao
@Select("select * from permission")
public List<Permission> findAll();
5.2 资源权限添加
5.2.1. 权限资源添加页面 permission-add.jsp
<%@ 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>
<head>
<!-- 页面meta -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>数据 - AdminLTE2定制版</title>
<meta name="description" content="AdminLTE2定制版">
<meta name="keywords" content="AdminLTE2定制版"><!-- Tell the browser to be responsive to screen width -->
<metacontent="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"name="viewport"><link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/morris/morris.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/select2/select2.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/css/style.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.css">
</head><body class="hold-transition skin-purple sidebar-mini"><div class="wrapper"><!-- 页面头部 --><jsp:include page="header.jsp"></jsp:include><!-- 页面头部 /--><!-- 导航侧栏 --><jsp:include page="aside.jsp"></jsp:include><!-- 导航侧栏 /--><!-- 内容区域 --><div class="content-wrapper"><!-- 内容头部 --><section class="content-header"><h1>资源权限管理 <small>资源权限表单</small></h1><ol class="breadcrumb"><li><a href="${pageContext.request.contextPath}/index.jsp"><iclass="fa fa-dashboard"></i> 首页</a></li><li><a href="${pageContext.request.contextPath}/permission/findAll.do">资源权限管理</a></li><li class="active">资源权限表单</li></ol></section><!-- 内容头部 /--><form action="${pageContext.request.contextPath}/permission/save.do"method="post"><!-- 正文区域 --><section class="content"> <!--产品信息--><div class="panel panel-default"><div class="panel-heading">资源权限信息</div><div class="row data-type"><div class="col-md-2 title">权限名称</div><div class="col-md-4 data"><input type="text" class="form-control" name="permissionName"placeholder="权限名称" value=""></div><div class="col-md-2 title">RUL</div><div class="col-md-4 data"><input type="text" class="form-control" name="url"placeholder="URL" value=""></div></div></div><!--订单信息/--> <!--工具栏--><div class="box-tools text-center"><button type="submit" class="btn bg-maroon">保存</button><button type="button" class="btn bg-default"onclick="history.back(-1);">返回</button></div><!--工具栏/--> </section><!-- 正文区域 /--></form></div><!-- 内容区域 /--><!-- 底部导航 --><footer class="main-footer"><div class="pull-right hidden-xs"><b>Version</b> 1.0.8</div><strong>Copyright © 2014-2017 <ahref="http://www.itcast.cn">研究院研发部</a>.</strong> All rights reserved. </footer><!-- 底部导航 /--></div><scriptsrc="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/jQueryUI/jquery-ui.min.js"></script><script>$.widget.bridge('uibutton', $.ui.button);</script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/raphael/raphael-min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/morris/morris.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/sparkline/jquery.sparkline.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/knob/jquery.knob.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/daterangepicker/moment.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.zh-CN.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/datepicker/bootstrap-datepicker.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/slimScroll/jquery.slimscroll.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/fastclick/fastclick.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/iCheck/icheck.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/adminLTE/js/app.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/select2/select2.full.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/markdown.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/to-markdown.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/ckeditor/ckeditor.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.date.extensions.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.extensions.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/datatables/jquery.dataTables.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/chartjs/Chart.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/flot/jquery.flot.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/flot/jquery.flot.resize.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/flot/jquery.flot.pie.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/flot/jquery.flot.categories.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-slider/bootstrap-slider.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"></script><script>$(document).ready(function() {// 选择框$(".select2").select2();// WYSIHTML5编辑器$(".textarea").wysihtml5({locale : 'zh-CN'});});// 设置激活菜单function setSidebarActive(tagUri) {var liObj = $("#" + tagUri);if (liObj.length > 0) {liObj.parent().parent().addClass("active");liObj.addClass("active");}}</script></body></html>
5.2.2.PermissionController
@RequestMapping("/permission")
@Controller
public class PermissionController {
@Autowired
private IPermissionService permissionService;
@RequestMapping("/save.do")
public String save(Permission p) throws Exception {
permissionService.save(p);
return "redirect:findAll.do";
}
}
5.2.3.Dao
@Insert("insert into permission(permissionName,url) value(#{permissionName},#{url})")
public void save(Permission p);
6. 权限关联与控制
6.1 用户角色关联
用户与角色之间是多对多关系,我们要建立它们之间的关系,只需要在中间表 user_role 插入数据即可。
6.1.1. 用户角色关联相关页面
在 user-list.jsp 页面上添加链接
<a href="${pageContext.request.contextPath}/user/findUserByIdAndAllRole.do?id=${user.id}"
class="btn bg-olive btn-xs">添加角色</a>
展示可以添加角色的页面 user-role-add.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<!-- 页面meta -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>数据 - AdminLTE2定制版</title>
<meta name="description" content="AdminLTE2定制版">
<meta name="keywords" content="AdminLTE2定制版"><!-- Tell the browser to be responsive to screen width -->
<metacontent="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"name="viewport"><link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/morris/morris.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/select2/select2.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/css/style.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.css">
</head><body class="hold-transition skin-purple sidebar-mini"><div class="wrapper"><!-- 页面头部 --><jsp:include page="header.jsp"></jsp:include><!-- 页面头部 /--><!-- 导航侧栏 --><jsp:include page="aside.jsp"></jsp:include><!-- 导航侧栏 /--><!-- 内容区域 --><div class="content-wrapper"><!-- 内容头部 --><section class="content-header"><h1>用户管理 <small>添加角色表单</small></h1><ol class="breadcrumb"><li><a href="${pageContext.request.contextPath}/index.jsp"><iclass="fa fa-dashboard"></i> 首页</a></li><li><ahref="${pageContext.request.contextPath}/user/findAll.do">用户管理</a></li><li class="active">添加角色表单</li></ol></section><!-- 内容头部 /--><formaction="${pageContext.request.contextPath}/user/addRoleToUser.do"method="post"><!-- 正文区域 --><section class="content"> <input type="hidden" name="userId" value="${user.id}"><table id="dataList"class="table table-bordered table-striped table-hover dataTable"><thead><tr><th class="" style="padding-right: 0px"><input id="selall" type="checkbox" class="icheckbox_square-blue"></th><th class="sorting_asc">ID</th><th class="sorting">角色名称</th><th class="sorting">角色描述</th> </tr></thead><tbody><c:forEach items="${roleList}" var="role"><tr><td><input name="ids" type="checkbox" value="${role.id}"></td><td>${role.id}</td><td>${role.roleName }</td><td>${role.roleDesc}</td></tr></c:forEach></tbody></table><!--订单信息/--> <!--工具栏--><div class="box-tools text-center"><button type="submit" class="btn bg-maroon">保存</button><button type="button" class="btn bg-default"onclick="history.back(-1);">返回</button></div><!--工具栏/--> </section><!-- 正文区域 /--></form></div><!-- 内容区域 /--><!-- 底部导航 --><footer class="main-footer"><div class="pull-right hidden-xs"><b>Version</b> 1.0.8</div><strong>Copyright © 2014-2017 <ahref="http://www.itcast.cn">研究院研发部</a>.</strong> All rights reserved. </footer><!-- 底部导航 /--></div><scriptsrc="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/jQueryUI/jquery-ui.min.js"></script><script>$.widget.bridge('uibutton', $.ui.button);</script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/raphael/raphael-min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/morris/morris.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/sparkline/jquery.sparkline.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/knob/jquery.knob.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/daterangepicker/moment.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.zh-CN.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/datepicker/bootstrap-datepicker.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/slimScroll/jquery.slimscroll.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/fastclick/fastclick.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/iCheck/icheck.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/adminLTE/js/app.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/select2/select2.full.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/markdown.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/to-markdown.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/ckeditor/ckeditor.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.date.extensions.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.extensions.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/datatables/jquery.dataTables.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/chartjs/Chart.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/flot/jquery.flot.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/flot/jquery.flot.resize.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/flot/jquery.flot.pie.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/flot/jquery.flot.categories.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-slider/bootstrap-slider.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"></script><script>$(document).ready(function() {// 选择框$(".select2").select2();// WYSIHTML5编辑器$(".textarea").wysihtml5({locale : 'zh-CN'});// 全选操作 $("#selall").click(function() {var clicks = $(this).is(':checked');if (!clicks) {$("#dataList td input[type='checkbox']").iCheck("uncheck");} else {$("#dataList td input[type='checkbox']").iCheck("check");}$(this).data("clicks", !clicks);});});// 设置激活菜单function setSidebarActive(tagUri) {var liObj = $("#" + tagUri);if (liObj.length > 0) {liObj.parent().parent().addClass("active");liObj.addClass("active");}}</script></body></html>
6.1.2.UserController
findUserByIdAndAllRole(Long id) 方法
此方法用于查找要操作的用户及可以添加的角色,参数是要操作的用户 id
@RequestMapping("/findUserByIdAndAllRole.do")
public ModelAndView findUserByIdAndAllRole(Long id) throws Exception {
UserInfo user = userService.findById(id);
List<Role> roleList = roleService.findOtherRole(id);
ModelAndView mv = new ModelAndView();
mv.addObject("user", user);
mv.addObject("roleList", roleList);
mv.setViewName("user-role-add");
return mv;
}
调用 IUserService 的 fifindById 方法获取要操作的 User
调用 IRoleService 的 fifindOtherRole 方法用于获取可以添加的角色信息
addRoleToUser(Long userId,Long[] ids) 方法些方法用于在用户与角色之间建立关系,参数userId 代表要操作的用户 id, 参数 ids 代表的是角色 id 数组
@RequestMapping("/addRoleToUser.do")
public String addRoleToUser(Long userId, Long[] ids) throws Exception {
userService.addRoleToUser(userId,ids);
return "redirect:findAll.do";
}
6.1.3.Dao
IRoleDao
@Select("select * from role where id not in( select roleId from user_role where userId=#
{id})")
public List<Role> findOtherRole(Long id);
用于查找可以添加的角色
IUserDao
@Insert("insert into user_role(userId,roleId) value(#{userId},#{roleId})")
public void addRoleToUser(@Param("userId") Long userId, @Param("roleId") Long roleId);
用于添加用户与角色关系
6.2 角色权限关联
角色与权限之间是多对多关系,我们要建立它们之间的关系,只需要在中间表 role_permission 插入数据即可。
6.2.1. 角色权限关联相关页面
在 role-list.jsp 页面上添加链接
<a href="${pageContext.request.contextPath}/role/findRoleByIdAndAllPermission.do?
id=${role.id}" class="btn bg-olive btn-xs">添加权限</a>
展示可以添加权限的页面 role-permission-add.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<!-- 页面meta -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>数据 - AdminLTE2定制版</title>
<meta name="description" content="AdminLTE2定制版">
<meta name="keywords" content="AdminLTE2定制版"><!-- Tell the browser to be responsive to screen width -->
<metacontent="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"name="viewport"><link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/ionicons/css/ionicons.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/iCheck/square/blue.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/morris/morris.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/datepicker/datepicker3.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.theme.default.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/select2/select2.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/adminLTE/css/AdminLTE.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/adminLTE/css/skins/_all-skins.min.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/css/style.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.skinNice.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-slider/slider.css">
<link rel="stylesheet"href="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.css">
</head><body class="hold-transition skin-purple sidebar-mini"><div class="wrapper"><!-- 页面头部 --><jsp:include page="header.jsp"></jsp:include><!-- 页面头部 /--><!-- 导航侧栏 --><jsp:include page="aside.jsp"></jsp:include><!-- 导航侧栏 /--><!-- 内容区域 --><div class="content-wrapper"><!-- 内容头部 --><section class="content-header"><h1>角色管理 <small>添加权限表单</small></h1><ol class="breadcrumb"><li><a href="${pageContext.request.contextPath}/index.jsp"><iclass="fa fa-dashboard"></i> 首页</a></li><li><ahref="${pageContext.request.contextPath}/role/findAll.do">角色管理</a></li><li class="active">添加权限表单</li></ol></section><!-- 内容头部 /--><formaction="${pageContext.request.contextPath}/role/addPermissionToRole.do"method="post"><!-- 正文区域 --><section class="content"> <input type="hidden" name="roleId" value="${role.id}"><table id="dataList"class="table table-bordered table-striped table-hover dataTable"><thead><tr><th class="" style="padding-right: 0px"><input id="selall" type="checkbox" class="icheckbox_square-blue"></th><th class="sorting_asc">ID</th><th class="sorting">权限名称</th><th class="sorting">权限URL</th></tr></thead><tbody><c:forEach items="${permissionList}" var="permission"><tr><td><input name="ids" type="checkbox" value="${permission.id}"></td><td>${permission.id}</td><td>${permission.permissionName }</td><td>${permission.url}</td></tr></c:forEach></tbody></table><!--订单信息/--> <!--工具栏--><div class="box-tools text-center"><button type="submit" class="btn bg-maroon">保存</button><button type="button" class="btn bg-default"onclick="history.back(-1);">返回</button></div><!--工具栏/--> </section><!-- 正文区域 /--></form></div><!-- 内容区域 /--><!-- 底部导航 --><footer class="main-footer"><div class="pull-right hidden-xs"><b>Version</b> 1.0.8</div><strong>Copyright © 2014-2017 <ahref="http://www.itcast.cn">研究院研发部</a>.</strong> All rights reserved. </footer><!-- 底部导航 /--></div><scriptsrc="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/jQueryUI/jquery-ui.min.js"></script><script>$.widget.bridge('uibutton', $.ui.button);</script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/raphael/raphael-min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/morris/morris.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/sparkline/jquery.sparkline.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/jvectormap/jquery-jvectormap-world-mill-en.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/knob/jquery.knob.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/daterangepicker/moment.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/daterangepicker/daterangepicker.zh-CN.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/datepicker/bootstrap-datepicker.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/slimScroll/jquery.slimscroll.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/fastclick/fastclick.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/iCheck/icheck.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/adminLTE/js/app.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/treeTable/jquery.treetable.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/select2/select2.full.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/colorpicker/bootstrap-colorpicker.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-wysihtml5/bootstrap-wysihtml5.zh-CN.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/bootstrap-markdown.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-markdown/locale/bootstrap-markdown.zh.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/markdown.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-markdown/js/to-markdown.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/ckeditor/ckeditor.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.date.extensions.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/input-mask/jquery.inputmask.extensions.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/datatables/jquery.dataTables.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/datatables/dataTables.bootstrap.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/chartjs/Chart.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/flot/jquery.flot.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/flot/jquery.flot.resize.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/flot/jquery.flot.pie.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/flot/jquery.flot.categories.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/ionslider/ion.rangeSlider.min.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-slider/bootstrap-slider.js"></script><scriptsrc="${pageContext.request.contextPath}/plugins/bootstrap-datetimepicker/bootstrap-datetimepicker.min.js"></script><script>$(document).ready(function() {// 选择框$(".select2").select2();// WYSIHTML5编辑器$(".textarea").wysihtml5({locale : 'zh-CN'});// 全选操作 $("#selall").click(function() {var clicks = $(this).is(':checked');if (!clicks) {$("#dataList td input[type='checkbox']").iCheck("uncheck");} else {$("#dataList td input[type='checkbox']").iCheck("check");}$(this).data("clicks", !clicks);});});// 设置激活菜单function setSidebarActive(tagUri) {var liObj = $("#" + tagUri);if (liObj.length > 0) {liObj.parent().parent().addClass("active");liObj.addClass("active");}}</script></body></html>
6.2.2.RoleController
findRoleByIdAndAllPermission(Long roleId) 方法
此方法用于查找要操作的角色及可以添加的权限,参数是要操作的角色 id
@RequestMapping("/findRoleByIdAndAllPermission.do")
public ModelAndView findRoleByIdAndAllPermission(@RequestParam(name = "id", required
= true) Long roleid)
throws Exception {
ModelAndView mv = new ModelAndView();
Role role = roleService.findById(roleid);
mv.addObject("role", role);
List<Permission> permissionList =
permissionService.findOtherPermission(roleid);
mv.addObject("permissionList", permissionList);
mv.setViewName("role-permission-add");
return mv;
}
调用 IRoleService 的 fifindById 方法获取要操作的 Role
调用 IPermissionService 的 fifindOtherPermission 方法用于获取可以添加的权限信息
addPermissionToRole(Long roleId,Long[] ids) 方法
些方法用于在角色与权限之间建立关系,参数 roleId 代表要操作的角色 id, 参数 permissionIds 代表的是权限 id数组
@RequestMapping("/addPermissionToRole.do")
public String addPermissionToRole(@RequestParam(name = "roleId") Long roleId,
@RequestParam(name = "ids") Long[] permissionIds) throws Exception {
roleService.addPermissionToRole(roleId, permissionIds);
return "redirect:findAll.do";
}
6.2.3.Dao
IPermissionDao
@Select("select * from permission where id not in (select permissionId from role_permission
where roleId=#{roleId})")
public List<Permission> findOtherPermission(Long roleid);
用于查找可以添加的权限
IRoleDao
@Insert("insert into role_permission (roleId,permissionId) value (#{roleId},#
{permissionId})")
public void addPermissionToRole(@Param("roleId") Long roleId, @Param("permissionId") Long
permissionId);
用于绑定角色与权限的关系
6.3 服务器端方法级权限控制
在服务器端我们可以通过 Spring security 提供的注解对方法来进行权限控制。 Spring Security 在方法的权限控制上支持三种类型的注解,JSR-250 注解、 @Secured 注解和支持表达式的注解,这三种注解默认都是没有启用的,需要单独通过global-method-security 元素的对应属性进行启用
6.3.1. 开启注解使用
配置文件
<security:global-method-security jsr250-annotations= "enabled" />
<security:global-method-security secured-annotations= "enabled" />
<security:global-method-security pre-post-annotations= "disabled" />
注解开启
@EnableGlobalMethodSecurity : Spring Security 默认是禁用注解的,要想开启注解,需要在继承
WebSecurityConfifigurerAdapter 的类上加 @EnableGlobalMethodSecurity 注解,并在该类中将
AuthenticationManager 定义为 Bean 。
6.3.2.JSR-250 注解
@RolesAllowed 表示访问对应方法时所应该具有的角色
示例:
@RolesAllowed({"USER", "ADMIN"}) 该方法只要具有 "USER", "ADMIN" 任意一种权限就可以访问。这里可以省略前缀ROLE_ ,实际的权限可能是 ROLE_ADMIN
@PermitAll 表示允许所有的角色进行访问,也就是说不进行权限控制
@DenyAll 是和 PermitAll 相反的,表示无论什么角色都不能访问
6.3.3. 支持表达式的注解
@PreAuthorize 在方法调用之前 , 基于表达式的计算结果来限制对方法的访问
示例:
@PreAuthorize("#userId == authentication.principal.userId or hasAuthority(‘ADMIN’)")
void changePassword(@P("userId") long userId ){ }
这里表示在 changePassword 方法执行之前,判断方法参数 userId 的值是否等于 principal 中保存的当前用户的
userId ,或者当前用户是否具有 ROLE_ADMIN 权限,两种符合其一,就可以访问该方法。
@PostAuthorize 允许方法调用,但是如果表达式计算结果为false,将抛出一个安全性异常
示例:
@PostAuthorize
User getUser("returnObject.userId == authentication.principal.userId or
hasPermission(returnObject, 'ADMIN')");
@PostFilter 允许方法调用 , 但必须按照表达式来过滤方法的结果
@PreFilter 允许方法调用 , 但必须在进入方法之前过滤输入值
6.3.4.@Secured 注解
@Secured 注解标注的方法进行权限控制的支持,其值默认为 disabled
示例:
@Secured("IS_AUTHENTICATED_ANONYMOUSLY")
public Account readAccount(Long id);
@Secured("ROLE_TELLER")
6.4 页面端标签控制权限
在 jsp 页面中我们可以使用 spring security 提供的权限标签来进行权限控制
6.4.1. 导入
maven 导入
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>version</version>
</dependency>
页面导入
<%@taglib uri="http://www.springframework.org/security/tags" prefix="security"%>
6.4.2. 常用标签
在 jsp 中我们可以使用以下三种标签,其中 authentication 代表的是当前认证对象,可以获取当前认证对象信息,例如用户名。其它两个标签我们可以用于权限控制
6.4.2.1 authentication
<security:authentication property="" htmlEscape="" scope="" var=""/>
hasPermission : hasPermission 属性用于指定以逗号分隔的权限列表
domainObject : domainObject 用于指定对应的域对象
var : var 则是用以将鉴定的结果以指定的属性名存入 pageContext 中,以供同一页面的其它地方使用
相关文章:

SSM——用户、角色、权限操作
1. 数据库与表结构 1.1 用户表 1.1.1 用户表信息描述 users 1.1.2 sql语句 CREATE TABLE users( id varchar2(32) default SYS_GUID() PRIMARY KEY, email VARCHAR2(50) UNIQUE NOT NULL, username VARCHAR2(50), PASSWORD VARCHAR2(50), phoneNum VARCHAR2(20), STATUS INT…...

UI界面设置
文章目录 1. 修改 share.html 内容如下:2. 修改 html 文件格式为 utf-83.保存,运行程序4. 访问页面 1. 修改 share.html 内容如下: <!DOCTYPE html><html> <head><meta charset"utf-8"><title>1v1屏…...

论文学习——PixelSNAIL:An Improved Autoregressive Geenrative Model
文章目录 引言论文翻译Abstract问题 Introduction第一部分问题 第二部分问题 Model Architecture网络结构第一部分问题第二部分问题 Experiments实验问题 Conclusion结论问题 总结参考 引言 这篇文章,是《PixelSNAIL:An Improved Autoregressive Geenrative Model》…...

mySQL 视图 VIEW
简化版的创建视图 create view 视图名 as select col ...coln from 表create view 视图名(依次别名) as select col ...coln from 表create view 视图名 as select col “别名1”,。。。col "别名n" from 表show tab…...

「UG/NX」Block UI 曲线收集器CurveCollector
✨博客主页何曾参静谧的博客📌文章专栏「UG/NX」BlockUI集合📚全部专栏「UG/NX」NX二次开发「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序设计「C/C+&#...

微信小程序:函数节流与函数防抖
目录 问题引入: 定义 解决方案:函数节流 一、案例举例 1.页面展示 2.search.wxml标签展示 3.search.js展示 4.结果展示 二、函数节流解决问题 1.函数 2.实例应用 三、函数防抖解决问题 1.函数 2.原理 3.应用场景 4.应用实例 总结 问题引入…...

Mathematica(42)-计算N个数值的和
比如,我们要用Mathematica求得到下面的式子: 这就需要用到一个函数:Sum 具体地,Sum函数的使用形式如下: 因此,按照公式就可以得到下面的结果: 如果,我们想要将求和号也加进去&#…...

安装和配置 Ansible
安装和配置 Ansible 按照下方所述,在控制节点 control.area12.example.com 上安装和配置 Ansible: 安装所需的软件包 创建名为 /home/curtis/ansible/inventory 的静态清单文件,以满足以下要求: node1 是 dev 主机组的成员 node2 …...

电脑系统重装日记
重装原因 电脑C盘几乎爆炸故重装系统一清二白 此片原因 记录重装过程,强调一些要注意的点,以防日后重装。 重装过程 1.清空电脑文件后重启,电脑冒蓝光,一直蓝屏反复重启,故只能重装系统以解难题。 2.准备一个U盘&…...

通讯协议044——全网独有的OPC HDA知识一之聚合(十二)持续坏值时间
本文简单介绍OPC HDA规范的基本概念,更多通信资源请登录网信智汇(wangxinzhihui.com)。 本节旨在详细说明HDA聚合的要求和性能。其目的是使HDA聚合标准化,以便HDA客户端能够可靠地预测聚合计算的结果并理解其含义。如果用户需要聚合中的自定义功能&…...

Docker:Windows container和Linux container
点击"Switch to Windows containers"菜单时: 提示 然后 实际上是运行:com.docker.admin.exe start-service...

excel提示更新外部引用文件 这个提示能手动禁用
是的,你可以手动禁用 Excel 中的更新外部引用文件的提示。这些步骤可能因 Excel 版本而有所不同,以下是一般的步骤: 1. **打开 Excel**: 2. **进入“选项”**: - 在 Excel 中,点击顶部菜单中的“文件”…...

2023 最新 小丫软件库app开源源码 PHP后端
上传了源码解压之后,在admin/public/config.php修改后台登录账号和密码 后台地址:域名或者ip/admin 然后自己修改配置即可 后端搭建完成,现在导入iapp源码 导入iapp源码之后,修改mian.iyu载入事件的对接api和url就可以打包了 sss …...

Selenium 测试用例编写
编写Selenium测试用例就是模拟用户在浏览器上的一系列操作,通过脚本来完成自动化测试。 编写测试用例的优势: 开源,免费。 支持多种浏览器 IE,Firefox,Chrome,Safari。 支持多平台 Windows,Li…...

es自定义分词器支持数字字母分词,中文分词器jieba支持添加禁用词和扩展词典
自定义分析器,分词器 PUT http://xxx.xxx.xxx.xxx:9200/test_index/ {"settings": {"analysis": {"analyzer": {"char_test_analyzer": {"tokenizer": "char_test_tokenizer","filter": [&…...

基于libevent的tcp服务器
libevent使用教程_evutil_make_socket_nonblocking_易方达蓝筹的博客-CSDN博客 一、准备 centos7下安装libevent库 yum install libevent yum install -y libevent-devel 二、代码 server.cpp /** You need libevent2 to compile this piece of code Please see: http://li…...

【TypeScript】tsc -v 报错 —— 在此系统上禁止运行脚本
在 VS Code 终端中执行 tsc -v ,报错 —— 在此系统上禁止运行脚本 然后 windows x ,打开终端管理员,出现同样的问题 解决方法: 终端(管理员)执行以下命令: 出现 RemoteSigned 则代表更改成功…...

【C++】STL---list
STL---list 一、list 的介绍二、list 的模拟实现1. list 节点类2. list 迭代器类(1)前置(2)后置(3)前置- -、后置- -(4)! 和 运算符重载(5)* 解引用重载 和 …...

六、分组背包
六、分组背包 题记算法题目代码 题记 一个旅行者有一个最多能装V公斤的背包和有N件物品,它们的重量分别是W[1],W[2],…,W[n],它们的价值分别为C[1],C[2],…,C[n]。这些物品被划分为若干组,每组中的物品互相冲突&#…...

LangChain入门:构建LLM驱动的应用程序的初学者指南
LangChain & DemoGPT 一、介绍 你有没有想过如何使用大型语言模型(LLM)构建强大的应用程序?或者,也许您正在寻找一种简化的方式来开发这些应用程序?那么你来对地方了!本指南将向您介绍LangChain&#x…...

gitlab修改远程仓库地址
目录 背景: 解决: 1.删除本地仓库关联的远程地址,添加新的远程仓库地址 2.直接修改本地仓库关联的远程仓库地址 3.打开.git隐藏文件修改远程仓库地址 4.拉取代码报错(git host key verification failed) 背景: 公司搬家&#…...

VB+SQL自动点歌系统设计与实现
摘 要 随着社会的发展,人类的进步,21世纪人们的生活的水平有所提高,为了满足人们对生活的需要,丰富业余生活,就需要有一些娱乐的设施来弥补这些空缺,所以开发了自动点歌系统。 论文详细论述了系统总体设计思想、数据库设计以及功能模块设计等,给出了自动点歌系统一般流程…...

设计模式之适配器模式(Adapter)的C++实现
1、适配器模式的提出 在软件功能开发中,由于使用环境的改变,之前一些类的旧接口放在新环境的功能模块中不再适用。如何使旧接口能适用于新的环境?适配器可以解决此类问题。适配器模式:通过增加一个适配器类,在适配器接…...

C#系统锁屏事件例子 - 开源研究系列文章
今天有个网友问了个关于操作系统锁屏的问题。 我们知道,操作系统是基于消息和事件处理的,所以我们只要找到该操作系统锁屏和解屏的那个事件,然后在事件里进行处理即可。下面是例子介绍。 1、 项目目录; 下面是项目目录:…...

R语言实现免疫浸润分析(2)
原始数据承接免疫浸润分析(1),下面展示免疫浸润结果: #直接使用IOBR包内的cell_bar_plot pic<-cell_bar_plot(input quantiseq_immo_de[1:20,], title "quanTiseq Cell Fraction") #使用ggplot2 library(ggplot2)…...

系统架构设计师-信息安全技术(2)
目录 一、安全架构概述 1、信息安全所面临的威胁 二、安全模型 1、安全模型的分类 2、BLP模型 3、Biba 模型 4、Chinese Wall模型 三、信息安全整体架构设计 1、WPDRRC模型 2、各模型的安全防范功能 四、网络安全体系架构设计 1、开放系统互联安全体系结构 2、安全服务与安…...

STM32F4X-GPIO输入功能使用
STM32F4 GPIO输入模式配置 上一节讲GPIO的时候说到了将GPIO设置成输出模式,并通过将GPIO的电平拉高拉低控制LED灯的例程。GPIO除了用作输出功能之外,还可以用作输入功能。最常用的就是检测按键的输入电平。 硬件设计 本章的硬件是基于正点原子的探索者…...

Jenkins-CICD-python/Java包升级与回退
Jenkins- CICD流水线 python/Java代码升级与回退 1、执行思路 1.1、代码升级 jenkins上点击 upgrade和 代码版本号 --${tag} jenkins 推送 代码 和 执行脚本 到目标服务器/opt目录下 执行命令 sh run.sh 代码名称 版本号 upgrade 版本号 来自jenkins的 构建参数中的 标签…...

模糊测试面面观 | 模糊测试工具知多少
自1988年威斯康星大学的Barton Miller首次提出模糊测试这一概念以来,模糊测试领域经历了持续长久发展。模糊测试作为一种软件测试方法,旨在通过向程序输入模糊、随机、异常的数据,探测和发现潜在的漏洞和错误。这种方法备受安全研究人员的青睐…...

esp8266+电压检测模块检测电池电压
该模块5v时输出1v,因esp8266 ADC引脚(A0)支持电压范围是0v-1v,所以该方案仅支持0-5v电压检测 接线: - 接 esp8266GND 可不接 S 接 ADC esp8266 为 A0 VCC 被检测直流电 GND 被检测直流电- #include <Wire.h>const int adcPin A0; // …...