基于SpringBoot-Mybatis-SpringSecurity-LayUI的简单用户权限管理
项目实现效果
项目放在GitHub:
https://github.com/LinZiYU1996/Spring-Boot-Mybatis-springsecurity
Pom文件:
<?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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.20.BUILD-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>safe-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>safe-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<!--热加载工具-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.6.RELEASE</version>
</dependency>
<!--日志工具-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.8</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.22</version>
</dependency>
<!--lombok工具-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.12</version>
</dependency>
<!-- 阿里巴巴连接池druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<!-- mybatis的配置 -->
<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!-- mybatis分页功能 -->
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.6</version>
</dependency>
<!--MySql连接驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
<!--谷歌处理json的工具包-->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories>
</project>
MySql表的设计:
没有设置外键,使用user_role来保存用户对应的角色,查询用户时需要使用关联查询
<select id="getAllUsers" resultMap="userMap">
select u.*
,r.name
from user u
LEFT JOIN user_role sru on u.id= sru.userID
LEFT JOIN role r on sru.roldID=r.id
</select>
基本流程:
前端页面基本都是发送Ajax请求来获取Json数据,之后使用LayUI来进行渲染,请求页面的Url都在WebMvcConfig里面,Controller存放的都是返回Json数据格式的处理类
Spirng Security 核心配置类:
配置了访问权限,表单验证处理页面和Url以及验证成功以及失败的处理Handler,登出处理Handler,无权限访问时的处理Handler
public class BrowerSecurityConfig extends WebSecurityConfigurerAdapter {
private final static BCryptPasswordEncoder ENCODER = new BCryptPasswordEncoder();
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
public MyUserDetailService myUserDetailService(){
return new MyUserDetailService();
}
@Autowired
private UserLoginAuthenticationFailureHandler userLoginAuthenticationFailureHandler;
@Autowired
private UserLoginAuthenticationSuccessHandler userLoginAuthenticationSuccessHandler;
@Autowired
private UserLogoutSuccessHandler userLogoutSuccessHandler;
@Autowired
private UserAuthenticationAccessDeniedHandler userAuthenticationAccessDeniedHandler;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers().frameOptions().sameOrigin()//设置弹出层
.and()
.authorizeRequests()
.antMatchers("/admin/**","/setUserAdmin","/setUser","/deleteUserById")
.access("hasRole('ROLE_ADMIN')")//只有管理员才能访问
.antMatchers("/home","/static/**","/getAllUser","/register_page",
"/register","/checkNameIsExistOrNot")//静态资源等不需要验证
.permitAll()//不需要身份认证
.anyRequest().authenticated()//其他路径必须验证身份
.and()
.formLogin()
.loginPage("/login_page")//登录页面
.loginProcessingUrl("/login")
.usernameParameter("username")
.passwordParameter("password")
.failureHandler(userLoginAuthenticationFailureHandler)//验证失败处理
.successHandler(userLoginAuthenticationSuccessHandler)//验证成功处理
.permitAll()//登录页面不需要验证
.and()
.logout()
.logoutSuccessHandler(userLogoutSuccessHandler)//登出处理
.permitAll()
.and()
.csrf().disable()
.exceptionHandling().accessDeniedHandler(userAuthenticationAccessDeniedHandler);//无权限时的处理
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailService()).passwordEncoder(new PasswordEncoder() {
@Override
public String encode(CharSequence charSequence) {
return ENCODER.encode(charSequence);
}
@Override
public boolean matches(CharSequence charSequence, String s) {
if ( !ENCODER.matches(charSequence,s)){
// log.info("{}","密码对不上");
}else {
// log.info("{}","密码OK");
}
return ENCODER.matches(charSequence,s);
}
});
}
}