SpringSecurity入门(超级无敌认真好用,万字收藏篇!!!!)

这篇具有很好参考价值的文章主要介绍了SpringSecurity入门(超级无敌认真好用,万字收藏篇!!!!)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

SpringSecurity入门

本文属于SpringSecurity入门篇,后续学习过程中会持续更新

基于spring的安全框架

前言

什么是安全框架?

解决系统安全问题的框架,如果没有安全框架,我们就需要手动处理每个资源的访问控制,显得非常麻烦。使用安全框架后就可以使用配置的方式对资源进行访问控制。

常见的安全框架

  • Apache Shiro:一个功能强大且易于使用的安全框架,提供了认证,授权,加密,会话管理。
  • Spring Security:Spring家族中的一员,是一个能够为应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组Spring上下文配置的Bean,利用SpringIoc,DI和AOP功能,为应用系统提供声明式的安全访问控制功能,减少了企业系统安全控制编写大量重复代码工作。

1 SpringSecurity概述

SpringSecurity是一个高度自定制的安全框架,他利用SpringIoc,DI,AOP功能,为应用系统提供声明式的安全访问控制功能,减少企业系统安全控制编写大量重复代码工作。

SpringSecurity两大核心功能

  1. 认证:是建立一个主体的过程("主体"一般指用户,设备或可以在应用程序中执行动作的其他系统),简单说是指使用者通过账户名和密码登陆的整个过程称为认证。
  2. 授权:是指一个主体是否允许在应用程序中执行某个动作的过程,简单说就是给某个用户指定某个功能的访问权限。
  • SpringSecurity通过过滤器实现请求拦截,实现认证,授权等操作。

2 SpringSecurity的基本使用

  1. 引入Springboot和SpringSecurity相关依赖

       <parent>
            <groupId>org.springframework.boot</groupId>
            <version>2.7.9</version>
            <artifactId>spring-boot-starter-parent</artifactId>
        </parent>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>runtime</scope>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <excludes>
                            <exclude>
                                <groupId>org.projectlombok</groupId>
                                <artifactId>lombok</artifactId>
                            </exclude>
                        </excludes>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
  2. 创建springboot启动类

    @SpringBootApplication
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(Application.class);
        }
    }
    
  3. 创建Controller

    @RestController
    @RequestMapping("/test")
    public class TestController {
    
        @RequestMapping("/test01")
        public String test01(){
            return "test01";
        }
    
        @RequestMapping("/test02")
        public String test02(){
            return "test02";
        }
    }
    
  4. 启动测试跳入如下页面

    当在项目中引入SpringSecurity依赖后,整个项目就会被SpringSecurity管理起来

    未认证用户无权进入系统,会自动跳转到SpringSecurity提供的登陆页面

    springsecurity入门,JAVA小记,java,spring boot,spring,安全,mvc

  • 如图我们需要登陆才能访问

    密码在每次服务器启动时,控制台会自动生成一串字符串,如图所示

    默认用户名:user

    springsecurity入门,JAVA小记,java,spring boot,spring,安全,mvc

  1. 输入用户名和密码,进入test01页面

    springsecurity入门,JAVA小记,java,spring boot,spring,安全,mvc

  2. 自定义SpringSecurity登陆页面

    如果要使用自定义页面,需要SpringSecurity配置类中指定

    • 继承WebSecurityConfigurerAdapter

      • public class SecurityConfig extends WebSecurityConfigurerAdapter

        继承的方式可能会存在安全隐患,此方式已过时

    • 组装式定义SpringSecurity配置类

      /**
       * SpringSecurity配置类
       */
      @Configuration
      public class SecurityConfig {
      }
      
  • SecurityFilterChain方法

    用于拦截请求,并对请求进行处理

        /**
         * 用于拦截请求,并对请求进行处理
         * @param httpSecurity
         * @return  SecurityFilterChain:Security过滤器链
         */
        @Bean
        @Autowired
        public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
         httpSecurity
                 .csrf().disable()//禁用跨域请求伪造的攻击
                 //请求配置
                 .authorizeRequests()//获得所有认证请求
                     //防止发生重定向次数过多错误,需要将login.html放行
                    .antMatchers("/login.html","/fail.html")//匹配指定的路径
                        .permitAll()//无需认证即可访问
                    .anyRequest()//获得任意请求
                        .authenticated()//必须认证才允许访问
                 .and()
                 //配置form表单
                 .formLogin()//配置表单
                 	.loginProcessingUrl("/login")//配置登陆处理器的url地址,该地址所对应处理类由SpringSecurity提供
                    .loginPage("/login.html")//配置登陆页
                    .failureUrl("/fail.html")//登陆失败处理页
            ;
         return httpSecurity.build();//获得securityFilterChain的实现类对象并返回
        }
    
  • 上述拦截到页面直接无需认证让其放行,还有一种方式

    若拦截页面很多,则使用下列方式

        /**
         * 处理需要忽略的请求
         * @return
         */
        @Bean
        public WebSecurityCustomizer webSecurityCustomizer(){
            return new WebSecurityCustomizer(){
                @Override
                public void customize(WebSecurity web) {
                    //配置不拦截的路径(要忽略的路径)
                       web.ignoring().antMatchers("/login.html","/fail.html");
                }
            };
        }
    

