0
点赞
收藏
分享

微信扫一扫

ProjectDay02

晴儿成长记 2022-03-11 阅读 35

续 Spring 安全框架

密码加密的实现

上次课讲解了密码加密的概念

介绍了bcrypt密码加密的算法

下面我们通过一个测试,演示这个算法

// 声明密码加密操作对象
PasswordEncoder encoder=new BCryptPasswordEncoder();
// 加密测试
@Test
public void pwd(){
    String str="123456";
    // 执行加密,使用encode方法参数是要加密的字符串,返回值是加密结果
    String pwd= encoder.encode(str);
    System.out.println(pwd);
    //$2a$10$kVuKchYUN92TGcQb./H.iOHCT8LOIho12bI1OTb5xPTassynjdsES
}

运行测试方法,能够得到加密结果

我们发现每次加密结果是不同的

因为如果每次加密结果时固定的,反而容易被人破解,并不安全

bcrypt加密算法采用了"随机加盐"技术,每次加密结果不同,提高了安全等级

下面我们来测试,加密得到的字符串,能不能正确的验证成功

"验证"指判断当前加密字符串是不是指定字符串生成的

// 验证操作
@Test
public void match(){
    // 验证一个字符串是否能够加密为指定的加密结果
    // 方法matches([原字符串],[加密字符串])返回值是boolean类型
    // 返回值为真表示验证通过,返回值为假表示验证失败
    boolean b=encoder.matches("123456",
            "$2a$10$kVuKchYUN92TGcQb./H.iOHCT8LOIho12bI1OTb5xPTassynjdsE");
    System.out.println("验证结果为:"+b);

}

上面的测试如果运行输出验证通过(true),表示字符串和加密结果匹配

否则会输出false

下面将我们的application.properties配置文件中的用户密码设置为加密的

# Spring-Security自定义登录用户名和密码的配置
spring.security.user.name=admin
spring.security.user.password={bcrypt}$2a$10$kVuKchYUN92TGcQb./H.iOHCT8LOIho12bI1OTb5xPTassynjdsES

{bcrypt}是"算法id"的声明定义

表示后面的字符串是由bcrypt算法加密得来的

登录时会按照相同的算法来验证

Spring-Security配置登录与权限管理

上面章节中我们将登录用户信息保存在application配置文件中

实际登录时,一定是从数据库来获得用户信息的,所以登录一定会编写在java代码中

我们学习如何在java配置类中配置一个用户的登录,顺便演示用户的权限管理功能

portal项目中创建一个security包

这个包中创建SecurityConfig类,进行配置代码如下

// SpringBoot启动时扫描到@Configuration标记的类,会自动加载其中的配置
// 所有SpringBoot框架环境下@Configuration必须写才能配置生效
@Configuration
// 启动Spring-Security配置的注解
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    // WebSecurityConfigurerAdapter是我们需要基础的父类
    // 这个父类提供了配置Spring-Security运行的基本方法
    // 我们要想修改配置的话,重写它的方法即可
    // 下面我们就配置一个可以登录的用户
    // 一旦重写这个方法,配置文件中的admin就失效了
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 删除原有的super调用
        // 在代码中配置一个等于用户
        // inMemory表示在内存中保存一个用户
        auth.inMemoryAuthentication()
                .withUser("tom")
                .password("{bcrypt}$2a$10$ELGiEhKyLlO9r3.WVOkHDe16JTCKCErcABhElD5CF7ZwQ.Hm6sVRW")
                .authorities("answer");
        // 我们配置了一个可以登录的用户
        // 用户名tom 密码 888888
        // 在代码最后一行,我们授予了当前tom用户answer的授权\资格
        // 这个授权或资格可以访问需要对应授权的控制器方法

    }
}

重启服务

登录tom

登录成功后可以访问项目的大部分资源

但是如果有控制器方法需要特殊授权才能执行

运行前Spring-Security会验证当前用户是否具有这个资格

我们在UserController中编写两个需要不同授权才能访问的方法代码如下

@GetMapping("/answer")
// 下面的注解规定当前用户必须包含answer授权
// 才能访问下面的控制方法
@PreAuthorize("hasAuthority('answer')")
public String answer(){
    return "允许回答问题!";
}
@GetMapping("/delete")
@PreAuthorize("hasAuthority('delete')")
public String delete(){
    return "允许删除回答!";
}

重启服务

tom用户具有answer授权

所以可以访问/answer方法

但是访问/delete方法时返回403错误,表示没有权限访问

这样就能显示某些用户访问某些资源

如果想让一个用户具有多个授权,可以改写登录配置如下

String[] as={"answer","delete"};
// inMemory表示在内存中保存一个用户
auth.inMemoryAuthentication()
        .withUser("tom")
        .password("{bcrypt}$2a$10$ELGiEhKyLlO9r3.WVOkHDe16JTCKCErcABhElD5CF7ZwQ.Hm6sVRW")
        .authorities(as);

再重启服务,登录tom

就可以访问/answer和/delete两个方法了!

用户与权限

上面章节,我们学习了定义一个用户的登录,并且设置一个用户具有的授权

我们在登录当前数据库中用户时,又如何确定这个用户的授权呢?

现在登录需要的信息有

1.用户名

2.密码(加密的)

3.用户的所有权限

上面的信息都保存在数据库中,用户名和密码保存在user表里

但是用户的授权(权限)是需要相对复杂的查询才能查询出来的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J5WH6V5b-1646625752230)(image-20220307115752528.png)]

上的5张表表示的是用户\角色\权限的关系

我们需要根据用户的id查询出这个用户具有哪些角色

在根据用户的角色查询出它的所有权限

他们之前的关系表有user_role和role_permission

英文

Enable:启用\启动

Global:全局\全球

Adapter:适配器

Configurer:配置

Authentication:授权

今后几乎所有auth开头的单词都是授权的意思,只是不同的词性

Memory:记忆\计算机中就是内存

学校中的用户和权限

用户 中间表 角色 中间表 权限

杨过 学生 签到

令狐冲 任课老师 成绩管理

欧阳锋 班主任 学生管理

乔峰 年级组长 课程管理

段誉 教导主任 教职工管理

洪七公 校长 学校倒闭

表与表之间的关系

1.一对一

2.一对多(多对一):

班级和学生

部门和员工

特征:在多(学生表)的一方,保存一个一的一方(班级表)的id列

一对多是所有关系中最常见的关系

3.多对多

传统义务教育阶段的老师和班级

一个老师给多个班级讲课

一个班级被多个老师教

特征:在两张表之间,创建一个关系表

关系表中保存班级和老师的关系

举报

相关推荐

ProjectDay08

ProjectDay15

ProjectDay20

Day-02-02

To:02

day10-demo02&exer02

jQuery————02

【笔记02】

0 条评论