1、SpringSecurity框架简介
1.1 摘要
Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案。
 主要包括2部分:认证(Authentication)和授权(Authorization)
 认证:系统认为用户能否登录
 授权:系统判断用户能否有权限去做什么事情
1.2 历史
1.3 同款产品对比
1.3.1 SpringSecurity
- 和Spring无缝整合
 - 全面的权限控制
 - 专门为web开发而设计
 - 重量级
 
1.3.2 Shiro
- 轻量级
 - 通用性(好处:不局限于web环境,缺陷:在web环境中需要自己编写代码定制)
 
2、Hello Spring Security
创建一个maven项目
 pom.xml文件如下
<?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>com.ycm</groupId>
    <artifactId>spring-security-test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--父依赖-->
    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.2.1.RELEASE</version>
    </parent>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
 
创建Springboot启动方法
 创建一个测试用的controller
 
 点击运行
 在浏览器地址栏输入localhost:8080/hello
 
 此时就进入SpringSecurity的拦截页面,需要认证通过以后才可以进行访问
 默认的用户名:user,密码是控制台打印出来的一个随机字符串
 
 输入账号和密码就可以成功访问了
 
3、修改SpringBoot默认的用户名和密码
(1)通过配置文件修改

(2)通过配置类
@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); //密码解析器
        String encodePwd = passwordEncoder.encode("123456"); //必须转成对应的密码格式才可以
        auth.inMemoryAuthentication().withUser("root").password(encodePwd).roles("admin");
    }
    @Bean
    public PasswordEncoder passwordEncoder(){
        //注入密码解析器
        return new BCryptPasswordEncoder();
    }
}
 
4、通过查询数据库完成用户认证
数据库表创建,创建一个users表,其中的表结构如下
 
新加入pom文件依赖:
 		<!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.0.5</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
 
配置文件添加配置
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/security?serverTimezone=GMT%2B8
    username: root
    password: root
 
创建Users对应实体类
@Data
public class Users {
    @TableId(type = IdType.AUTO)
    private Integer id;
    private String username;
    private String password;
}
 
整合MBatisPlus
@Mapper
@Repository
public interface UsersMapper extends BaseMapper<Users> {
}
 
编写配置类
@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService; //用于实现用户登录功能的接口,先注入容器,然后新建一个类实现它
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }
    @Bean
    public PasswordEncoder passwordEncoder(){
        //注入密码解析器
        return new BCryptPasswordEncoder();
    }
}
 
登录逻辑接口
@Service("userDetailsService")
public class LoginService implements UserDetailsService {
    @Autowired
    private UsersMapper usersMapper;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //通过username从数据库查询
        QueryWrapper<Users> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        Users users = usersMapper.selectOne(wrapper);
        if (users == null) {
            throw new UsernameNotFoundException("用户名不存在");
        }
        //密码加密
        String pwd = new BCryptPasswordEncoder().encode(users.getPassword());
        List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("admin");
        return new User(users.getUsername(),pwd, auths);
    }
}