3 SpringSecurity基于内置账户的实现

  • 设置账户时,每个账户都必须有一个角色
  • 密码必须加密,通过BCryptPasswordEncoder进行加密

SpringSecurity把设置的内存密码交给加密器进行加密,获得一个"盐",通过"盐"和输入的密码进行加密获得一个加密后的字符串,和设置的内存密码进行匹配,若一样登陆成功

用于处理认证和授权逻辑

  • 该方法内,可以定义认证和授权相关操
  • 此处功能:
    •  设置内存账户,根据内存账户自定义用户名和密码进行登陆
      
    •  `@param builder`    认证管理器的编译器对象,该对象由springSecurity自动注入
      
    /**
     *用于处理认证和授权逻辑
     * 该方法内,可以定义认证和授权相关操作
     * 此处功能:
     *      -设置内存账户,根据内存账户自定义用户名和密码进行登陆
     * @param builder    认证管理器的编译器对象,该对象由springSecurity自动注入
     */
    @Autowired
    public void registerProvider(AuthenticationManagerBuilder builder) throws Exception {
        //SpringSecurity要求密码必须加密,创建加密器对象
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        builder
                        .inMemoryAuthentication()//设置内存账户
                            .passwordEncoder(passwordEncoder)//设置密码加密器对象
                            .withUser("admin")//设置内置账户用户名
                            .password(passwordEncoder.encode("123456"))//设置内置账户密码
                            //SpringSecurity要求每个账户必须有一个角色,此处定义账户为设置角色
                            .roles("USER")//设置角色
                        ;
    }
  • 加入角色后,每个资源都必须设置一个角色

    在SecurityFilterChain方法设置

                    .antMatchers("/index.html")
                        .hasAnyRole("USER","ADMIN")
                    .antMatchers("/test/test01")
                        .hasRole("ADMIN")
                    .antMatchers("/test/test02")
                        .hasAnyRole("USER")
    
    • 上面设置允许角色"USER","ADMIN"访问资源index.html

      允许角色"USER"访问资源test/test01

      允许角色"ADMIN"访问资源test/test02

