版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第7章SpringBoot安全管理《SpringBoot企业级开发教程(第2版)》学习目标/Target了解安全框架概述,能够简述SpringSecurity和Shiro的作用掌握SpringSecurity入门案例,能够基于SpringBoot项目完成SpringSecurity入门案例了解SpringSecurity结构总览,能够简述SpringSecurity过滤器处理请求的流程熟悉SpringSecurity认证流程,能够简述SpringSecurity的认证流程掌握SpringSecurity自定义身份认证,能够基于内存身份认证、JDBC身份认证和自定义UserDetailsService实现用户身份认证学习目标/Target熟悉SpringSecurity授权流程,能够简述SpringSecurity的授权流程掌握SpringSecurity自定义授权,能够使用Web授权和方法授权实现用户授权管理掌握SpringSecurity会话管理,能够在SpringSecurity中获取认证后的用户信息,以及进行会话控制掌握SpringSecurity用户退出,能够在SpringBoot项目中实现使用SpringSecurity实现用户退出掌握动态展示菜单,能够通过SpringSecurity的授权管理实现动态展示菜单章节概述/Summary实际开发中,开发者为了确保Web应用的安全性,通常需要保护Web应用的用户信息、数据信息等资源不受侵害,例如,对于某些指定的功能,需要先对访问的用户进行身份验证,验证通过后还需要具备相关权限之后才可以操作。下面将对SpringBoot的安全管理进行详细地讲解。目录/Contents7.17.2安全框架概述SpringSecurity基础入门7.3SpringSecurity认证管理7.4SpringSecurity授权管理7.5SpringSecurity会话管理和用户退出安全框架概述7.17.1
安全框架概述先定一个小目标!
先定一个小目标!了解安全框架概述,能够简述SpringSecurity和Shiro的作用7.1
安全框架概述Java中的安全框架通常是指解决Web应用安全问题的框架,如果开发Web应用时没有使用安全框架,开发者需要自行编写代码增加Web应用安全性。自行实现Web应用的安全性并不容易,需要考虑不同的认证和授权机制、网络关键数据传输加密等多方面的问题,为此Web应用中通常会选择使用一些成熟的安全框架,这些安全框架基本都提供了一套Web应用安全性的完整解决方案,以便提升Web应用的安全性。Java中常用的安全框架有SpringSecurity和Shiro,这两个安全框架都提供了强大功能,可以很容易实现Web应用的很多安全防护。下面对这两个安全框架的特点进行讲解。7.1
安全框架概述1.SpringSecuritySpringSecurity是Spring生态系统中重要的一员,是一个基于AOP思想和Servlet过滤器实现的安全框架,它提供了完善的认证机制和方法级的授权功能,是一款非常优秀的权限管理框架。SpringSecurity伴随着Spring生态系统不断修正、升级,使用SpringSecurity减少了为企业系统安全控制编写大量重复代码的工作,在SpringBoot项目中使用SpringSecurity十分简单。7.1
安全框架概述1.SpringSecurity使用SpringSecurity可以很方便地实现Authentication(认证)和Authorization(授权),其中认证是指验证用户身份的过程,授权是指验证用户是否有权限访问特定资源的过程。SpringSecurity在架构上将认证与授权分离,并提供了扩展点。SpringSecurity具有以下的特点。灵活:SpringSecurity提供了一系列可扩展的模块,可以根据具体需求进行选择和配置。安全:SpringSecurity集成了一系列安全措施,包括XSS(Cross-SiteScripting,跨站脚本)攻击防范、CSRF攻击防范、点击劫持攻击防范等。易用:SpringSecurity提供了一系列快捷配置选项,可以使开发人员轻松地实现认证和授权等功能。社区支持:SpringSecurity作为Spring生态系统的一部分,与Spring无缝整合,并且得到了社区广泛的支持和更新维护。7.1
安全框架概述2.ShiroShiro是apache旗下一个开源框架,它将软件系统的安全认证相关功能抽取出来,实现用户身份认证,授权、加密、会话管理等功能,组成了一个通用的安全认证框架。Shiro具有如下特点。易于理解的JavaSecurityAPI。简单的身份认证,支持LDAP,JDBC等多种数据源。支持对角色的简单鉴权,也支持细粒度的鉴权。支持一级缓存,以提升应用程序的性能。内置的基于POJO企业会话管理,适用于Web以及非Web的环境。不跟任何的框架或者容器捆绑,可以独立运行。7.1
安全框架概述不管SpringSecurity还是Shiro,在进行安全管理的过程中都涉及权限管理的两个重要概念:认证和授权。权限管理是指根据系统设置的安全规则或者安全策略,用户可以访问且只能访问自己被授权的资源。实现权限管理通常需要三个对象,分别为用户、角色、权限,这三个对象的说明如下。用户:主要包含用户名、密码和当前用户的角色信息,可以实现认证操作。角色:主要包含角色名称、角色描述和当前角色拥有的权限信息,可以实现授权操作。权限:权限也可以称为菜单,主要包含当前权限名称、url地址等信息,可以实现动态展示菜单。SpringSecurity基础入门7.27.2.1SpringSecurity入门案例先定一个小目标!
先定一个小目标!掌握SpringSecurity入门案例,能够基于SpringBoot项目完成SpringSecurity入门案例7.2.1SpringSecurity入门案例本入门案例主要演示SpringSecurity在SpringBoot中的安全管理效果。为了更好地使用SpringBoot整合实现SpringSecurity安全管理功能,体现案例中Authentication(认证)和Authorization(授权)功能的实现,本案例在SpringBoot项目中结合SpringMVC和Thymeleaf实现访问图书管理后台页面。7.2.1SpringSecurity入门案例使用SpringInitializr方式创建一个名为chapter07的SpringBoot项目,在Dependencies依赖选择中选择SpringWeb、Thymeleaf和SpringSecurity的依赖,然后根据提示完成项目创建。1.创建SpringBoot项目7.2.1SpringSecurity入门案例在项目的resources目录的templates和static文件夹中,分别引入案例的模板文件,以及页面所需的静态资源文件。2.导入页面资源7.2.1SpringSecurity入门案例2.导入页面资源导入的页面文件有3个,其中main.html为图书管理的主页面,book_list.html为图书列表页面,该页面展示所有可阅读的图书信息,book_manag.html为图书管理页面,该页面可以对图书进行增删改等操作,这3个页面的核心代码如文件7-1~文件7-3所示。文件7-1main.html文件7-2book_list.html文件7-3book_manag.html源代码7.2.1SpringSecurity入门案例3.创建控制器类在项目的java目录下创建包com.itheima.chapter07.controller,并在该包下创建实体类控制器类BookController,在该类中定义处理图书列表和图书管理请求的方法,具体如文件7-4所示。文件7-4BookController.java源代码7.2.1SpringSecurity入门案例4.添加配置类导入的页面文件有3个,其中main.html为图书管理的主页面,book_list.html为图书列表页面,该页面在项目的java目录下创建包com.itheima.chapter07.config,并在该包下创建配置类WebMvcConfig,在该类中添加视图路径映射,实现访问项目首页自动映射到后台管理首页,具体如文件7-5所示。文件7-5WebMvcConfig.java源代码7.2.1SpringSecurity入门案例5.测试项目效果启动项目,在浏览器访问“http://localhost:8080/”。7.2.1SpringSecurity入门案例5.测试项目效果查看IDEA控制台信息,信息中包含一些特别的内容。7.2.1SpringSecurity入门案例5.测试项目效果在默认登录页面中使用SpringSecurity提供的账号,以及生成的随机密码进行登录。7.2.2SpringSecurity结构总览先定一个小目标!
先定一个小目标!了解SpringSecurity结构总览,能够简述SpringSecurity过滤器处理请求的流程7.2.2SpringSecurity结构总览当初始化SpringSecurity时,会创建一个类型为org.springframework.security.web.FilterChainProxy,名称为springSecurityFilterChain过滤器,这个过滤器实现了javax.servlet.Filter接口,外部请求系统资源时会经过此过滤器。7.2.2SpringSecurity结构总览SpringSecurity安全管理的实现主要是由过滤器链中一系列过滤器相互配合完成,下面对过滤器链中主要的几个过滤器及其作用分别进行说明。SecurityContextPersistenceFilter:是整个拦截过程的入口和出口,也就是第一个和最后一个拦截器。UsernamePasswordAuthenticationFilter:用于处理来自表单提交的认证,提交的表单必须提供对应的用户名和密码。FilterSecurityInterceptor:用于保护Web资源,获取所配置资源访问的授权信息。CsrfFilter:SpringSecurity会对所有Post请求验证是否包含系统生成的csrf的token信息,如果不包含,则报错,起到防止csrf攻击的效果。ExceptionTranslationFilter:能够捕获来自FilterChain所有的异常,并进行处理。DefaultLoginPageGeneratingFilter:如果没有在配置文件中指定认证页面,则由该过滤器生成一个默认认证页面。SpringSecurity认证管理7.37.3
SpringSecurity认证管理认证是SpringSecurity的核心功能之一,SpringSecurity所提供的认证可以更好地保护系统的隐私数据与资源,只有当用户的身份合法后方可访问该系统的资源。SpringSecurity提供了默认的认证相关配置,开发者也可以根据自己实际的环境进行自定义身份认证配置。下面对SpringSecurity的认证流程以及自定义认证进行讲解。7.3.1SpringSecurity认证流程先定一个小目标!
先定一个小目标!熟悉SpringSecurity认证流程,能够简述SpringSecurity的认证流程7.3.1SpringSecurity认证流程用户认证就是判断一个用户的身份是否合法的过程,用户访问系统资源时系统要求验证用户的身份信息,身份合法方可继续访问,否则拒绝其访问。7.3.1SpringSecurity认证流程SpringSecurity的认证流程进行详细介绍。①用户提交用户名和密码进行认证请求后,被SecurityFilterChain中的UsernamePasswordAuthenticationFilter过滤器获取到,将用户名和密码封装到UsernamePasswordAuthenticationToken对象中,该对象为Authentication的实现类。②过滤器将封装用户名和密码的Authentication对象提交至AuthenticationManager(认证管理器)进行认证。③AuthenticationManager根据当前的认证类型进行认证,认证时会根据提交的用户信息最终返回一个SpringSecurity的UserDetails对象,如果返回的UserDetails对象为空,则说明认证失败,抛出异常。7.3.1SpringSecurity认证流程④如果返回的UserDetails对象不为空,则返回UserDetails对象,最后AuthenticationManager认证管理器返回一个被填充满了信息的Authentication实例,包括权限信息,身份信息,细节信息,但密码通常会被移除。⑤SecurityContextHolder安全上下文容器存放填充了信息的Authentication,认证成功后通过SecurityContextHolder.getContext().setAuthentication()方法,将Authentication设置到其中。7.3.2SpringSecurity自定义身份认证先定一个小目标!
先定一个小目标!掌握SpringSecurity自定义身份认证,能够基于内存身份认证、JDBC身份认证和自定义UserDetailsService实现用户身份认证7.3.2SpringSecurity自定义身份认证尽管项目启动时,SpringSecurity会提供了默认的用户信息,可以快速认证和启动,但大多数应用程序都希望使用自定义的用户认证。对于自定义用户认证,SpringSecurity提供了多种认证方式,常用的有In-MemoryAuthentication(内存身份认证)、JDBCAuthentication(JDBC身份认证)和UserDetailsService(身份详情服务)。下面对SpringSecurity的这三种自定义身份认证进行详细讲解。7.3.2SpringSecurity自定义身份认证以内存身份认证时,需要在SpringSecurity的相关组件中进行指定当前认证方式为内存身份认证。SpringSecurity5.7.1开始SpringSecurity将WebSecurityConfigurerAdapter类标注为过时,推荐直接声明配置类,在配置类中直接定义组件的信息。本书使用SpringBoot2.7.6,其对应的SpringSecurity版本为5.7.5。自定义内存身份认证时,可以通过InMemoryUserDetailsManager类实现,InMemoryUserDetailsManager是UserDetailsService的一个实现类,方便在内存中创建一个用户。对此,只需
在自定义配置类中创建InMemoryUserDetailsManager实例,在该实例中指定该实例的认证信息,并存入在Spring容器中即可。1.内存身份认证7.3.2SpringSecurity自定义身份认证(1)创建配置类在chapter07项目中创建名为com.itheima.config的包,并在该包下创建一个配置类WebSecurityConfig,在该类中创建UserDetailsService类型的InMemoryUserDetailsManager实例对象交由Spring容器管理,具体如文件7-6所示。1.内存身份认证文件7-6WebSecurityConfig.java源代码7.3.2SpringSecurity自定义身份认证进行自定义用户认证时,需要注意以下几个问题。提交认证时会对输入的密码使用密码编译器进行加密并与正确的密码进行校验。如果不想要对输入的密码进行加密,需要在密码前对使用{noop}进行标注。从SpringSecurity5开始,自定义用户认证如果没有设置密码编码器,也没有在密码前使用{noop}进行标注,会认证失败。自定义用户认证时,可以定义用户角色roles,也可以定义用户权限authorities,在进行赋值时,权限通常是在角色值的基础上添加“ROLE_”前缀。自定义用户认证时,可以为某个用户一次指定多个角色或权限。1.内存身份认证7.3.2SpringSecurity自定义身份认证(2)验证内存身份认证启动项目后,查看控制台输出的信息,发现没有默认安全管理时随机生成了密码。在浏览器访问项目首页“http://localhost:8080/”。1.内存身份认证7.3.2SpringSecurity自定义身份认证使用不是文件7-6中设置的用户信息进行登录。1.内存身份认证7.3.2SpringSecurity自定义身份认证使用文件7-6中设置的用户信息进行登录。1.内存身份认证7.3.2SpringSecurity自定义身份认证JDBC身份认证是通过JDBC连接数据库,基于数据库中已有的用户信息进行身份认证,这样避免了内存身份认证的弊端,可以实现对系统已注册的用户进行身份认证。JdbcUserDetailsManager是SpringSecurity内置的UserDetailsService的实现类,使用JdbcUserDetailsManager可以通过JDBC将数据库和SpringSecurity连接起来。下面对JDBC身份认证方式进行讲解。2.JDBC身份认证7.3.2SpringSecurity自定义身份认证(1)数据准备使用之前创建的名为springbootdata的数据库,在该数据库中创建三个表user、priv和user_priv,并预先插入几条测试数据。准备数据的SQL语句如文件7-7所示。2.JDBC身份认证文件7-7security.sql源代码7.3.2SpringSecurity自定义身份认证(2)配置依赖打开chapter07项目的pom.xml文件,在该文件中添加JDBC的启动器依赖。2.JDBC身份认证pom.xml源代码7.3.2SpringSecurity自定义身份认证(3)设置配置信息在项目chapter07中创建配置文件
application.yml,在该文件中设置数据库连接的相关配置信息,具体如文件7-8所示。2.JDBC身份认证文件7-8application.yml源代码7.3.2SpringSecurity自定义身份认证(4)修改配置类修改文件7-6中WebSecurityConfig配置类userDetailsService()方法,将该方法创建的实例对象修改为JdbcUserDetailsManager,修改后的代码如文件7-9所示。2.JDBC身份认证文件7-9WebSecurityConfig.java源代码7.3.2SpringSecurity自定义身份认证(5)效果测试重启chapter07项目进行效果测试,项目启动成功后,通过浏览器访问“http://localhost:8080/”后使用错误的数据库用户信息进行登录。2.JDBC身份认证7.3.2SpringSecurity自定义身份认证使用正确的数据库用户信息进行登录。2.JDBC身份认证7.3.2SpringSecurity自定义身份认证使用InMemoryUserDetailsManager和JdbcUserDetailsManager进行身份认证时,其真正的认证逻辑都在UserDetailsService接口重写的loadUserByUsername()方法中。对于一个完善的项目来说,通常会实现用户信息查询服务,对此可以自定义一个UserDetailsService实现类,重写该接口的loadUserByUsername()方法,在该方法中查询用户信息,将查询到的用户信息填充到UserDetails对象返回,以实现用户的身份认证。下面通过案例对自定义UserDetailsService进行身份验证的实现进行演示。3.自定义UserDetailsService身份认证7.3.2SpringSecurity自定义身份认证(1)创建实体类在项目chapter07的java目录下创建包com.itheima.chapter07.entity,在该包下创建用户实体类UserDto和权限实体类Privilege,具体如文件7-10和文件7-11所示。文件7-10UserDto.java文件7-11Privilege.java源代码3.自定义UserDetailsService身份认证7.3.2SpringSecurity自定义身份认证(2)创建用户持久层接口在项目chapter07的java目录下创建包com.itheima.chapter07.dao,在该包下创建用户持久层接口,在接口中定义查询用户及角色信息的方法,具体如文件7-12所示。文件7-12UserDao.java源代码3.自定义UserDetailsService身份认证7.3.2SpringSecurity自定义身份认证(3)封装用户认证信息在项目chapter07的java目录下创建包com.itheima.chapter07.service,在该包下创建UserDetailsServiceImpl类,该类实现UserDetailsService接口,并在重写的loadUserByUsername()方法中封装用户认证信息,具体如文件7-13所示。文件7-13UserDetailsServiceImpl.java源代码3.自定义UserDetailsService身份认证7.3.2SpringSecurity自定义身份认证(4)效果测试将文件7-8中的userDetailsService()方法进行注释,使用自定义UserDetailsService身份认证。重启chapter07项目进行效果测试,项目启动成功后,在浏览器通过“http://localhost:8080/”访问项目首页后,使用错误的数据库用户信息进行登录。3.自定义UserDetailsService身份认证7.3.2SpringSecurity自定义身份认证使用正确的数据库用户信息进行登录。3.自定义UserDetailsService身份认证SpringSecurity授权管理7.47.4
SpringSecurity授权管理授权是SpringSecurity的核心功能之一,是根据用户的权限来控制用户访问资源的过程,拥有资源的访问权限则可正常访问,没有访问的权限时则会被拒绝访问。认证是为了保证用户身份的合法性,而授权则是为了更细粒度地对隐私数据进行划分,授权是在认证通过后发生的,以控制不同的用户访问不同的资源。SpringSecurity提供了授权方法,开发者通过这些方法进行用户访问控制,下面对SpringSecurity的授权流程以及自定义授权进行讲解。7.4.1SpringSecurity授权流程先定一个小目标!
先定一个小目标!熟悉SpringSecurity授权流程,能够简述SpringSecurity的授权流程7.4.1SpringSecurity授权流程实现授权需要对用户的访问进行拦截校验,校验用户的权限是否可以操作指定的资源。SpringSecurity使用标准Filter建立了对Web请求的拦截,最终实现对资源的授权访问。7.4.1SpringSecurity授权流程①拦截请求。已认证用户访问受保护的Web资源将被SecurityFilterChain中FilterSecurityInterceptor实例对象拦截。②获取资源访问策略。FilterSecurityInterceptor实例对象会通过SecurityMetadataSource的子类DefaultFilterInvocationSecurityMetadataSource实例对象中获取要访问当前资源所需要的权限,权限封装在Collection实例对象中。SecurityMetadataSource是读取访问策略的抽象,具体读取的内容,就是开发者配置的访问规则。③FilterSecurityInterceptor通过AccessDecisionManager进行授权决策,若决策通过,则允许访问资源,否则将禁止访问。AccessDecisionManager中包含一系列AccessDecisionVoter,可对当前认证过的身份是否有权访问对应的资源进行投票,AccessDecisionManager根据投票结果做出最终决策。7.4.2SpringSecurity自定义授权先定一个小目标!
先定一个小目标!掌握SpringSecurity自定义授权,能够使用Web授权和方法授权实现用户授权管理7.4.2SpringSecurity自定义授权SpringSecurity的底层实现本质是通过多个Filter形成的过滤器链完成,过滤器链中提供了默认的安全拦截机制,设置安全拦截规则,以控制用户的访问。HttpSecurity是SecurityBuilder接口的实现类,是HTTP安全相关的构建器,SpringSecurity中可以通过HttpSecurity对象设置安全拦截规则,并通过该对象构建过滤器链。1.Web授权根据授权的位置和形式,通常可以将授权的方式分为Web授权和方法授权,这两种授权方式都会调用AccessDecisionManager进行授权决策。下面分别对这两种自定义授权的方式进行讲解。7.4.2SpringSecurity自定义授权HttpSecurity可以根据不同的业务场景,对不同的URL采用不同的权限处理策略。当开发者需要配置项目的安全拦截规则时,可以调用HttpSecurity对象对应的方法实现。1.Web授权方法作用authorizeRequests()开启基于HttpServletRequest请求访问的限制formLogin()开启基于表单的用户登录httpBasic()开启基于HTTP请求的Basic认证登录logout()开启退出登录的支持sessionManagement()开启Session管理配置rememberMe()开启“记住我”功能csrf()配置CSRF跨站请求伪造防护功能HttpSecurity类的常用方法7.4.2SpringSecurity自定义授权通过authorizeRequests()方法可以添加用户请求控制的规则,这些规则通过用户请求控制的相关方法指定。1.Web授权用户请求控制的常用方法方法作用antMatchers(String...antPatterns)开启Ant风格的路径匹配mvcMatchers(String...patterns)开启MVC风格的路径匹配,与Ant风格类似regexMatchers(String...regexPatterns)开启正则表达式的路径匹配and()功能连接符anyRequest()匹配任何请求rememberMe()开启“记住我”功能access(Stringattribute)使用基于SpEL表达式的角色进行匹配7.4.2SpringSecurity自定义授权1.Web授权用户请求控制的常用方法方法作用hasAnyRole(String...roles)匹配用户是否有参数中的任意角色hasRole(Stringrole)匹配用户是否有某一个角色hasAnyAuthority(String...authorities)匹配用户是否有参数中的任意权限hasAuthority(Stringauthority)匹配用户是否有某一个权限authenticated()匹配已经登录认证的用户fullyAuthenticated()匹配完整登录认证的用户(非rememberMe登录用户)hasIpAddress(StringipaddressExpression)匹配某IP地址的访问请求permitAll()无条件对请求进行放行7.4.2SpringSecurity自定义授权1.Web授权基于表单的身份验证的常见方法通过HttpSecurity类的formLogin()方法开启基于表单的用户登录后,可以指定表单认证的相关设置。方法作用loginPage(StringloginPage)指定自定义登录界面,不使用SpringSecurity默认登录界面loginProcessingUrl(StringloginProcessingUrl)指定处理登录的请求url,为表单提交用户信息的ActionsuccessForwardUrl(StringforwardUrl)指定登录成功后默认跳转的路径7.4.2SpringSecurity自定义授权下面通过案例演示在SpringBoot项目中使用SpringSecurity的Web授权方式进行权限管理。1.Web授权(1)导入登录页面在项目chapter07的resources目录的templates文件夹中导入自定义的登录页面。文件7-14login.html源代码7.4.2SpringSecurity自定义授权1.Web授权(2)编辑配置类在项目chapter07的WebSecurityConfig配置类中使用HttpSecurity对象设置安全拦截规则,并创建SecurityFilterChain对象交由Spring管理,具体代码如文件7-15所示。文件7-15WebSecurityConfig.java源代码7.4.2SpringSecurity自定义授权1.Web授权(2)编辑配置类文件7-5的WebMvcConfig配置类中添加loginview的视图映射,具体代码如文件7-16所示。文件7-16WebMvcConfig.java源代码7.4.2SpringSecurity自定义授权1.Web授权(3)测试效果启动项目chapter07,在浏览器中通过“http://localhost:8080/”访问项目首页。7.4.2SpringSecurity自定义授权1.Web授权在登录页面使用zhangsan的用户信息进行登录。7.4.2SpringSecurity自定义授权1.Web授权图书管理需要角色为ROLE_ADMIN的用户才可以访问,用户zhangsan的角色为ROLE_COMMON,在后台首页单击“图书管理”链接。7.4.2SpringSecurity自定义授权1.Web授权使用用户lisi进行登录,lisi对应的角色为ROLE_ADMIN,登录成功再次访问“图书管理”。7.4.2SpringSecurity自定义授权2.方法授权SpringSecurity除了可以在配置类中通过创建过滤器链设置安全拦截规则外,还可以使用@Secured、@RolesAllowed和@PreAuthorize注解控制类中所有方法或者单独某个方法的访问权限,以实现对访问进行授权管理。7.4.2SpringSecurity自定义授权2.方法授权使用@Secured和@RolesAllowed注解时,只需在注解中指定访问当前注解标注的类或方法所需要具有的角色,允许多个角色访问时,使用大括号对角色信息进行包裹,角色信息之间使用分号分隔即可。@RequestMapping("list")@Secured({"ROLE_ADMIN","ROLE_COMMON"})publicStringfindList(){return"book_list";}@RequestMapping("admin/manag")@RolesAllowed("ROLE_ADMIN")publicStringfindManagList(){return"book_manag";}7.4.2SpringSecurity自定义授权2.方法授权@PreAuthorize注解会在方法执行前进行权限验证,支持SpEL表达式。@RequestMapping("list")@PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_COMMON')")publicStringfindList(){return"book_list";}@RequestMapping("admin/manag")@PreAuthorize("hasRole('ROLE_ADMIN')")publicStringfindManagList(){return"book_manag";}7.4.2SpringSecurity自定义授权2.方法授权@Secured、@RolesAllowed和@PreAuthorize注解都可以对方法的访问进行权限控制。@Secured为SpringSecurity提供的注解。@RolesAllowed为基于JSR250规范的注解。@PreAuthorize支持SpEL表达式。7.4.2SpringSecurity自定义授权2.方法授权SpringSecurity默认是禁用方法级别的安全控制注解,要想使用注解进行方法授权,可以使用@EnableGlobalMethodSecurity注解开启基于方法的安全认证机制,该注解可以标注在任意配置类上。@Configuration@EnableGlobalMethodSecurity(securedEnabled=true,jsr250Enabled=true,prePostEnabled=true)publicclassWebSecurityConfig{……}7.4.2SpringSecurity自定义授权2.方法授权(1)开启基于方法的安全认证机制在项目chapter07的WebSecurityConfig配置类中开启基于方法的安全认证机制,并将类中HttpSecurity对象设置的访问“图书管理”拦截规则删除,以确保对资源授权地为方法授权,修改后的代码如文件7-17所示。文件7-17WebSecurityConfig.java源代码7.4.2SpringSecurity自定义授权2.方法授权(2)方法授权在文件7-4BookController类的findManagList()方法上使用注解指定访问该方法所需的角色,具体如文件7-18所示。文件7-18BookController.java源代码7.4.2SpringSecurity自定义授权2.方法授权(3)测试效果启动项目chapter07,在浏览器中通过“http://localhost:8080/”访问项目首页后,使用用户zhangsan登录系统。7.4.2SpringSecurity自定义授权2.方法授权单击左侧的“图书管理”链接。7.4.2SpringSecurity自定义授权2.方法授权在用户登录页面使用用户lisi进行登录,登录成功后再次访问“图书管理”。7.4.3动态展示菜单先定一个小目标!
先定一个小目标!掌握动态展示菜单,能够通过SpringSecurity的授权管理实现动态展示菜单7.4.3动态展示菜单在前面的讲解中,只是通过SpringSecurity对后台资源的访问根据角色进行权限控制,前端页面并没有做任何处理,不同角色能看到的前端页面是一样的,即使当前用户没有对应的访问权限,依然能看到对应的菜单,用户体验较差。下面在前面案例的基础上,讲解如何使用SpringSecurity与Thymeleaf整合实现前端页面根据登录用户的角色动态展示菜单。7.4.3动态展示菜单在chapter07项目的pom.xml文件中添加Thymeleaf与SpringSecurity5的集成包:thymeleaf-extras-springsecurity5。pom.xml源代码1.添加依赖7.4.3动态展示菜单打开chapter07项目后台首页main.html,引入SpringSecurity安全标签,并在页面中根据需求使用SpringSecurity标签指定为不同角色显示不同的页面内容,实现动态展示控制,具体如文件7-19所示。文件7-19main.html源代码2.修改页面代码7.4.3动态展示菜单重启chapter07项目进行效果测试,项目启动后,使用用户zhangsan的信息进行登录,登录后展示后台首页。3.效果测试7.4.3动态展示菜单使用用户lisi的信息进行登录,登录后展示后台首页。3.效果测试SpringSecurity会话管理和用户退出7.57.5
SpringSecurity会话管理和用户退出用户认证通过后,为了避免用户的每次操作都进行认证,可以将用户的信息保存在会话中。会话就是系统为了保持当前用户的登录状态所提供的机制,常见的有基于Session方式、基于Token方式等。SpringSecurity提供会话管理功能,只需要配置即可使用。同时,如果想结束当前会话,可以在自定义退出功能中销毁会话中的用户信息。下面将在SpringBoot项目中基于SpringSecurity实现会话管理和用户退出。7.5.1会话管理先定一个小目标!
先定一个小目标!掌握SpringSecurity会话管理,能够在SpringSecurity中获取认证后的用户信息,以及进行会话控制7.5.1会话管理SpringSecurity对用户信息认证通过后,会将用户信息存入SpringSecurity应用的上下文对象SecurityContext中,SecurityContext与当前线程进行绑定,需要获取用户信息时,可以通过SecurityContextHolder获取SecurityContext对象,进而使用SecurityContext对象获取用户信息。Authenticationauthentication=
SecurityContextHolder.getContext().getAuthentication();if(!authentication.isAuthenticated()){returnnull;}UserDetailsuserDetails=(UserDetails)authentication.getPrincipal();Stringusername=userDetails.getUsername();1.获取用户信息7.5.1会话管理默认情况下,SpringSecurity会为每个登录成功的用户新建一个Session对象进行会话管理,开发者也可以根据具体的需求对Session的创建进行控制。SpringSecurity管理Session的创建策略有以下四种。always:如果没有Session就创建一个。ifRequired:如果需要就创建一个Session,是默认的创建策略。never:Spring
Security将不会创建Session,但是如果项目中其他地方创建了Session,那么SpringSecurity可以使用它。stateless:Spring
Security将绝对不会创建Session,也不使用Session。2.会话控制7.5.1会话管理2.会话控制当项目中不想自动创建Session,但是想要使用项目中其他地方创建的Session时,可以选择使用never策略。@BeanpublicSecurityFilterChainsecurityFilterChain(HttpSecurityhttp)throwsException{http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);returnhttp.build();}7.5.1会话管理2.会话控制SpringSecurity对用户信息认证通过后,会将用户信息存入SpringSecurity应用的上下文对象如果项目中允许创建Session,默认情况下Session的超时时间为30分钟,如果想要对Session默认的超时时间进行修改,可以在SpringBoot的配置文件中设置Session的超时时间。server:servlet:session:timeout:86400s7.5.2用户退出先定一个小目标!
先定一个小目标!掌握SpringSecurity用户退出,能够在SpringBoot项目中实现使用SpringSecurity实现用户退出7.5.2用户退出Springsecurity默认实现了用户退出的功能,用户退出主要考虑退出后会话如何管理以及跳转到哪个页面。HttpSecurity类提供了logout()方法开启退出登录的支持,默认触发用户退出操作的URL为“/logout”,用户退出时同时也会清除Session等默认用户配置。用户退出登录的逻辑是由过滤器LogoutFilter执行的,但是项目开发时一般不会选择直接操作LogoutFilter,而是通过LogoutConfigurer对LogoutFilter进行配置,HttpSecurity类logout()方法的返回值就是一个LogoutConfigurer对象,该对象提供了一系列设置用户退出的方法。7.5.2用户退出用户退出的主要方法方法作用logoutUrl(StringlogoutUrl)用户退出处理控制URL,默认为post请求的/logoutlogoutSuccessUrl(StringlogoutSuccessUrl)用户退出成功后的重定向地址logoutSuccessHandler(LogoutSuccessHandlerlogoutSuccessHandler)用户退出成功后的处理器设置deleteCookies(String...cookieNamesToClear)用户退出后删除指定CookieinvalidateHttpSession(booleaninvalidateHttpSession)用户退出后是否立即清除Session,默认为trueclearAuthentication(booleanclearAuthentication)用户退出后是否立即清除Authentication用户认证信息,默认为true7.5.2用户退出下面通过案例演示用户退出的实现。1.设置用户退出的请求路径项目后台首页main.html右上方有一个“注销”菜单,可以在该菜单中设置用户退出的请求路径,具体如文件7-20所示。文件7-20main.html源代码7.5.2用户退出2.效果测试重启chapter07项目进行效果测试,项目启动成功后,使用正确的用户信息登录后进入后台首页,单击后台首页页面右上角的“注销”。本章小结本章主要对SpringBoot项目中的安全管理进行了讲解。首先讲解了安全框架概述;然后讲解了SpringSecurity基础入门;接着讲解了SpringSecurity认证管理和授权管理;最后对SpringSecurity会话管理和用户退出进行了讲解。通过本章的学习,希望大家可以在SpringBoot项目中正确使用SpringSecurity进行安全管理。本章小结第8章SpringBoot消息服务《SpringBoot企业级开发教程(第2版)》学习目标/Target熟悉常见消息中间件,能够说出4种常见的消息中间件名称和特点熟悉使用消息服务的好处,能够通过不同的场景说出使用消息服务的好处了解RabbitMQ简介,能够说出RabbitMQ消息代理流程熟悉RabbitMQ工作模式,能够说出RabbitMQ支持的工作模式,以及每种模式的工作原理掌握RabbitMQ的下载、安装和配置,能够在Windows平台安装和配置RabbitMQ,并成功启动RabbitMQ学习目标/Target掌握RabbitMQ入门案例,能够独立实现RabbitMQ入门案例掌握SpringBoot整合RabbitMQ环境搭建,能够在SpringBoot项目中整合RabbitMQ掌握使用Routing模式实现消息服务,能够在SpringBoot项目中使用Routing模式实现消息服务掌握使用Topics模式实现消息服务,能够在SpringBoot项目中使用Topics模式实现消息服务掌握使用Publish/Subscribe模式实现消息服务,能够在SpringBoot项目中使用Publish/Subscribe模式实现消息服务章节概述/Summary在实际项目开发中,有时候需要与其他系统进行集成完成相关业务功能,这种情况最原始的做法是程序内部相互调用,除此之外,还可以使用消息服务中间件进行业务处理,使用消息服务中间件处理业务能够提升系统的异步通信和扩展解耦能力。SpringBoot对消息服务管理提供了非常好的支持,下面将对SpringBoot消息服务的原理和整合使用进行详细讲解。目录/Contents8.18.2消息服务概述RabbitMQ快速入门8.3SpringBoot与RabbitMQ整合实现消息服务概述8.18.1
消息服务概述Java中的消息服务是指不同应用程序之间或同一个应用程序的不同组件之间通信的API,包括创建、发送、读取消息等,用于支持JAVA应用程序开发。在J2EE中,当两个组件使用Java消息服务进行通信时,发送消息的组件通常称为消息生产者,使用发送过来的数据的组件称为消息消费者,消息生产者与消息消费者之间并不是直接相连,而是通过一个共同的消息收发服务连接起来,消息生产者和消息消费者双方无须相互了解消息服务的实现细节,只需了解交换消息的格式即可。消息服务这种机制实现了组件之间的解耦,因此更加灵活。下面对常用消息中间件以及使用消息服务的优势进行讲解。8.1.1常用消息中间件先定一个小目标!
先定一个小目标!熟悉常见消息中间件,能够说出4种常见的消息中间件名称和特点8.1.1常用消息中间件消息队列(MessageQueue,MQ)是一种能实现消息生产者到消息消费者单向通信的通信模型,通常将实现了这个模型的组件称为消息队列中间件(简称消息中间件)。消息中间件通过高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。目前开源的消息中间件可谓是琳琅满目,能让大家耳熟能详的有很多,例如ActiveMQ、RabbitMQ、Kafka、RocketMQ等,也有直接使用Redis充当消息队列的案例,而这些消息中间件各有侧重,在实际选型时,需要结合具体需求来选择。下面对常用的消息中间件进行介绍。8.1.1常用消息中间件1.ActiveMQActiveMQ是采用Java语言编写的完全基于Java消息服务(JavaMessageService,JMS)规范的面向消息的中间件,它为应用程序提供高效、可扩展的、稳定的、安全的企业级消息通信。ActiveMQ丰富的API和多种集群构建模式使其成为业界老牌的消息中间件,在中小型企业中应用广泛。相较于后续出现的RabbitMQ、RocketMQ、Kafka等消息中间件来说,ActiveMQ性能相对较弱,在如今的高并发、大数据处理的场景下显得力不从心,经常会出现一些问题,例如消息延迟、堆积、堵塞等。8.1.1常用消息中间件2.RabbitMQRabbitMQ是使用Erlang语言开发的开源消息队列系统,支持高级消息队列协议(AdvancedMessageQueuingProtocol,AMQP,可扩展通讯和表示协议,ExtensibleMessagingandPresenceProtocol,XMPP)等。AMQP是应对大规模并发活动提供统一消息服务的应用层标准高级消息队列协议,专为面向消息的中间件设计,该协议更多用在企业系统内对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求不是很高。RabbitMQ具有并发能力强、性能好、消息延迟低、社区活跃、管理界面丰富等特性,使得其在应用开发中越来越受欢迎。8.1.1常用消息中间件3.KafkaKafka是它是一种采用Scala和Java语言编写的高吞吐量分布式发布订阅消息系统,提供了快速的、可扩展的、分布式的、分区的和可复制的日志订阅服务,其主要特点是追求高吞吐量,适用于会产生大量数据的互联网服务的数据收集业务。8.1.1常用消息中间件4.RocketMQRocketMQ使用纯Java语言编写,具有高吞吐量、高可用性、适合大规模分布式系统应用的特点。RocketMQ的思路起源于Kafka,对消息的可靠传输和事务性做了优化,目前被广泛应用于交易、充值、流计算、消息推送、日志流式处理场景。8.1.2
使用消息服务的好处先定一个小目标!
先定一个小目标!熟悉使用消息服务的好处,能够通过不同的场景说出使用消息服务的好处8.1.2
使用消息服务的好处在多数应用尤其是分布式系统中,消息服务是不可或缺的重要部分,它使用起来比较简单,同时解决了不少难题,例如应用解耦、异步提速、流量削峰、分布式事务管理等,使用消息服务可以实现一个高性能、高可用、高扩展的系统。下面使用实际开发中的若干场景来分析和说明使用消息服务的好处。8.1.2
使用消息服务的好处1.应用解耦8.1.2
使用消息服务的好处2.异步提速8.1.2
使用消息服务的好处3.流量削峰8.1.2
使用消息服务的好处4.分布式事务管理RabbitMQ快速入门8.28.2.1
RabbitMQ简介先定一个小目标!
先定一个小目标!了解RabbitMQ简介,能够说出RabbitMQ消息代理流程8.2.1
RabbitMQ简介AMQP是一种与平台无关的线路级的消息中间件协议,其通过制定协议来统一数据交互的格式。AMQP是跨语言的,它只制定协议,不规定实现语言和实现方式。RabbitMQ是基于AMQP标准,使用Erlang语言开发的消息中间件,在SpirngBoot中对RabbitMQ进行了集成管理。8.2.1
RabbitMQ简介在所有的消息服务中,消息中间件都会作为一个第三方消息代理,接收发布者发布的消息,并推送给消息消费者。8.2.1
RabbitMQ简介Connection:代表客户端(包括消息生产者和消息消费者)与RabbitMQ之间的连接。Channel:消息通道,位于连接内部,负责实际的通信。在客户端的每个连接里,可建立多个Channel。Broker:表示消息队列服务器实体,Broker会维护从消息生产者到消息消费者的路线,保证数据能按照指定的方式进行传输。VirtualHost:虚拟主机,包含交换机、消息队列等对象。Exchange:交换机,用于接收消息生产者发送的消息,并根据分发规则将这些消息路由给服务器中的队列。Queue:队列,是消息的载体,每个消息都会被投到一个或多个队列中,等待消息消费者连接到这个队列将其取走。Binding:交换机和消息队列之间的虚拟连接。8.2.1
RabbitMQ简介RabbitMQ消息代理流程如下。消息生产者(发送消息的程序)和消息队列服务器实体建立连接后,向指定的虚拟主机发送消息。虚拟主机内部的交换机接收消息生产者发送过来的消息,并将消息传递并存储到与之绑定的消息队列中。消息消费者(等待接收消息的程序)通过网络连接与消息队列服务器实体建立连接,在连接内部使用消息通道进行消息的最终消费。8.2.2
RabbitMQ工作模式先定一个小目标!
先定一个小目标!熟悉RabbitMQ工作模式,能够说出RabbitMQ支持的工作模式,以及每种模式的工作原理8.2.2
RabbitMQ工作模式1.简单模式RabbitMQ是一个消息代理,它接收和转发消息,RabbitMQ的简单模式不用声明交换机,只需要定义一个队列,消息生产者会将消息交给默认的交换机,默认的交换机将获取到的信息绑定到消息生产者对应的队列,消息消费者监听这个队列,当队列中有消息时,消息消费者执行消息消费。8.2.2
RabbitMQ工作模式2.WorkQueuesWorkQueues模式即工作队列模式,在WorkQueues模式中,同样不需要设置交换机,RabbitMQ会使用内部默认交换机进行消息转换,只需要指定唯一的消息队列进行消息传递。WorkQueues模式和简单模式的主要区别在于,WorkQueues模式可以有多个消息消费者。在这种模式下,多个消息消费者通过轮询的方式依次接收消息队列中存储的消息,一旦消息被某一个消息消费者接收,消息队列会将消息移除,而接收并处理消息的消费者必须在消费完一条消息后再准备接收下一条消息。8.2.2
RabbitMQ工作模式3.Publish/SubscribePublish/Subscribe模式即发布/订阅模式,在Publish/Subscribe模式中,必须先显式配置一个fanout类型的交换机,消息生产者将消息发送到交换机,同时会将消息路由到每一个消息队列上,然后每个消息队列都可以对相同的消息进行接收和存储,进而由各自消息队列关联的消费者进行消费。8.2.2
RabbitMQ工作模式4.RoutingRouting模式即路由模式,在Routing模式中,必须先配置一个direct类型的交换机,并指定一个RoutingKey。队列与交换机的绑定也需要指定一个RoutingKey,发送消息时交换机不再把消息交给每一个绑定的队列,而是根据消息的RoutingKey进行判断,只有队列的RoutingKey与消息的RoutingKey完全一致时,才会接收到消息,最后由消息消费者进行消费。8.2.2
RabbitMQ工作模式5.Topics(通配符模式)Topics模式即通配符模式,在Topics模式中必须先配置一个topic类型的交换机,并指定不同的Routingkey,根据Routingkey将对应的消息从交换机路由到不同的消息队列进行存储,然后由消息消费者进行消费。Topics模式与Routing模式的主要不同在于,Topics模式设置的路由键包含通配符。其中,“#”用于匹配多个字符,“*”用于匹配一个字符,然后与其他字符一起用“.”进行连接。8.2.2
RabbitMQ工作模式6.RPCRPC模式与WorkQueues模式主体流程相似,都不需要设置交换机,只需要指定唯一的消息队列进行消息传递。RPC模式与WorkQueues模式的主要不同在于,RPC模式是一个回环结构,主要对分布式架构的消息传递业务,客户端(Client)先发送消息到消息队列,远程服务端(Server)获取消息,然后再写入另一个消息队列,向原始客户端(Client)响应消息处理结果。8.2.2
RabbitMQ工作模式7.PublisherConfirmsPublisherConfirms模式即发布者确认模式,是AMQP0.9.1协议的RabbitMQ扩展,默认情况下不启用,发布者在通道上启用发布者确认后,代理将异步确认客户端发布的消息。PublisherConfirms模式最大的好处在于它是异步的,一旦发布一条消息,消息生产者就可以在等信道返回确认的同时继续发送下一条消息,当消息最终得到确认之后,消息生产者应用便可以通过回调方法来处理该确认消息。8.2.3
RabbitMQ的下载、安装和配置先定一个小目标!
先定一个小目标!掌握RabbitMQ的下载、安装和配置,能够在Windows平台安装和配置RabbitMQ,并成功启动RabbitMQ8.2.3
RabbitMQ的下载、安装和配置1.RabbitMQ下载在RabbitMQ官网首页的GetStarted版块中单击“Download+Installation”按钮进入RabbitMQ的下载页面。8.2.3
RabbitMQ的下载、安装和配置1.RabbitMQ下载在RabbitMQ的下载页面单击“ChocolateyorInstaller”超链接,进入基于Windows平台的安装包下载页面。8.2.3
RabbitMQ的下载、安装和配置2.RabbitMQ安装和配置RabbitMQ是使用Erlang语言开发的,安装RabbitMQ之前需要先安装Erlang语言包。RabbitMQ3.11.5需要Erlang的最小版本为25.0,最大版本为25.1。RabbitMQ安装包和Erlang语言包的安装都非常简单,只需要双击下载的安装文件进行安装,然后“下一步”、“安装”即可完成,在此就不对安装过程进行讲解。8.2.3
RabbitMQ的下载、安装和配置2.RabbitMQ安装和配置完成Erlang和RabbitMQ的安装后,进一步对RabbitMQ的启动进行配置,具体步骤如下。(1)配置环境变量在Path系统变量中添加值“%ERLANG_HOME%\bin;”就可以将Erlang的bin路径添加到Path系统变量中。为了确保Erlang安装成功,并且环境变量设置成功,在CMD窗口中任意路径下输入erl命令进行验证。8.2.3
RabbitMQ的下载、安装和配置2.RabbitMQ安装和配置(2)启动插件编辑完环境变量后,在CMD窗口中进入RabbitmQ的sbin目录,通过命令启动RabbitMQ的插件。rabbitmq-pluginsenablerabbitmq_management8.2.3
RabbitMQ的下载、安装和配置2.RabbitMQ安装和配置(3)启动RabbitMQ进入RabbitmQ的sbin目录,双击“rabbitmq-server.bat”文件启动RabbitMQ服务,此时会弹出CMD窗口显示启动情况。8.2.3
RabbitMQ的下载、安装和配置2.RabbitMQ安装和配置RabbitMQ安装过程中默认提供了用户名和密码均为guest的用户,可以使用该账户进行登录。8.2.4
RabbitMQ入门案例先定一个小目标!
先定一个小目标!掌握RabbitM
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 一年级口算练习题大全(可直接打印A4)
- 文书模板-《固定资产移交报告》
- 玻璃制造的保温与隔热效应考核试卷
- 家庭纺织品的销售模式与渠道考核试卷
- 学校书法教师工作总结5篇
- 知识产权保护的重要性考核试卷
- 山东省青岛市李沧区2024-2025学年六年级上学期期中英语试卷
- 林业可再生能源产业的开发与利用考核试卷
- 焙烤食品制造中的产品质量标准与认证体系考核试卷
- DB11T 932-2012 数字化城市管理信息系统部件和事件处置
- 人教版四年级英语上册Unit-3-测试卷附答案-
- 广东省深圳市福田区2023-2024学年三年级上学期11月期中科学试题
- 银行副行长转正申请工作总结
- 人教版七年级下册数学第八章二元一次方程组应用题-方案问题
- 98S205 消防增压稳压设备选用与安装(隔膜式气压罐)
- 改善人因绩效
- 炉头设备安全操作规定
- 托管安全责任承诺书范文(19篇)
- 隧道岩溶处治关键技术
- -常规化验单解读
- 关于生活中物理的课件
评论
0/150
提交评论