【动力节点】springsecurity课程笔记6-13章

这篇具有很好参考价值的文章主要介绍了【动力节点】springsecurity课程笔记6-13章。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

**

6 密码处理

6.1 为什么要加密?

csdn 密码泄露事件
泄露事件经过:https://www.williamlong.info/archives/2933.html
泄露数据分析:https://blog.csdn.net/crazyhacking/article/details/10443849

6.2加密方案

密码加密一般使用散列函数,又称散列算法,哈希函数,这些函数都是单向函数(从明文到密文,反之不行)
常用的散列算法有MD5和SHA
Spring Security提供多种密码加密方案,基本上都实现了PasswordEncoder接口,官方推荐使用BCryptPasswordEncoder

6.3 BCryptPasswordEncoder类初体验

拷贝springsecurity-04-inmemory工程,重命名为springsecurity-05-password-encode
test/java 下新建包com.powernode.password,在该包下新建测试类PasswordEncoderTest,如下

@Slf4j
  public class PasswordEncoderTest {
   
    @Test
    @DisplayName("测试加密类BCryptPasswordEncoder")
    void testPassword(){
   
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        //加密(明文到密文)
        String encode1 = bCryptPasswordEncoder.encode("123456");
        _log_.info("encode1:"+encode1);
        String encode2 = bCryptPasswordEncoder.encode("123456");
        _log_.info("encode2:"+encode2);
        String encode3 = bCryptPasswordEncoder.encode("123456");
        _log_.info("encode3:"+encode3);
        //匹配方法,判断明文经过加密后是否和密文一样
        boolean result1 = bCryptPasswordEncoder.matches("123456", encode1);
        boolean result2 = bCryptPasswordEncoder.matches("123456", encode1);
        boolean result3 = bCryptPasswordEncoder.matches("123456", encode1);
        _log_.info(result1+":"+result2+":"+result3);
        _assertTrue_(result1);
        _assertTrue_(result2);
        _assertTrue_(result3);
    }
} 

查看控制台发现特点是:**相同的字符串加密之后的结果都不一样,但是比较的时候是一样的,因为加了盐(**salt)了。
【动力节点】springsecurity课程笔记6-13章
上面简单看下即可
小提示:
Ø 开发代码时不允许使用main方法测试,而是使用单元测试来测试
Ø 代码中一般不允许使用System.out.println 直接输出,而是使用日志输出
Ø 单元测试尽量使用断言,而不是使用System.out.println输出

6.4 使用加密器并且加密

修改MySecurityUserConfig类中的加密器bean

@Bean

  public PasswordEncoder passwordEncoder(){
   
    //使用加密算法对密码进行加密
    return new BCryptPasswordEncoder();
  } 

启动程序测试,发现不能正常登录
原因是输入的密码是进行加密了,但是系统中定义的用户密码没有加密
将系统定义的用户密码修改成密文,如下

@Configuration
  public class MySecurityUserConfig {
   
    @Bean
    public UserDetailsService userDetailService() {
   
  //        使用org.springframework.security.core.userdetails.User类来定义用户
        //定义两个用户
        UserDetails user1 = User._builder_()
                .username("eric")
                .password(passwordEncoder().encode("123456"))
                .roles("student")
                .build();
        UserDetails user2 = User._builder_()
                .username("thomas")
                .password(passwordEncoder().encode("123456"))
                .roles("teacher")
                .build();
        //创建两个用户
        InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();
        userDetailsManager.createUser(user1);
        userDetailsManager.createUser(user2);
        return userDetailsManager;
    }
    /*
     * 从 Spring5 开始,强制要求密码要加密
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
   
        //使用加密算法对密码进行加密
        return new BCryptPasswordEncoder();
    }
  
} 

重启程序,再次测试即可,发现登录和访问没问题了

7 查看当前登录用户信息及配置用户权限

复制springsecurity-05-password-encode,复制后为springsecurity-06-loginuser-info

7.1 获取当前登录用户信息

新建一个controller

@RestController
  public class CurrentLoginUserInfoController {
    
    _/**
     * 从当前请求对象中获取
     */
    _@GetMapping("/getLoginUserInfo")
    public Principal getLoginUserInfo(Principal principle){
   
            return principle;
    }
    _/**
     *从当前请求对象中获取
     */
    _@GetMapping("/getLoginUserInfo1")
    public Authentication getLoginUserInfo1(Authentication authentication){
   
        return authentication;
    }
    _/**
     * 从安全应用上下文(SecurityContextHolder)获取安全应用上下文(SecurityContext),从安全应用上下文中获取认证信息
     * **@return
     ***/
    _@GetMapping("/getLoginUserInfo2")
    public Authentication getLoginUserInfo(){
   
        Authentication authentication = SecurityContextHolder._getContext_().getAuthentication();
        return authentication;
    }

}  

注意Authentication接口继承自 Principal
重启程序,访问

