1.引入依赖:
<?xml version="1.0" encoding="UTF-8"?>
<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>cn.ld</groupId>
<artifactId>TourManage</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<spring.version>5.0.2.RELEASE</spring.version>
<spring.security.version>5.0.2.RELEASE</spring.security.version>
</properties>
<dependencies>
<!-- spring相关的jar包 -->
<!-- 容器 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 事务 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- JDBC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- springMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- mybatis与Spring整合 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!-- AOP切面 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
<!-- 数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.9</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- servletAPI -->
<!-- JSP应用 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<!-- servlet应用 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<!--日志开始-->
<!-- 日志工具包 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.7</version>
</dependency>
<!--日志核心包-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
</dependency>
<!--web相关的功能包-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.7</version>
</dependency>
<!--为java做简单的日志记录-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<!--slf4j的log4j实现类-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.9.1</version>
</dependency>
<!--程序运行的时候检测用了哪种日志实现类-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-jcl</artifactId>
<version>2.9.1</version>
</dependency>
<!--日志结束-->
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!--oracle的jar包-->
<!-- JSTL -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.1</version>
</dependency>
<!-- 文件上传 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- mybatis提供的分页助手 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</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>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring.security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${spring.security.version}</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<!-- 配置插件tomcat7 -->
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>90</port>
<path>/</path>
<uriEncoding>UTF-8</uriEncoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/TourManage</path>
</configuration>
</plugin>
</plugins>
<!-- 如果不添加此节点mybatis的mapper.xml文件都会被漏掉。 -->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
2.添加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 pattern="/login.jsp" security="none"></security:http>
<security:http pattern="/css/**" security="none"></security:http>
<security:http pattern="/img/**" security="none"></security:http>
<security:http pattern="/plugins/**" security="none"></security:http>
<!-- 配置拦截的规则
auto-config="使用自带的页面"
use-expressions="是否使用spel表达式",如果使用表达式:hasRole('ROLE_USER')
-->
<security:http auto-config="true" use-expressions="false">
<!-- 配置拦截的请求地址,任何请求地址都必须有ROLE_USER的权限-->
<security:intercept-url pattern="/**" access="ROLE_USER"/>
<!--
指定安全框架使用的页面
login-page:指定登录页面
login-processing-url:登录的请求路径:登陆时必须使用的路径
default-target-url:登录成功后进入的页面
authentication-failure-url:认证失败后要进入的页面
-->
<security:form-login login-page="/login.jsp"
login-processing-url="/login"
default-target-url="/index.jsp"
authentication-failure-url="/login.jsp"
></security:form-login>
<!-- 关闭跨站请求伪造-->
<security:csrf disabled="true"/>
<!-- 退出 -->
<security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/login.jsp"/>
</security:http>
<!-- 配置认证信息:认证管理器-->
<security:authentication-manager>
<!-- 认证信息的提供者:关联用户服务对象,提供账号和密码-->
<security:authentication-provider user-service-ref="userService">
<!-- 用户的服务对象-->
<!-- <security:user-service> -->
<!--
用户信息:临时账号和密码
{noop}:不使用加密
authorities:指定用户的认证角色
-->
<!-- <security:user name="admin" password="{noop}admin" authorities="ROLE_USER"/> -->
<!-- </security:user-service> -->
</security:authentication-provider>
</security:authentication-manager>
</beans>
3.修改web.xml文件:
<!-- 配置全局参数 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml,classpath:spring-security.xml</param-value>
</context-param>
<!-- 监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置编码过滤器 -->
<filter>
<filter-name>CharacterEncoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置委派代理过滤器链 -->
<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>
<!-- 配置前端控制器 -->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
4.创建sys_user表和SysUser实体类:
表:
create table sys_user(
id int primary key auto_increment,
username varchar(30) unique,
password varchar(100),
email varchar(20),
phoneNum varchar(20),
status int
);
实体类:
public class SysUser {
private Integer id;
private String username;
private String password;
private String email;
private String phoneNum;
private Integer status;
}
5.创建用户业务层:
//UserDetailsService:接口中提供了一个方法LoadUserByUsername
public interface UserService extends UserDetailsService{
}
/**
* @Service("userService")必须和spring-security.xml里面的
* <security:authentication-provider user-service-ref="userService">保持一致
*/
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
UserDao userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println(username);
//根据用户名获取用户(SysUser)对象
SysUser sysUser=userDao.findByUsername(username);
if (sysUser!=null){
//创建角色集合对象
Collection<GrantedAuthority> authorities=new ArrayList<>();
//创建角色对象
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_USER");
authorities.add(grantedAuthority);
/**
* 参数1:用户名;参数2:密码(二者来源于数据库)
* 参数3:角色集合对象
*/
User user = new User(sysUser.getUsername(),"{noop}"+sysUser.getPassword(),authorities);
return user;
}
return null;
}
6.创建用户DAO层:
public interface UserDao {
/**
* 根据用户名查询一个SysUser对象
* @param username
* @return
*/
SysUser findByUsername(String username);
}
<!--根据用户名查询一个SysUser对象-->
<select id="findByUsername" parameterType="String" resultType="SysUser">
select * from sys_user where username=#{username}
</select>
服务端获取用户名:
/**
* 使用安全框架登录成功后,将用户名显示到页面
*/
@Controller
public class ShowUsernameController {
/**
* 获取用户名
* 不使用安全框架:自行将用户对象存入session,并在需要的地方取出
* 使用安全框架:存入session的操作已经被spring-security完成,只需要取出就行
* @param request
*/
@RequestMapping("showUsername")
public void showUsername(HttpServletRequest request){
//获取session对象
HttpSession session = request.getSession();
//从session域中获取所有的属性名
Enumeration attributeNames = session.getAttributeNames();
//遍历枚举类型
while (attributeNames.hasMoreElements()){
Object o = attributeNames.nextElement();
System.out.println(o);
}
//SPRING_SECURITY_CONTEXT:表示存储用户登录信息的session中的名称
//安全框架的上下文对象
SecurityContext securityContext = (SecurityContext) session.getAttribute("SPRING_SECURITY_CONTEXT");
//获取认证信息
Authentication authentication = securityContext.getAuthentication();
//获取重要信息(用户信息)
User user = (User) authentication.getPrincipal();
//获取用户名
String username = user.getUsername();
System.out.println(username);
//获取上下文的对象的另一种方式:
SecurityContext context = SecurityContextHolder.getContext();
}
}
前台显示用户名:
方式一:el表达式获取用户名
${sessionScope.SPRING_SECURITY_CONTEXT.authentication.principal.username}
方式二:SpringSecurity标签获取用户名
<%@taglib prefix="security" uri="http://www.springframework.org/security/tags"%>
<security:authentication property="principal.username"/>
用户退出功能:
class="btn btn-default btn-flat">注销</a>
<a href="${pageContext.request.contextPath}/logout"
<div class="pull-right">
</div>
<!-- 退出 -->
<security:logout invalidate-session="true" logout-url="/logout" logout-success-url="/login.jsp"/>
login.jsp:
<%@ page language="java" isELIgnored="false" 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>
<meta
content="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></b>权限管理系统</a>
</div>
<!-- /.login-logo -->
<div class="login-box-body">
<p class="login-box-msg">登录系统</p>
<form action="login"
method="post">
<div class="form-group has-feedback">
<input type="text" name="username" class="form-control"
placeholder="用户名"> <span
class="glyphicon glyphicon-envelope form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input type="password" name="password" class="form-control"
placeholder="密码"> <span
class="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 -->
<script
src="${pageContext.request.contextPath}/plugins/jQuery/jquery-2.2.3.min.js"></script>
<script
src="${pageContext.request.contextPath}/plugins/bootstrap/js/bootstrap.min.js"></script>
<script
src="${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>
效果: