1. 介绍
Spring Security 是一个安全管理框架,核心功能有两个:认证、授权
- 认证:判断 访问者 是不是系统里的用户,可以简单的认为能否登陆
- 比如:手机刷脸解锁
- 授权:判断 访问者 是否有权限做某个操作
- 比如:去京东买东西,上面的价格只能看,不能改,只有商家才能改
2. 快速入门
创建一个普通的maven项目
1. pom.xml
<!-- 引用父pom -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.13</version>
</parent>
<dependencies>
<!-- spring web 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2. Application
@SpringBootApplication
public class Application {
public static void main(String[] args){
SpringApplication.run(Application.class,args);
}
}
3. Controller
@RestController
public class SecController {
@GetMapping("/sec")
public String sec(){
return "spring-secutiry";
}
}
访问结果:
4. 引入 Security
修改 pom.xml 增加 Spring Security 依赖
<!-- spring security 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
然后重启项目,再次访问:localhsot:8080/sec,就需要登录了
默认的用户名:user,
密码:
注意,每次重启,密码都变
退出登陆,访问:http://localhost:8080/logout
3. 从数据库查询用户
上面的用户名、密码是框架自带的,正常情况下,我们的用户都是存储在数据库中
下面,从数据库中获取用户,完成登陆
1. pom.xml
增加 Mybatis Plus 和 mysql 依赖
<!-- mybatis plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<!-- 连接MySQL数据库 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
2. properties
#数据库
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false
spring.datasource.username=
spring.datasource.password=
3. 数据库
CREATE TABLE `user` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`username` VARCHAR(45) NULL,
`password` VARCHAR(45) NULL,
PRIMARY KEY (`id`));
INSERT INTO `test`.`user` (`id`, `username`, `password`) VALUES ('1', 'fengxiansheng', '{noop}123456');
4.代码
User 实体类
@TableName("user")
public class User {
@TableId
private Integer id;
//用户名
private String username;
//密码
private String password;
get、set 省略
}
UserMapper 接口
public interface UserMapper extends BaseMapper<User> {
}
Application
@SpringBootApplication
@MapperScan("com.feng.security.mapper")
public class Application {
public static void main(String[] args){
SpringApplication.run(Application.class,args);
}
}
UserService
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User getByUserName(String username){
Map<String,Object> map = new HashMap<String, Object>();
map.put("username", username);
List<User> users = userMapper.selectByMap(map);
if(CollectionUtils.isEmpty(users)){
return null;
}
return users.get(0);
}
}
下面是重点
新建 LoginUserService,实现 UserDetailsService 接口,这样就可以从数据库查询用户
@Component
public class LoginUserService implements UserDetailsService {
@Autowired
private UserService userService;
/**
* 根据用户名查询用户对象
* @param username 前端传的用户名
* @return
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 从数据库查询用户
User user = userService.getByUserName(username);
if(user == null){
throw new UsernameNotFoundException("没有这个用户");
}
// 把用户信息封装到一个 UserDetails 对象中,UserDetails是一个接口,LoginUser实现了这个接口
LoginUser loginUser = new LoginUser();
loginUser.setUser(user);
return loginUser;
}
}
新建 LoginUser 类,实现 UserDetails 接口,用来封装 User 信息
public class LoginUser implements UserDetails {
private User user;
/**
* 返回用户密码
* @return
*/
@Override
public String getPassword() {
return user.getPassword();
}
/**
* 返回用户名
* @return
*/
@Override
public String getUsername() {
return user.getUsername();
}
/**
* 用户是否过期,可以根据用户的信息判断是否过期
* @return
* false 表示用户过期,不可登陆
* true 可以登陆
*/
@Override
public boolean isAccountNonExpired() {
return true;
}
/**
* 用户是否锁定,可以根据用户的信息判断是否锁定
* @return
* false 用户锁定,不可登陆
* true 没有锁定,可以登陆
*/
@Override
public boolean isAccountNonLocked() {
return true;
}
/**
* 用户密码是否过期
* @return
* false 表示过期,不可登陆
* true 没有过期,可以登陆
*/
@Override
public boolean isCredentialsNonExpired() {
return true;
}
/**
* 用户是否禁用
* @return
* false 用户禁用,不可登陆
* true 没有禁用,可以登陆
*/
@Override
public boolean isEnabled() {
return true;
}
/**
* 放回这个用户的权限列表,暂时先不管
* @return
*/
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
重启项目,然后故意输入错误的用户密码
再输入正确的,结果正常跳转