http://localhost:8080/getLoginUserInfo
http://localhost:8080/getLoginUserInfo1
http://localhost:8080/getLoginUserInfo2

运行结果

{
“authorities”: [{
“authority”: “ROLE_teacher”
}],
“details”: {
“remoteAddress”: “0:0:0:0:0:0:0:1”,
“sessionId”: “34E452050095348E6306CF95B2025CD9”
},
“authenticated”: true,
“principal”: {
“password”: null,
“username”: “thomas”,
“authorities”: [{
“authority”: “ROLE_teacher”
}],
“accountNonExpired”: true,
“accountNonLocked”: true,
“credentialsNonExpired”: true,
“enabled”: true
},
“credentials”: null,
“name”: “thomas” }

Principal 定义认证的而用户,如果用户使用用户名和密码方式登录,principal通常就是一个UserDetails(后面再说)
Credentials:登录凭证,一般就是指密码。当用户登录成功之后,登录凭证会被自动擦除,以防泄露。
authorities:用户被授予的权限信息。

7.2 配置用户权限

配置用户权限有两种方式:
配置roles
配置authorities
注意事项:
如果给一个用户同时配置roles和authorities,哪个写在后面哪个起作用
配置roles时,权限名会加上ROLE_。
修改WebSecurityConfig代码中的

    // 注意 1 哪个写在后面哪个起作用 2 角色变成权限后会加一个ROLE_前缀,比如ROLE_teacher
        //        UserDetails user2 = User.builder()

//                .username("thomas")

//                .password(passwordEncoder().encode("123456"))

//                .authorities("teacher:add","teacher:update")

//                .roles("teacher")

//                .build();
        UserDetails user2 = User._builder_()
                .username("thomas")             .password(passwordEncoder().encode("123456"))
                .roles("teacher")
                .authorities("teacher:add","teacher:update")
                .build();  

重启程序使用thomas登录,然后查看用户认证信息

http://localhost:8080/getLoginUserInfo

可以看到authorities的情况。
从设计层面讲,角色和权限是两个完全不同的东西
从代码层面来讲,角色和权限并没有太大区别,特别是在Spring Security中

8 授权(对URL进行授权)

上面讲的实现了认证功能,但是受保护的资源是默认的,默认所有认证(登录)用户均可以访问所有资源,不能根据实际情况进行角色管理,要实现授权功能,需重写WebSecurityConfigureAdapter 中的一个configure方法
复制springsecurity-06-loginuser-info 工程,然后改名为springsecurity-07-url
新建WebSecurityConfig类,重写configure(HttpSecurity http)方法
WebSecurityConfig 完整代码如下:

@Configuration

@Slf4j

  public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
   
    @Override
    protected void configure(HttpSecurity http) throws Exception {
   
        http.authorizeRequests()
                //角色student或者teacher都可以访问/student/** 这样的url
                .mvcMatchers("/student/*").hasAnyRole("student", "teacher")
                // 角色teacher 可以访问teacher/**
                .mvcMatchers("/teacher/**").hasRole("teacher")
                //权限admin:query 可以访问/admin**

//                .mvcMatchers("/admin/**").hasAuthority("admin:query")
                //角色teacher 或者权限admin:query 觉可以访问admin/**
                .mvcMatchers("/admin/**").access("hasRole('teacher') or hasAuthority('admin:query')")
                //任何请求均需要认证
                .anyRequest().authenticated();
        //使用表单登录
        http.formLogin();
    }
  
} 

使用admin登录,访问

http://localhost:8080/teacher/query
http://localhost:8080/student/query
http://localhost:8080/admin/query

分别查看效果,实现权限控制
上面是对URL资源进行控制,就是哪些权限可以访问哪些URL。

9 授权(方法级别的权限控制)

上面学习的认证与授权都是基于URL的,我们也可以通过注解灵活的配置方法安全,我们先通过@EnableGlobalMethodSecurity开启基于注解的安全配置。

9.1 新建模块springsecurity-08-method

9.2 添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency> 

9.3 新建启动类并复制 CurrentLoginUserInfoController类

新建启动类Application,学员自行创建

9.4 新建service及其实现

com.powernode.service 新建教师接口

public interface TeacherService {
   
    String add();
    String update();
    String delete();
    String query();
  } 

com.powernode.service.impl 实现接口文章来源地址https://www.toymoban.com/news/detail-420273.html

@Service

@Slf4j

  public class TeacherServiceImpl implements TeacherService {
   
    @Override
    public String add() {
   
        _log_.info("添加教师成功");
        return "添加教师成功";
    }
    @Override
    public String update() {
   
        _log_.info("修改教师成功");
        return "修改教师成功";
    }
    @Override
    public String delete() {
   
        _log_.info("删除教师成功");
        return "删除教师成功";
    }
    @Override
    public String query() {
   
        _log_.info("查询教师成功");
        return "查询教师成功";
    }
} 

