当前位置: 首页 > news >正文

SpringSecurity 5

Spring认证和授权异常处理_exceptionhandling().authenticationentrypoint-CSDN博客 

        springSecurity是spring的一个顶级项目 也是一个安全框架,可以在spring框架中直接引用。

        springSecurity基于RBAC用来处理登录功能和各种权限校验。

〇、配置和运行springSecurity

         导入security启动器和web启动器,写一个springBoot的启动类,可以直接在springboot项目中运行security框架。

        1)配置

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

         2)启动并访问

            3)默认登录用户

                        默认的密码直接在控制台打印出来了

                        默认的用户名是user

           3.5)修改默认用户配置     

                        

           4)登录成功

                        没有进行任何配置,404就登录成功了。



〇点五、关闭csrf防护

        csrf防护是security框架默认开启的安全机制。

        每次向服务器发送请求时,响应界面中都会携带一个token字符串,再次提交表单会携带此字符串和服务器中存储的token比较。

        如果没有该防护,用户登录security项目,再访问第三方网站:

                这时第三方网页中内嵌有security项目的相关url请求,

                用户就在无意识中跟随第三方的意识访问了security项目,

                而这个访问可以是提交表单,修改数据,转账操作。

        要使用csrf防护机制也很简单

        只需要在界面中添加name值为_csrf    的隐藏域

        每次发送请求携带此键值对就ok。

        这里学习security框架时可以先行关闭csrf防护,具体操作是在全局配置调用方法                  http.csrf().disable();



一、全局配置      放行登录url

           1)创建配置类

                     WebSecurityConfigurerAdapter是默认的security框架全局配置类,

                      security框架调用的配置方法为该类的configure(HttpSecurity http),

                     修改全局配置只需要新建一个继承该类的配置类重写该方法。

        2)创建登录界面 和 登录控制器

                2.1)使用thymeleaf技术创建界面login.html

                                这里用户名默认为username

                                           密码默认为password

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

   

        3)在配置类中配置 表单、用户请求 的访问规则

http.formLogin().loginProcessingUrl("/login")   //用户发送登录表单请求的url,会执行登录认证.successHandler((request, response, authentication) ->{request.getRequestDispatcher("/index").forward(request,response);})                 //成功后的自定义处理.failureForwardUrl("/404")    //失败的处理.loginPage("/myLogin");       //登录网址
http.authorizeRequests().antMatchers("/myLogin").permitAll() //.antMatchers("拦截路径")permitAll()表示放行         .anyRequest().authenticated(); //拦截所有的请求进行登录认证,校验是否登录
http.csrf().disable();                 //关闭csrf防护

        4)测试



 二、自定义用户名密码检验规则  

     1)重写校验类,实现自定义校验        

                需要实现一个接口UserDetailsService,这个接口其实是security框架提供给我们的自定义校验的接口,

                实现该接口,生成该实现类对象的话,security框架就不会使用默认的内置接口实现类对象进行校验。

                

       2)在配置类的配置方法中配置密码解析器

                        



三、remember-me记住我  

             0)security完成的接口调用

                        使用记住我功能登录security框架以后,关闭浏览器后直接访问该项目,无需再次登录,记住我功能在浏览器cookie中存储了一个token字符串,并在数据库中也存储该token。

                        再次打开浏览器,不仅会校验token值,也会根据token表中记录的用户名校验用户表,如果token值一样,但是用户表中没有查询相关用户信息仍然不通过。

             1)   登录界面添加值为true,键名为remember-me的复选框

           2)配置dataSource对象需要的依赖

<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.4</version>
</dependency>

         3)注入dataSource提供给security框架token表操作对象jdbcTokenRepository

         4)在配置类中写一个配置对象jdbcTokenRepository完成数据库表初始化

                     jdbcTokenRepository对象创建了表结构,并连接数据库检验token值

 @Beanpublic JdbcTokenRepositoryImpl jdbcTokenRepository(){JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();jdbcTokenRepository.setDataSource(dataSource);
//        jdbcTokenRepository.setCreateTableOnStartup(true);return jdbcTokenRepository;}

         5)设置rememberMe配置

                        把用户名校验对象userDetailsService和token表操作对象jdbcTokenRepository扔进去完成rememberMe配置

   //配置RememberMe相关信息:http.rememberMe().userDetailsService(userDetailsService) //调用其完成用户信息的查询.tokenRepository(jdbcTokenRepository) ; //调用其完成token的校验
//                .tokenValiditySeconds(3600*24*3) ;//设置token的有效期,单位秒
//                .rememberMeParameter("wollo");//设置记住我请求数据的键名


四、session会话管理

        在security框架的全局配置中:

                  session会话失效后使用InvalidSessionStrategy类的方法处理时总是需要加上这样一句话request.getSession(),因为所有会话无效的请求都会自动调用该方法。为了避免自循环创建一个有效的会话对象。

    // 会话配置http.sessionManagement(session ->{// 会话失效跳转的页面//       session.invalidSessionUrl("/login");// 会话失效处理器session.invalidSessionStrategy(new InvalidSessionStrategy() {@Overridepublic void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {request.getSession();response.sendRedirect("/login");}});//最大并发会话数,设置单个用户允许同时在线的最大会话数,重新登录的会话会踢掉旧的会话.session.maximumSessions(1);});



