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 &copy; 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 &copy; 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 &copy; 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 &copy; 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 &copy; 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 中,以供同一页面的其它地方使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/68907.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux系列讲解 —— FTP协议的应用

简单介绍一下FTP文件传输协议在linux系统中的应用。 目录 0. 基本概念1. FTP Server1.1 安装FTP Server1.2 FTP Server开启和关闭1.3 查看FTP Server是否开启1.4 FTP服务器配置 2. FTP Client2.1 lftp2.2 ftp2.3 sftp2.4 文件资源管理器集成的ftp和sftp 3. ftp常用命令 0. 基本…

麦肯锡发布《2023年度科技报告》!

在经历了 2022 年技术投资和人才的动荡之后&#xff0c;2023 年上半年&#xff0c;人们对技术促进商业和社会进步的潜力重新燃起了热情。生成式人工智能&#xff08;Generative AI&#xff09;在这一复兴过程中功不可没&#xff0c;但它只是众多进步中的一个&#xff0c;可以推…

【前端】CSS水平居中的6种方法

文章目录 flex绝对定位margin:auto绝对定位margin:负值定位transformtext-align: center;margin: 0 auto;思维导图 后文&#xff1a;【前端】CSS垂直居中的7种方法_karshey的博客-CSDN博客 左右两边间隔相等的居中 flex display: flex;justify-content: center; <div clas…

react-vite-antd环境下新建项目

vite 创建一个react项目 1. 安装vite并创建一个react项目1. 我使用的 yarn安装&#xff0c;基本配置项目名字, 框架react &#xff0c;js2. cd vite-react进入项目目录安装node包并启动项目 2. 安装引入Ant Design引入依赖&#xff08;我用的yarn&#xff0c;没有安装的也可以使…

观察者模式 Observer Pattern 《游戏编程模式》学习笔记

定义 观察者模式定义了对象间的一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都得到通知并被自动更新。 这是定义&#xff0c;看不懂就看不懂吧&#xff0c;我接下来举个例子慢慢说 为什么我们需要观察者模式 我们看一个很简…

Hands on RL 之 Deep Deterministic Policy Gradient(DDPG)

Hands on RL 之 Deep Deterministic Policy Gradient&#xff08;DDPG&#xff09; 文章目录 Hands on RL 之 Deep Deterministic Policy Gradient&#xff08;DDPG&#xff09;1. 理论部分1.1 回顾 Deterministic Policy Gradient(DPG)1.2 Neural Network Difference1.3 Why i…

Elisp之获取PC电池状态(二十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

SAP Fiori 问题收集

事务代码篇 启动工作台&#xff1a;/N/UI2/FLP 错误日志&#xff1a; /n/IWFND/ERROR_LOG 服务清单&#xff1a; /n/IWFND/MAINT_SERVICE 创建语义对象&#xff1a;/N/UI2/SEMOBJ 创建目录&#xff1a;/N/UI2/FLPD_CONF&#xff08;cross-client&#xff09;或 /N/UI2…

OpenCV-Python中的图像处理-视频分析

OpenCV-Python中的图像处理-视频分析 视频分析Meanshift算法Camshift算法光流Lucas-Kanade Optical FlowDense Optical Flow 视频分析 学习使用 Meanshift 和 Camshift 算法在视频中找到并跟踪目标对象: Meanshift算法 Meanshift 算法的基本原理是和很简单的。假设我们有一堆…

Spring Security用户授权

用户认证在上一篇用户认证 用户授权 总体流程&#xff1a; 在SpringSecurity中&#xff0c;会使用默认的FilterSecurityInterceptor来进行权限校验。在FilterSecurityInterceptor中会从SecurityContextHolder获取其中的Authentication&#xff0c;然后获取其中的权限信息。…

idea中Maven报错Unable to import maven project: See logs for details问题的解决方法

idea中Maven报错Unable to import maven project: See logs for details问题的解决方法。 在查看maven的环境配置和idea的maven配置后&#xff0c;发现是idea 2020版本和maven 3.9.3版本的兼容性问题。在更改为Idea自带的maven 3.6.1版本后问题解决&#xff0c;能成功下载jar包…

word 应用 打不开 显示一直是正在启动中

word打开来显示一直正在启动中&#xff0c;其他调用word的应用也打不开&#xff0c;网上查了下以后进程关闭spoolsv.exe,就可以正常打开word了