4 SpringSecurity基于数据库的实现

  • 创建bean

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class UserInfo implements Serializable {
        private Integer user_id;
        private String user_name;
        private String user_password;
        private String user_email;
        private Date user_birthday;
        private String user_hobbys;
        private Integer user_sex;
        private String user_address;
        private Integer user_status;
    
    }
    
  • 声明UserDetailsService对象并注入进认证管理器

    @Autowired
        private UserDetailsService userDetailsService; 
    @Autowired
        public void registerProvider(AuthenticationManagerBuilder builder) throws Exception {
            //SpringSecurity要求密码必须加密,创建加密器对象
            PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
            /**
             * 基于数据库
             */
            builder.userDetailsService(userDetailsService)//用于指定登陆的处理逻辑(认证逻辑)的对象
                    .passwordEncoder(passwordEncoder)//设置密码加密器
            ;
        }
    
  • 创建UserDetailsServiceImpl类并实现UserDetailsService接口

    该类需要实现接口中的loadUserByUsername方法,该方法返回值为UserDetails

    该方法作用

    1. 根据用户名获得用户信息
    2. 将用户信息认证需要的数据封装到UserDetails的实现类对象中(User)
    3. 将封装好的认证信息提交给SpringSecurity进行认证

    UserDetails接口中方法:

    • Collection<? extends GrantedAuthority> getAuthorities();获得权限集合
    • String getPassword();获得账号
    • String getUsername();获得密码
    • boolean isAccountNonExpired();判断账户是否过期(有效)
    • boolean isAccountNonLocked();判断账户是否被冻结
    • boolean isCredentialsNonExpired();凭证是否过期
    • boolean isEnabled();账户是否启用
    /**
     * 处理认证逻辑的类
     * + 该类需要重写接口中的loadUserByUsername方法根据用户名获得用户对象
     */
    @Service
    public class UserDetailsServiceImpl implements UserDetailsService {
        /**
         * 1.根据用户名获得用户信息
         * 2.将用户信息认证需要的数据封装到UserDetails的实现类对象中(User)
         * 3.将封装好的认证信息提交给SpringSecurity进行认证
         * @param username
         * @return
         * @throws UsernameNotFoundException
         */
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            return null;
        }
    }
    
  • 由于要根据用户名获得用户信息则创建UserMapper接口

    @Repository
    public interface UserMapper {
    
        /**
         *
         * 根据用户名获得用户对象
         * @param username
         * @return
         */
        @Select("select * from tbl_user where user_name=#{username}")
        public UserInfo getUserByUsername(String username);
    }
    
  • 根据三步完善UserDetailsServiceImpl

     	@Resource
        private UserMapper userMapper;
        /**
         * 1.根据用户名获得用户信息
         * 2.将用户信息认证需要的数据封装到UserDetails的实现类对象中(User)
         * 3.将封装好的认证信息提交给SpringSecurity进行认证
         * @param username
         * @return
         * @throws UsernameNotFoundException
         */
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
            //根据用户名获得用户信息
            UserInfo userInfo = userMapper.getUserByUsername(username);
            //检测用户名是否正确
            if (userInfo==null){
                  log.info("用户名不存在");
                  return null;
            }
            //检测用户是否为有效用户
            if (userInfo.getUser_status()==-1){
                log.info("用户被冻结");
                return null;
            }
            List<GrantedAuthority>  authorities =new ArrayList<>();
            authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
            //将UserInfo中认证需要数据封装到User对象中(UserDetails的实现类对象)
            User user = new User(userInfo.getUser_name()//附加数据
                             ,userInfo.getUser_password()//密码
                             ,true//账户是否启用
                             ,true//账户是否过期
                             ,true//凭证是否过期
                             ,userInfo.getUser_status()==-1?false:true//账户是否被锁定
                             ,authorities);//账户拥有的权限
            return user;//将该返回值交给SpringSecurity进行认证
    
        }
    

ps:小知识点

  • 前端的文本框和密码框name只能是username和password,要想使用其他name该如何解决

在配置from表单里设置

.formLogin()//配置表单
                    .loginProcessingUrl("/login")//配置登陆处理器的url地址,该地址所对应处理类由SpringSecurity提供
                    .loginPage("/login.html")//配置登陆页
                    .failureUrl("/fail.html")//登陆失败处理页
               		.usernameParameter("myusername")//前端文本框的name
           	        .passwordParameter("mypassword")//前端密码框的name

  • 学习来自于西安加中实训

文章来源地址https://www.toymoban.com/news/detail-605843.html