9.5 修建TeacherController

@RestController

@RequestMapping("/teacher")

  public class TeacherController {
   
    @Reso

到了这里,关于【动力节点】springsecurity课程笔记6-13章的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 动力节点RocketMQ笔记第三章RocketMQ集成SpringBoot

    22.1.1 创建项目,完整的pom.xml 22.1.2 修改配置文件application.yml 22.1.3 我们在测试类里面测试发送消息 往powernode主题里面发送一个简单的字符串消息 运行后查看控制台 22.1.4 查看rocketMq的控制台 查看消息细节

    2024年02月04日
    浏览(27)
  • 老杜Java零基础视频笔记-第一章 学前准备(动力节点)

    为什么使用截图工具 在听课的过程中,有的时候老师操作的比较快,通过截图的方式将老师的操作保存下来,以便后期的操作。另外截图之后的图片也可以用于笔记的记录,在笔记当中最好采用图文并茂的方式,这样更加利于知识的回顾。 使用哪个截图工具 snipaste 免费 免安

    2024年02月07日
    浏览(39)
  • RabbitMQ笔记一7-11章RabbitMQ工作模型【动力节点】

    broker 相当于mysql服务器,virtual host相当于数据库(可以有多个数据库) queue相当于表,消息相当于记录。   消息队列有三个核心要素:  消息生产者 、 消息队列 、 消息消费者 ; 生产者(Producer):发送消息的应用;(java程序,也可能是别的语言写的程序) 消费者(Con

    2023年04月26日
    浏览(23)
  • 【动力节点】杜老师Vue笔记第七章vue3

    vue3官网地址 https://cn.vuejs.org/ vue3发布时间 2020年9月18日。 翻译: 今天,我们很自豪地宣布Vue.js 3.0“海贼王”正式发布。这个新的主要版本的框架提供了改进的性能、更小的捆绑包大小、更好的TypeScript集成、用于处理大规模用例的新API,以及为框架未来的长期迭代奠定了坚实

    2024年02月05日
    浏览(34)
  • 动力节点最新RocketMq笔记第一章RocketMQ基本操作

    MQ====Message Queue 官网: http://rocketmq.apache.org/ RocketMQ是阿里巴巴2016年MQ中间件,使用Java语言开发,RocketMQ 是一款开源的 分布式消息系统 ,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。同时,广泛应用于多个领域,包括异步通信解耦、企业解决方

    2024年02月07日
    浏览(38)
  • 动力节点最新Redis7笔记-第七章Redis缓存

    7.1.1 Jedis简介 Jedis是一个基于java的Redis客户端连接工具,旨在提升性能与易用性。 7.1.2 创建工程 首先创建一个普通的Maven工程01-jedis,然后在POM文件中添加Jedis与Junit依赖。 7.1.3 使用Jedis实例 Jedis基本使用十分简单,其提供了非常丰富的操作Redis的方法,而这些方法名几乎与R

    2024年02月07日
    浏览(50)
  • 动力节点RabbitMQ笔记-1-6章What is RabbitMQ?

    笔记出自: 动力节点最新RabbitMQ视频 RabbitMQ是一个广泛使用的消息服务器,采用Erlang语言编写,是一种开源的实现 AMQP(高级消息队列协议)的消息中间件; RabbitMQ最初起源于金融系统,它的性能及稳定性都非常出色; AMQP协议(http://www.amqp.org),即 Advanced Message Queuing Proto

    2023年04月25日
    浏览(35)
  • RocketMQ视频笔记第三章RocketMQ集成SpringBoot(动力节点)

    本篇文章是RocketMQ视频笔记的第三章,重点介绍了如何将RocketMQ集成到Spring Boot框架中。通过学习该文章,读者能够掌握如何使用RocketMQ和Spring Boot进行消息传递和处理。

    2024年02月05日
    浏览(42)
  • 【动力节点】最新rabbitmq笔记-1-6章What is RabbitMQ?

    动力节点最新RabbitMQ视频 RabbitMQ是一个广泛使用的消息服务器,采用Erlang语言编写,是一种开源的实现 AMQP(高级消息队列协议)的消息中间件; RabbitMQ最初起源于金融系统,它的性能及稳定性都非常出色; AMQP协议(http://www.amqp.org),即 Advanced Message Queuing Protocol,高级消息

    2024年02月03日
    浏览(32)
  • 动力节点Redis7笔记-第六章Redis分布式系统

    Redis分布式系统,官方称为Redis Cluster,Redis集群,其是Redis 3.0开始推出的分布式解决方案。其可以很好地解决不同Redis节点存放不同数据,并将用户请求方便地路由到不同Redis的问题。 分布式数据库系统会根据不同的数据分区算法,将数据分散存储到不同的数据库服务器节点上

    2024年02月07日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包