1. 准备数据库环境
# 新建用户表
CREATE TABLE `user` (
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '编号',
`username` VARCHAR(32) NOT NULL COMMENT '账号',
`birthday` DATETIME DEFAULT NULL COMMENT '生日',
`sex` CHAR(1) DEFAULT NULL COMMENT '性别',
`address` VARCHAR(256) DEFAULT NULL COMMENT '地址',
`password` VARCHAR(100) DEFAULT NULL COMMENT '密码',
CONSTRAINT pk_user PRIMARY KEY (`id`)
);
# 添加用户数据
INSERT INTO
`user`(`id`,`username`,`birthday`,`sex`,`address`,`password`)
VALUES
(1,'周瑜','2020-02-27 17:47:08','男','吴国','$2a$10$gw70IRq6RuHMgZyO3w84Sepu2zPGyXniOENu7xeTK0lZArSU/fyO6');
2. 新建SpringBoot项目
3. 项目依赖
<dependencies>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<!-- jdbc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<!-- configuration -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
4. 用户实体类
package zw.springboot.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* @className UserDO
* @description 用户实体类
* @author 周威
* @date 2020-09-02 8:59
**/
@Data
public class UserDO implements Serializable
{
/* 用户编号 */
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/* 用户姓名 */
@TableField("username")
private String userName;
/* 用户密码 */
@TableField("password")
private String passWord;
/* 用户生日 */
@TableField("birthday")
private Date birthday;
/* 用户性别 */
@TableField("sex")
private String sex;
/* 用户地址 */
@TableField("address")
private String address;
}
5. 用户展示实体类
package zw.springboot.vo;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import zw.springboot.domain.UserDO;
import java.io.Serializable;
/**
* @className UserVO
* @description 用户展示实体类
* @author 周威
* @date 2020-09-02 9:04
**/
@Data
@TableName("user")
public class UserVO extends UserDO implements Serializable
{
}
6. 用户持久层接口
package zw.springboot.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import zw.springboot.vo.UserVO;
/**
* @className UserMapper
* @description 用户持久层接口
* @author 周威
* @date 2020-09-02 9:06
**/
@Mapper
public interface UserMapper extends BaseMapper<UserVO>
{
}
7. 定义用户信息服务
- 定义一个类实现UserDetailsService接口
- 重写public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException方法
package zw.springboot.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import zw.springboot.mapper.UserMapper;
import zw.springboot.vo.UserVO;
import java.util.ArrayList;
import java.util.List;
/**
* @className SecurityServiceImpl
* @description 安全认证业务层实现类
* @author 周威
* @date 2020-09-02 9:08
**/
@Service
public class SecurityServiceImpl implements UserDetailsService
{
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException
{
// 查询数据库
QueryWrapper<UserVO> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username", userName);
UserVO userVO = userMapper.selectOne(queryWrapper);
if (userVO == null)
{
// 用户不存在
return null;
}
else
{
// 用户存在
// 角色集合
List<GrantedAuthority> authorities = new ArrayList<>();
// 角色必须以`ROLE_`开头,数据库中没有,则在这里加
authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
User user = new User(userVO.getUserName(), userVO.getPassWord(), authorities);
return user;
}
}
}
8. 安全认证表现层控制器
package zw.springboot.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @className LoginController
* @description 安全认证表现层控制器
* @author 周威
* @date 2020-09-02 10:31
**/
@Controller
@RequestMapping("security")
public class LoginController
{
@Autowired
private UserDetailsService securityService;
/**
* 跳转登录页面
* @return 逻辑视图名
*/
@GetMapping("page")
public String requsetLoginPage()
{
return "login";
}
/**
* 跳转后台首页
* @return 逻辑视图名
*/
@PostMapping("success")
public String requestLoginSuccess()
{
return "main";
}
}
9. 安全认证配置类
package zw.springboot.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
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.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* @className SpringSecurityConfig
* @description 安全认证配置类
* @author 周威
* @date 2020-09-02 9:11
**/
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter
{
@Autowired
private UserDetailsService securityService;
/**
* 创建密码加密器
* @return 密码加密器
*/
@Bean
public PasswordEncoder createPassWordEncoder()
{
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception
{
http.authorizeRequests()
// 指定哪些资源需要认证
.antMatchers("/user/**").authenticated()
// 其他资源不需要认证
.anyRequest().permitAll()
.and()
// 启用表单用户登录认证
.formLogin()
// 指定登录页面请求地址
.loginPage("/security/page")
// 指定登录认证请求地址
.loginProcessingUrl("/security/login")
// 指定登录成功跳转请求
.successForwardUrl("/security/success");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth
// 指定安全认证服务
.userDetailsService(securityService)
// 指定密码加密器
.passwordEncoder(createPassWordEncoder());
}
}
10. 定义登录界面
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<title>登录</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<meta name="author" content="周威"/>
</head>
<body>
<form th:action="@{/security/login}" method="post">
<p>
<label>账号:</label>
<input name="username" type="text">
</p>
<p>
<label>密码:</label>
<input name="password" type="password">
</p>
<p>
<input type="submit" value="登录">
</p>
</form>
</body>
</html>
11. 定义登录成功界面
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<title>后台主页</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<meta name="author" content="周威"/>
</head>
<body>
<p th:text="'Welcome To Admin Page'"></p>
</body>
</html>
12. 项目启动访问