到了这里,关于SpringSecurity入门(超级无敌认真好用,万字收藏篇!!!!)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【JavaSE】保姆级教程|1万字+10张图入门到学会类与对象(建议收藏)

    🌱博主简介:大一计科生,努力学习Java中!热爱写博客~预备程序媛 📜所属专栏:爪洼岛冒险记【从小白到大佬之路】 ✈往期博文回顾: 【爪洼岛冒险记】第5站:多图解,超详细讲解Java中的数组、二维数组–建议收藏 🕵️‍♂️近期目标:成为千粉小博主。 🌺“再牛的程

    2023年04月19日
    浏览(47)
  • C生万物 | 指针入门到进阶就看这篇了【十万字吐血整理,收藏学习】

    文章篇幅较长,可前往电脑端进行学习💻 之前很多粉丝私信我说 C语言指针 怎么这么难,看了很多视频都学不懂,于是我写了一篇有关指针从入门到进阶的教学,帮助那些对指针很困扰的同学有一个好的学习途径,下面是本文的参考配套视频,出自b站【鹏哥C语言】,鹏哥讲

    2024年02月03日
    浏览(49)
  • Spring Boot入门(04):SpringBoot实现多环境配置文件切换 | 超级详细,建议收藏

            在开发和部署Spring Boot应用的过程中,经常需要在不同的环境中进行配置,比如开发环境、测试环境、生产环境等。为了方便管理和部署,我们需要实现多环境配置文件切换。本篇教程将带你轻松搞定不同环境部署问题,让你的应用在各个环境中稳定运行。无论你是

    2024年02月12日
    浏览(50)
  • 专门为Github党打造的超级无敌Chrome插件

    8 GitHub Linker 一个可以链接到 NPM、bower、Composer Duo 依赖等项目主页的 Chrome 插件。 9 GitHub Selfies GitHub Selfies 允许你从网络摄像头为你的 requests、issues 以及 comments 添加自拍。 10 Command 使用网络更好的增强斜线“/”命令。命令可以很容易地发送图片、歌曲、自拍emojis,更在任何文

    2024年04月16日
    浏览(43)
  • Spring Boot入门(03): yaml、properties配置文件介绍及使用 | 超级详细,建议收藏

            在软件开发中,配置文件是一项非常重要的内容。它们通常用于存储应用程序的各种设置和配置选项,包括数据库连接信息、日志级别、Web服务器端口、安全认证密钥等等。在不同的环境(例如开发、测试、生产)中,这些配置文件可能会有所不同。因此,良好的

    2024年02月11日
    浏览(46)
  • 专门为Github党打造的超级无敌Chrome插件(1)

    Octotree GitHub 现有的目录层级形式,在查看来自不同层级文件夹的文件的时候,显得似乎不是很方便,Octotree 这款 Chrome 插件能够让你通过文档库的方式管理、查看你的 GitHub 仓库,简单直观的同时,也方便你进行文件之间的跳转操作。同时支持Gitlab 3 Github Toc 允许你根据 Gith

    2024年04月27日
    浏览(25)
  • 【C语言】指针超级无敌金刚霹雳进阶(但不难,还是基础)

    点击这里访问我的博客主页~~ 对指针概念还不太清楚的点击这里访问上一篇指针初阶2.0 上上篇指针初阶1.0 谢谢各位大佬的支持咯 今天我们一起来学习指针进阶内容 指针变量有 字符指针变量 , 数组指针变量 和 函数指针变量 char* 叫做字符指针 一般这么来使用: 通过指针存

    2024年03月09日
    浏览(41)
  • Spring Boot入门(08):整合Mybatis访问MySQL实现增删改查 | 超级详细,建议收藏

            在现代的Web应用程序中,数据库操作是不可避免的。而Spring Boot作为一款快速开发框架,其优秀的集成能力非常适合与数据库交互,而MyBatis则是一个优秀的ORM框架,可以大大简化我们的数据库操作。本文将结合Spring Boot和MyBatis,带您实现高效的MySQL增删改查操作,

    2024年02月12日
    浏览(45)
  • [超级无敌详细系列]Visual Studio/c++配置opencv环境

    写在前面:如果这篇文章对大家有帮助的话,欢迎关注Franpper的公众号: Franpper的知识铺 , 回复“进群”,即可进入讨论群 ,有什么问题大家可以一起讨论呀! 目录 1、下载opencv安装包 2、 添加环境变量 3、 导入.dll(动态库)文件 4、 Visual Studio项目属性配置 5、验证安装结

    2024年02月07日
    浏览(54)
  • Spring Boot入门(14):使用Mybatis-Plus执行自定义SQL | 超级详细,建议收藏

            在上几期,我们既讲了如何整合Mybatis-Plus进行数据库的增删改查,也讲解了如何使用MP的 Wrapper 构造器,但若是遇到复杂业务逻辑,如多表联查、动态拼接条件等,这些操作往往会让代码变得冗长且难以维护。但是,有了Mybatis-Plus这个优秀的框架,我们可以轻松实现

    2024年02月12日
    浏览(35)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包