【SpringSecurity】一、SpringSecurity入门

文章目录

  • 1、背景
  • 2、相关概念
  • 3、Java安全框架的实现
  • 4、入门案例
  • 4、使用配置文件配置用户名和密码
  • 5、基于内存的多用户管理

1、背景

新建个SpringBoot工程,写三个controller,里面有三个接口:

//学生
@RestController
@RequestMapping("/student")
public class StudentController {
    @GetMapping("/query")
    public String queryInfo(){
        return "this is a student,9527";
    }
}

//老师
@RestController
@RequestMapping("/teacher")
public class TeacherController {
    @GetMapping("/query")
    public String queryInfo(){
        return "this is a teacher,Mr.L";
    }
}

//管理员
@RestController
@RequestMapping("/admin")
public class AdminController {
    @GetMapping("/query")
    public String queryInfo(){
        return "this is a administrator, root";
    }
}

启动程序,此时不论是谁,访问这三个接口资源,都能成功返回信息。

curl -X GET localhost:9527/teacher/query

【SpringSecurity】一、SpringSecurity入门_第1张图片

即没有加入安全框架的代码程序,默认所有资源均不受保护,可被随意访问,因此,需要集成安全框架。

2、相关概念

认证:

认证是为了保护系统的隐私数据与资源,用户的身份合法方可访问该系统的资源,常见的用户身份认证的方式有:

  • 用户名密码登录
  • 二维码登录
  • 手机短信登录
  • 指纹认证
  • 人脸识别

会话:

用户认证通过后,为了避免用户的每次操作都进行认证可将用户的信息保存在会话中。会话就是系统为了保持当前用户的登录状态所提供的机制。直白讲就是别每干一件事就查身份,给你个五年有效期的身份证,你带身上或者我帮你存着,有这个证明,在这期间你就不用再反复认证

常见的实现方式有基于session方式和基于token方式等

授权:

即认证通过后,也不是所有的资源都能访问。拥有资源的访问权限则正常访问,没有权限则拒绝访问

RBAC(Role-Based Access Control) 基于角色的访问控制

有很多权限,把权限一个一个加给用户很繁琐,所以 将一组权限打包给一个角色,再让用户和角色挂钩。说白了,一个角色就是一组权限。

【SpringSecurity】一、SpringSecurity入门_第2张图片
一个用户可以拥有多个角色,一个角色可以被多个用户拥有。一个权限可以对应多个角色,一个角色可以对应多个权限。均为多对多,即RBAC底层最少需要5张表。

【SpringSecurity】一、SpringSecurity入门_第3张图片

  • xc_user:用户表,存储所有用户的基本信息,姓名、邮箱…
  • xc_role:角色表,根据业务需求。角色的创建是为了方便给用户分配权限。(一个用户有多个角色,一个角色下也可以有多个用户,多对多,需要中间表,中间表存两个表的主键即可)
  • xc_user_role:用户角色表(中间表,用户和角色的关系表)
  • xc_menu:权限表,记录了菜单及菜单下的权限。权限,是对资源的访问控制。一个角色可拥有多个权限,一个权限可被多个角色所拥有。(角色与权限多对多,需要中间表)
  • xc_permission:角色权限表(中间表,角色和权限的关系表)

3、Java安全框架的实现

  • Shiro:轻量级的安全框架,提供认证、授权、会话管理、密码管理、缓存管理等功能
  • Spring Security:功能比Shiro强大,更复杂,权限控制细粒度更高,对OAuth2 支持更好,与Spring 框架无缝集合,使Spring Boot 集成很快捷。
  • 自己写:基于过滤器(filter)和AOP来实现,难度大,没必要

Spring Security是一个能够为基于Spring的企业应用系统提供声明式(注解)的安全访问控制解决方案的安全框架。

https://spring.io/projects/spring-security

4、入门案例

给需要保护的微服务添加spring-boot-starter-security依赖即可。

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-securityartifactId>
dependency>


此时再访问上面controller中的接口,就会被Spring Security拦截,且Spring Security还提供了一个登录界面。

【SpringSecurity】一、SpringSecurity入门_第4张图片

使用默认用户user登录,密码在控制台可找到,是一个随机生成的UUID字符串:

【SpringSecurity】一、SpringSecurity入门_第5张图片

使用curl访问:

curl -v -X GET -u"user:550e8400-e29b-41d4-a716-446655440000" http://localhost:9527/admin/query

【SpringSecurity】一、SpringSecurity入门_第6张图片
退出登录则访问:

loclhost:port/logout

【SpringSecurity】一、SpringSecurity入门_第7张图片

以上只是个入门案例,当然密码和用户肯定不是这么存的。

4、使用配置文件配置用户名和密码

添加配置:

spring:
  security:
    user:
      name: admin
      password: admin123

重启服务,此时控制台上不再为我们生成密码,用上面自己配置的密码登录即可:

【SpringSecurity】一、SpringSecurity入门_第8张图片

当然这个还是临时给自己调试用的,生产环境不这么搞。接下来 看下源码实现,在application.yml 中 将鼠标指定到name那,按住ctrl键,单击鼠标左键

【SpringSecurity】一、SpringSecurity入门_第9张图片

5、基于内存的多用户管理

【SpringSecurity】一、SpringSecurity入门_第10张图片

在config目录下创建配置类:

@Configuration
public class MySecurityUserConfig {
    @Bean
    public UserDetailsService userDetailService() {
		//使用org.springframework.security.core.userdetails.User类来定义用户
        //定义两个用户
        UserDetails user1 = User.builder().username("liu").password("123456").roles("student").build();
        UserDetails user2 = User.builder().username("Mr.liu").password("123456").roles("teacher").build();
        //创建两个用户,信息存内存中
        InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();
        userDetailsManager.createUser(user1);
        userDetailsManager.createUser(user2);
        return userDetailsManager;
    }

}

重启服务,访问接口,跳登录页面后,输入上面定义的用户名和密码,控制台报错:

【SpringSecurity】一、SpringSecurity入门_第11张图片

这个是因为spring Sercurity强制要使用密码加密,当然我们也可以不加密,但是官方要求是不管你是否加密,都必须配置一个密码编码(加密)器

继续在MySecurityUserConfig类中定义bean:

/*
 * 从 Spring5 开始,强制要求密码要加密
 * 如果非不想加密,可以使用一个过期的 PasswordEncoder 的实例 NoOpPasswordEncoder,
 * 但是不建议这么做,毕竟不安全。
 *
 * @return
 */
@Bean
public PasswordEncoder passwordEncoder(){
    //不对密码进行加密,使用明文
    return NoOpPasswordEncoder.getInstance();
}

重启后再登录上面定义的用户,则可以登录成功。且此时,yaml配置文件中的用户名和密码就失效了。此时,有以下几个问题:

【SpringSecurity】一、SpringSecurity入门_第12张图片

你可能感兴趣的:(SpringSecurity,java,数据库,网络)