五、使用access表达式实行指定url访问控制

        1)在ExpressionInterceptUrlRegistry类中封装好了许多常用的access表达式:

        


        2)自己写一个access表达式

                2.1)封装好的denyAll()和access("denyAll()")一样的效果。

               2.2)自定义校验方法

                                这里access表达式调用方法时规则:

                                        使用@符号调用方法

                                        写bean的id及调用方法

                                        参数名必须叫request,authentication



六、用户退出功能

        1)security默认的登出url请求: /out

                不需要任何配置,只需要发送请求就能实现登出功能。

                2)配置类中 自定义  登出配置

     //登出配置http.logout().logoutUrl("/out").logoutSuccessUrl("/myLogin")  //成功的跳转路径
//                         .logoutSuccessHandler(new LogoutSuccessHandler() {
//                             @Override
//                             public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//                                 response.sendRedirect("/myLogin");
//                             }
//                         })    //自定义逻辑实现成功跳转.clearAuthentication(true)  //清除登录状态.invalidateHttpSession(true) ; //销毁session

                 3)踢出指定用户

                        3.1)配置类中创建sessionRegistry对象

                            3.2)控制器中实现踢出方法

public void kickOutUser(String username) {// 1.获取全部登录用户List<Object> allPrincipals = sessionRegistry.getAllPrincipals();// 2.遍历全部登录用户,找到要强制登出的用户for (Object principal : allPrincipals) {UserDetails userDetail = (UserDetails) principal;if (username.equals(userDetail.getUsername())) {// 3.找到认证用户所有的会话,不包含过期会话List<SessionInformation> sessions = sessionRegistry.getAllSessions(userDetail, false);if (null != sessions && !sessions.isEmpty()) {// 4.遍历该用户的会话,使其立即失效for (SessionInformation session : sessions) {session.expireNow();}}}}}



七、权限校验

              1)配置类中使用access表达式实现权限校验

                      两个hasRole方法是不同类实现的

                                前者必须加ROLE_。


       2)使用注解实现权限校验

   



八、security框架异常401 403处理 

        针对认证和授权两种功能,认证失败通常抛出401,授权失败抛出403

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 2024.9.18
  • Collections.synchronizedList()
  • 课程首发 | 微软 AI 创新日推荐官招募中
  • General OCR Theory: Towards OCR-2.0 via a Unified End-to-end Model
  • 如何使用ssm实现基于vue.js的购物商场的设计与实现+vue
  • git push命令报错:the remote end hung up unexpectedly
  • 【Transformer深入学习】之一:Sinusoidal位置编码的精妙
  • 升降梯人数识别摄像机
  • 为什么程序员都要了解GPT,学会构建AI大模型?了解GPT大模型,读这本书就够了!
  • Python学习——【2.3】for循环
  • Prometheus监控k8s环境构建
  • JAVA与Python谁更适合后端?
  • Vscode整合PHP Server 和debug
  • 亲测有效,长期有效的RTSP流地址公网RTSP地址,各种类型的视频源
  • Python精选200Tips:141-145
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • 30天自制操作系统-2
  • css属性的继承、初识值、计算值、当前值、应用值
  • Facebook AccountKit 接入的坑点
  • Python_网络编程
  • Shadow DOM 内部构造及如何构建独立组件
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 从0到1:PostCSS 插件开发最佳实践
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 我有几个粽子,和一个故事
  • 一天一个设计模式之JS实现——适配器模式
  • ​ ​Redis(五)主从复制:主从模式介绍、配置、拓扑(一主一从结构、一主多从结构、树形主从结构)、原理(复制过程、​​​​​​​数据同步psync)、总结
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • #考研#计算机文化知识1(局域网及网络互联)
  • (1)(1.11) SiK Radio v2(一)
  • (Python第六天)文件处理
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (Ruby)Ubuntu12.04安装Rails环境
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (附源码)计算机毕业设计高校学生选课系统
  • (生成器)yield与(迭代器)generator
  • (五)MySQL的备份及恢复
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .NET MVC之AOP
  • .NET关于 跳过SSL中遇到的问题
  • .NET设计模式(8):适配器模式(Adapter Pattern)
  • .Net实现SCrypt Hash加密
  • [5] CUDA线程调用与存储器架构
  • [ABC275A] Find Takahashi 题解
  • [Android 数据通信] android cmwap接入点
  • [AutoSar]BSW_OS 02 Autosar OS_STACK
  • [BUUCTF 2018]Online Tool
  • [BZOJ2208][Jsoi2010]连通数
  • [Doc][px4][ros2][gazebo][yolov8]PX4-ROS2-Gazebo-YOLOv8
  • [EFI]Lenovo ThinkPad X280电脑 Hackintosh 黑苹果引导文件
  • [flask] flask的基本介绍、flask快速搭建项目并运行