• srpingboot security demo


    《github代码地址》

    pom.xml

            <!--security-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    基于配置文件yaml的认证(不建议)

    spring:
      #基于配置文件的认证(不建议)
      security:
        user:
          name: test
          password: test
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    基于配置类的认证(不建议)

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    
    /**
     * 通过配置类实现认证(不建议)
     */
    @Configuration
    public class MyWebSecurity extends WebSecurityConfigurerAdapter {
        //在方法中配置用户名和密码,作为用户登录的数据
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            auth.inMemoryAuthentication().withUser("lucy").password(bCryptPasswordEncoder.encode("123")).roles();
        }
    
        @Bean
        PasswordEncoder passwordEncoder(){
            return new BCryptPasswordEncoder();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    自定义认证类(建议)

    注释MyWebSecurity

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
    import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
    
    import javax.annotation.Resource;
    import javax.sql.DataSource;
    
    /**
     * 自定义实现认证(建议)
     */
    @Configuration
    public class MyWebSecurity2 extends WebSecurityConfigurerAdapter {
        @Resource
        private UserDetailsService userDetailsService;
        //注入数据源
        @Resource
        private DataSource dataSource;
    
        @Bean
        public PersistentTokenRepository persistentTokenRepository(){
            JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
            jdbcTokenRepository.setDataSource(dataSource);
    //        jdbcTokenRepository.setCreateTableOnStartup(true);
            return jdbcTokenRepository;
        }
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.userDetailsService(userDetailsService);
        }
    
        @Bean
        PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            //登出
    //        http.logout().logoutUrl("/logout").logoutSuccessUrl("/login").permitAll();
    
            //登录
            http.formLogin()
    //                .loginPage("/login.html") //登录页面设置
    //                .loginProcessingUrl("/user/login")//登陆访问路径
    //                .defaultSuccessUrl("/hello").permitAll()//登录成功之后跳转的路径
                    .and()
                    .authorizeRequests()
                    .antMatchers("/", "/user/login").permitAll()//访问白名单
                    // 1. hasAuthority方法
    //                .antMatchers("/admin").hasAuthority("admin")//具有admin权限才能访问这个路径
                    // 2. hasAnyAuthority方法
    //                .antMatchers("/admin").hasAnyAuthority("admin,manager")
                    // 3. hasRole方法
    //                .antMatchers("/admin").hasRole("admin")//配置角色时要加ROLE_   如ROLE_admin
                    // 4. hasAnyRole方法
                    .antMatchers("/admin").hasAnyRole("admin,test")
                    .anyRequest().authenticated()
                    //自动登录
                    .and()
                    .rememberMe().tokenRepository(persistentTokenRepository())
                    .tokenValiditySeconds(60)//token过期时间秒
                    .userDetailsService(userDetailsService)
                    .and()
                    .csrf().disable();//关闭csrf跨站请求伪造攻击拦截
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

    RedisConfig

    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.JsonTypeInfo;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.RedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    
    @Configuration
    public class RedisConfig {
        /**
         * 防止数据存入redis乱码
         */
        @Bean(name="redisTemplate")
        public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
            // 设置序列化
            Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    //        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);//已过期
            om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance , ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
            jackson2JsonRedisSerializer.setObjectMapper(om);
            // 配置redisTemplate
            RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
            redisTemplate.setConnectionFactory(lettuceConnectionFactory);
            RedisSerializer<?> stringSerializer = new StringRedisSerializer();
            // key序列化
            redisTemplate.setKeySerializer(stringSerializer);
            // value序列化,可序列化对象
            redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
            // Hash key序列化
            redisTemplate.setHashKeySerializer(stringSerializer);
            // Hash value序列化,可序列化对象
            redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
            redisTemplate.afterPropertiesSet();
            return redisTemplate;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    Users实体类

    import lombok.Data;
    
    @Data
    public class Users {
        private Integer id;
        private String username;
        private String password;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    UsersMapper

    import com.fu.springsecuritydemo.entity.Users;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Component;
    
    import javax.annotation.Resource;
    
    /**
     * 用redis模拟查询数据库
     */
    @Component
    public class UsersMapper {
        @Resource
        private RedisTemplate redisTemplate;
    
        public void insert(Users users){
            redisTemplate.opsForValue().set(users.getId(),users);
        }
    
        public Users select(String username){
            return (Users) redisTemplate.opsForValue().get(username);
        }
    
        public void delete(Integer userId){
            redisTemplate.delete(userId);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    MyUserDetailsService

    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.AuthorityUtils;
    import org.springframework.security.core.userdetails.User;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    import java.util.List;
    
    @Service("userDetailsService")
    public class MyUserDetailsService implements UserDetailsService {
    
        @Resource
        private UsersMapper usersMapper;
    
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            //调用usersMapper根据用户名查询数据库
            Users users = usersMapper.select(username);
            //判断
            if (users == null){//数据库没有用户名,认证失败
                throw new UsernameNotFoundException("用户名不存在!");
            }
            List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("admin,ROLE_admin");//admin是权限,ROLE_admin是角色
            //从查询数据库返回users对象,得到用户名和密码,返回
            return new User(users.getUsername(),new BCryptPasswordEncoder().encode(users.getPassword()),auths);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    TestController

    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.annotation.Resource;
    
    @RestController
    public class TestController {
        @Resource
        private RedisTemplate<String,Object> redisTemplate;
    
        @GetMapping("hello")
        public String hello(){
            if (!redisTemplate.hasKey("lucy")){
                Users users = new Users();
                users.setId(1);
                users.setUsername("lucy");
                users.setPassword("123");
                redisTemplate.opsForValue().set(users.getUsername(),users);
            }
            return "hello";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    通过注解授权(建议)

    启动类加上 @EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true) 注解

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
    
    @SpringBootApplication
    @EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
    public class SpringSecurityDemoApplication {
        public static void main(String[] args) {
            SpringApplication.run(SpringSecurityDemoApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    TestController

    	@GetMapping("hello2")
        @Secured({"ROLE_admin"})//需要多个角色才能访问则用英文逗号配置如ROLE_admin,ROLE_test
        public String hello2(){
            return "hello2";
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    11.MySQL多表查询简介
    选课通知 | 北交大《人工智能与大数据应用实战》第二次开课,欢迎选修~
    ADB日常使用命令
    驱动开发:PE导出函数与RVA转换
    使用阿里PAI DSW部署Stable Diffusion WebUI
    目前工业界常用的推荐系统模型有哪些?
    【vue】下载导出excel
    【C语法学习】17 - fwrite()函数
    数据结构——排序算法——希尔排序
    STC32G 单片机EEPROM 操作实例
  • 原文地址:https://blog.csdn.net/weixin_43933728/article/details/125496118