1、集成一个mybatis项目
1.1 在pom.xml中导入
<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.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
1.2 application.yaml
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
#整合mybatis
mybatis:
type-aliases-package: com.paul.pojo
mapper-locations: classpath:mapper/*.xml
#解决首次重定向报400的错误(url携带jsessionid问题)
server:
servlet:
session:
tracking-modes: cookie
cookie:
http-only: true
1.3 创建数据库,新建实体类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String pwd;
private String perms;
}
1.4 在resource下新建mapper/UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.paul.mapper.UserMapper">
<select id="queryUserByName" parameterType="String" resultType="User">
select * from mybatis.user where name = #{name}
</select>
</mapper>
1.5 新建mapper对应的java
import com.paul.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface UserMapper {
public User queryUserByName(String name);
}
1.6 新建service
import com.paul.mapper.UserMapper;
import com.paul.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl {
@Autowired
UserMapper userMapper;
public User queryUserByName(String name) {
return userMapper.queryUserByName(name);
}
}
1.7 写一个测试用的控制器
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class RouterController {
@RequestMapping({"/","/index"})
public String toIndex(){
return "index";
}
@RequestMapping("/user/add")
@ResponseBody
public String add(){
return "add";
}
@RequestMapping("/user/update")
@ResponseBody
public String update(){
return "update";
}
@RequestMapping("/toLogin")
public String toLogin(){
return "logpage";
}
}
1.8 写首页和登录页
index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>首页</h1>
<a th:href="@{/toLogin}">去登录</a>
<br/>
<a th:href="@{/logout}">退出</a>
<hr>
<a th:href="@{/user/add}">add</a>
<a th:href="@{/user/update}">update</a>
</body>
</html>
logpage.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>登录</h1>
<form th:action="@{/login}" method="post">
用户名:<input name="username" type="text"><br/>
密码:<input name="password" type="password">
<input type="submit">
</form>
</body>
</html>
启动项目验证,此时项目可以正常访问。
2、导入SpringSecurity 的启动器jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
此时再启动项目,发现控制台有如下信息打印出
去访问首页,发现已被拦截
原因是导入SpringSecurity的启动器以后,不需任何配置,SpringSecurity已自带了默认的登录拦截,登录页面(/login)和注销页面(/logout)。此时登录的username为"user",password为启动时控制台打印出的内容,登录后即为正常访问。
3、自定义SpringSecurity配置,创建MySecurity类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class MySecurity extends WebSecurityConfigurerAdapter {
//授权
@Override
protected void configure(HttpSecurity http) throws Exception {
//super.configure(http);
http.authorizeRequests()
//设置权限
.antMatchers("/","/toLogin").permitAll() //首页和登录页允许全部
.antMatchers("/user/add").hasAnyAuthority("user:add") //有权限才可以访问
.antMatchers("/user/update").hasAnyAuthority("user:update")
.anyRequest().authenticated() //表示剩余的其他接口,登录之后就能访问
.and()
.formLogin()
.loginPage("/toLogin") //设置登录页(注意自定义的登录页需要放开全部访问的权限)
.usernameParameter("username") //设置登录的参数
.passwordParameter("password")
.loginProcessingUrl("/login") //设置登录成功跳转页
.and()
.logout().deleteCookies("remove").invalidateHttpSession(true) //设置退出
.logoutSuccessUrl("/") //设置退出成功跳转页
.and()
.csrf().disable() //禁用 csrf,防止跨站攻击
;
}
}
4、用数据库信息接管登录
在MySecurity中添加密码加密的bean
@Bean
public PasswordEncoder createPasswordEncoder(){
return new BCryptPasswordEncoder();
}
创建MyUserDetailService 实现SpringSecurity 的 UserDetailsService 类,注入PasswordEncoder 和自己的Service
import com.paul.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@Service
public class MyUserDetailService implements UserDetailsService {
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private UserServiceImpl userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println("用户名:"+ username);
User user = userService.queryUserByName(username);
if(user == null){
return null;
}else {
String encodePwd = passwordEncoder.encode(user.getPwd());
System.out.println("加密后密码:"+ encodePwd);
String perms = user.getPerms();
return new org.springframework.security.core.userdetails.User(username,encodePwd, getauthorities(perms));
}
}
private Collection<GrantedAuthority> getauthorities(String perms){
List<String> permsLists = Arrays.asList(perms.split(","));
List<GrantedAuthority> arrayList = new ArrayList<>();
for (String perm : permsLists) {
arrayList.add(new SimpleGrantedAuthority(perm));
}
return arrayList;
}
}
5、添加SpringSecurity 与Thymealf的整合包,给前台页面加标签
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>首页</h1>
<div sec:authorize="!isAuthenticated()">
<a th:href="@{/toLogin}">去登录</a>
</div>
<div sec:authorize="isAuthenticated()">
用户名:<span sec:authentication="name"></span>
权限:<span sec:authentication="principal.authorities"></span>
<br/>
<a th:href="@{/logout}">退出</a>
</div>
<hr>
<div sec:authorize="hasAnyAuthority('user:add')">
<a th:href="@{/user/add}">add</a>
</div>
<div sec:authorize="hasAnyAuthority('user:update')">
<a th:href="@{/user/update}">update</a>
</div>
</body>
</html>
6、启动测试