• Spring Security 基础教程 -- 密码加密和方法安全


    密码加密

    一般来说,密码是需要加密再存入数据库的,常用哈希函数进行加密。

    密码加密与通信加密是有区别的。

    通信加密是可逆加密,加密之后还需要解密,主要有对称加密和非对称加密两种。密码加密可以是单向加密,即加密之后不需要解密。

    为了保证相同的明文加密后生成的密文不一样,在加密过程中需要使用盐(salt)。

    在 Spring Security 中,提供了BCryptPasswordEncoder类,进行密码的加密,且相同的明文,加密后的密文是不一样的。

    示例

    在测试类中,写一个测试方法:

    @SpringBootTest
    class SecurityApplicationTests {
    
        @Test
        void contextLoads() {
            for (int i=0; i<10; i++){
                BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
                System.out.println(encoder.encode("123456"));
            }
        }
    }
    

    打印结果如下:

    $2a$10$/zpce9GF4fW0xmfCWZk2MuHSX9frcj1JIMk7n1TPcUHDfU1clqy/i
    $2a$10$Ihh9bkrN4KQjRF4BNbCwdeUgu779riYXofpVZu9djIjix2wAJo8tC
    $2a$10$BnMc9GSCLKNrgXpKRgHNYucQqcm/Mu.W21pfmm/DEKvQ0qoeAqYs6
    $2a$10$t2HljppbnA7NbBllkqgNB.lE655sD2ZPW6F2Y9ITZiEMJJTZUxTpS
    $2a$10$WyZkBbv1VakuTJFm9AbEHOgtIt1ZjIPEIDpOLNdOnEjvcW.t34Vki
    $2a$10$Lq3/QQLIgqiicGfEZL1YP.OVZ46X2WfPMOAz6iMJnNm/oWUs4/F1.
    $2a$10$2e1PSKN80/WSWsxdUcrSHe2EmD30M4IZfQog6mGw9H5Ul1jfu63aK
    $2a$10$VZcLRImtB18O1aV29ShRrONzygpCigBO3eROSyJ2035.AVkrgKpPa
    $2a$10$SW9ydYyb9BCnmSPSmdg2P.NP4XBduCDIlnl.hxIh3/M/d/fUr83DK
    $2a$10$hLWCemE7MVWtczl57shsQeF9nUILLmG0tooKh61sKW3Un17o18JSC
    

    可以看出,相同的明文 123456 ,生成的 10 次密文都是不一样的。

    在方法configure(AuthenticationManagerBuilder auth),将明文密码替换成密文密码:

    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        /**
         * 调用加密算法 BCryptPasswordEncoder
         */
        @Bean
        PasswordEncoder passwordEncoder(){
    //        return NoOpPasswordEncoder.getInstance();
            return new BCryptPasswordEncoder();
        }
    
        /**
         * 定义两个用户,并设置密码和角色
         * 从 Spring5.0 开始,密码必须要加密
         * 基于内存的用户认证
         * @param auth
         * @throws Exception
         */
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication()
                    .withUser("admin")
                    .password("$2a$10$9UwAaMnKSZHUloUl65mpWu01VF5ANLrmD/rsb6eGP4bc2f45.1.iG")
                    .roles("admin")
                    .and()
                    .withUser("user1")
                    .password("$2a$10$JnwOr9kXPg97mgOkUG2Qhe7b0Qrtr9BDm7G410p8sr6SPJoZupxP2")
                    .roles("user");
        }
    }
    

    关于 BCryptPasswordEncoder的加密、验证策略的源码分析,参考文章:BCryptPasswordEncoder加密、验证策略

    方法安全

    方法安全,即是直接在方法上加注解,来确保方法安全地执行。

    示例

    方法安全默认是关闭的,使用方法安全,首先需要在 SecurityConfig配置类上,加注解:

    @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
    

    新建一个 MethodService 类,在方法上进行安全注解:

    @Service
    public class MethodService {
        /**
         * 必须是角色 admin 才能调用这个方法
         */
        @PreAuthorize("hasRole('admin')")
        public String admin(){
            return "hello admin!";
        }
    
        /**
         * 只有角色 user 才能调用这个方法
         * @return
         */
        @Secured("ROLE_user")
        public String user(){
            return "hello user!";
        }
    
        /**
         * 角色 admin和user 都可以调用这个方法
         * @return
         */
        @PreAuthorize("hasAnyRole('admin', 'user')")
        public String hello(){
            return "hello hello!";
        }
    }
    

    再注入到 Controller 类中,测试一下 MethodService 中的方法:

        @Autowired
        MethodService methodService;
    
        @GetMapping("/hello1")
        public String hello1(){
            return methodService.admin();
        }
    
        @GetMapping("/hello2")
        public String hello2(){
            return methodService.user();
        }
    
        @GetMapping("/hello3")
        public String hello3(){
            return methodService.hello();
        }
    

    如果使用角色 admin 登录,就能成功调用接口 /hello1/hello3

    如果使用角色 user 登录,就能成功调用接口 /hello2/hello3

    这就是方法安全。

    每天学习一点点,每天进步一点点。

  • 相关阅读:
    2022321内部群每日三题清辉PMP
    PMP内部群每日错题回顾(一周目)
    2022225内部群每日三题清辉PMP
    202233内部群每日三题清辉PMP
    2022214内部群每日三题清辉PMP
    2022223内部群每日三题清辉PMP
    Qt6以上安装速度慢解决国内镜像加速
    2022.3.9内部群每日三题清辉PMP
    2022228内部群每日三题清辉PMP
    2022215内部群每日三题清辉PMP
  • 原文地址:https://www.cnblogs.com/youcoding/p/13915385.html
Copyright © 2020-2023  润新知