Spring Security

一、什么是Spring Security?
SpringSecurity是基于Spring AOP和Servlet过滤器的安全框架。它提供全面的安全性解决方案,同时在Web 请求级和方法调用级处理身份确认和授权。在 Spring Framework 基础上,Spring Security 充分利用了依赖注入(DI,Dependency Injection)和面向切面编程(AOP)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作。它是一个轻量级的安全框架,它确保基于Spring的应用程序提供身份验证和授权支持。它与Spring MVC有很好地集成,并配备了流行的安全算法实现捆绑在一起。安全主要包括两个操作“认证”与“验证”(有时候也会叫做权限控制)。“认证”是为用户建立一个其声明的角色的过程,这个角色可以一个用户、一个设备或者一个系统。“验证”指的是一个用户在你的应用中能够执行某个操作。在到达授权判断之前,角色已经在身份认证过程中建立了。*
我们简单来理解一下上面这段话:
第一:什么是Spring Security ?
Spring Security是一个安全框架。
第二:Spring Security核心功能?
(1)认证(你是谁,用户/设备/系统)
(2)验证(你能干什么,也叫权限控制/授权,允许执行的操作)
(3)攻击防护(防止伪造身份)
第三:Spring Security原理技术
Filter、Servlet、Spring DI、SpringAOP

首先我们要创造一个springboot项目

Spring Security Spring Security
Spring Security
Spring Security

项目创建成功后在pom.xml 中添加thymeleaf 依赖

<dependency>   <groupId>org.thymeleaf</groupId>   <artifactId>thymeleaf-spring5</artifactId> </dependency>  <dependency>    <groupId>org.thymeleaf.extras</groupId>    <artifactId>thymeleaf-extras-java8time</artifactId> </dependency> 

然后添加登录页面和主页面和需要通过权限访问的页面,
Spring Security
index.html

首页

<div class="ui segment" id="index-header-nav" th:fragment="nav-menu">     <div class="ui secondary menu">         <a class="item"  th:href="@{/index}">首页</a>          <!--登录注销-->         <div class="right menu">             <!--如果未登录-->             <div sec:authorize="!isAuthenticated()">                 <a class="item" th:href="@{/toLogin}">                     <i class="address card icon"></i> 登录                 </a>             </div>              <!--如果以登录:用户名,注销-->             <div sec:authorize="isAuthenticated()">                 <a class="item">                     用户名:<span sec:authentication="name"></span>                  <!--   角色:<span sec:authentication="principal.getAuthorities()"></span>-->                 </a>             </div>             <div sec:authorize="isAuthenticated()">                 <a class="item" th:href="@{/logout}">                     <i class="sign-out icon"></i> 注销                 </a>             </div>           </div>     </div> </div>  <div class="ui segment" style="text-align: center">     <h3>Spring Security Study by 阿杰</h3> </div>  <div>     <br>     <div class="ui three column stackable grid" >         <!--更据用户的角色动态的实现-->         <div class="column" sec:authorize="hasRole('vip1')">             <div class="ui raised segment">                 <div class="ui">                     <div class="content">                         <h5 class="content">Level 1</h5>                         <hr>                         <div><a th:href="@{/level1/1}"><i class="bullhorn icon"></i> Level-1-1</a></div>                         <div><a th:href="@{/level1/2}"><i class="bullhorn icon"></i> Level-1-2</a></div>                         <div><a th:href="@{/level1/3}"><i class="bullhorn icon"></i> Level-1-3</a></div>                     </div>                 </div>             </div>         </div>          <div class="column" sec:authorize="hasRole('vip2')">             <div class="ui raised segment">                 <div class="ui">                     <div class="content">                         <h5 class="content">Level 2</h5>                         <hr>                         <div><a th:href="@{/level2/1}"><i class="bullhorn icon"></i> Level-2-1</a></div>                         <div><a th:href="@{/level2/2}"><i class="bullhorn icon"></i> Level-2-2</a></div>                         <div><a th:href="@{/level2/3}"><i class="bullhorn icon"></i> Level-2-3</a></div>                     </div>                 </div>             </div>         </div>          <div class="column" sec:authorize="hasRole('vip3')">             <div class="ui raised segment">                 <div class="ui">                     <div class="content">                         <h5 class="content">Level 3</h5>                         <hr>                         <div><a th:href="@{/level3/1}"><i class="bullhorn icon"></i> Level-3-1</a></div>                         <div><a th:href="@{/level3/2}"><i class="bullhorn icon"></i> Level-3-2</a></div>                         <div><a th:href="@{/level3/3}"><i class="bullhorn icon"></i> Level-3-3</a></div>                     </div>                 </div>             </div>         </div>      </div> </div> 

login.html

登录

<div class="ui segment">      <div style="text-align: center">         <h1 class="header">登录</h1>     </div>      <div class="ui placeholder segment">         <div class="ui column very relaxed stackable grid">             <div class="column">                 <div class="ui form">                     <form th:action="@{/login}" method="post">                         <div class="field">                             <label>Username</label>                             <div class="ui left icon input">                                 <input type="text" placeholder="Username" name="user">                                 <i class="user icon"></i>                             </div>                         </div>                         <div class="field">                             <label>Password</label>                             <div class="ui left icon input">                                 <input type="password" name="pass">                                 <i class="lock icon"></i>                             </div>                         </div>                         <div class="field">                             <input type="checkbox" name="remember"> 记住我                         </div>                         <input type="submit" class="ui blue submit button"/>                     </form>                 </div>             </div>         </div>     </div>      <div style="text-align: center">         <div class="ui label">             </i>注册         </div>         <br><br>         <small>blog.kuangstudy.com</small>     </div>     <div class="ui segment" style="text-align: center">         <h3>Spring Security Study by 秦疆</h3>     </div> </div> 

level1 1.html

<!DOCTYPE html>  <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head>     <meta charset="UTF-8">     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">     <title>首页</title>     <!--semantic-ui-->     <link href="https://cdn.bootcss.com/semantic-ui/2.4.1/semantic.min.css"      rel="stylesheet">     <link th:href="@{/qinjiang/css/qinstyle.css}" rel="stylesheet">      </head>  <body>  <!--主容器-->  <div class="ui container">      <div th:replace="~{index::nav-menu}"></div>      <div class="ui segment" style="text-align: center">         <h3>Level-1-1</h3>     </div>  </div>   <script th:src="@{/qinjiang/js/jquery-3.1.1.min.js}"></script> <script th:src="@{/qinjiang/js/semantic.min.js}"></script>  </body> </html> 

level1 2.html

	<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head>     <meta charset="UTF-8">     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">     <title>首页</title>     <!--semantic-ui-->     <link href="https://cdn.bootcss.com/semantic-ui/2.4.1/semantic.min.css" rel="stylesheet">     <link th:href="@{/qinjiang/css/qinstyle.css}" rel="stylesheet"> </head> <body>  <!--主容器--> <div class="ui container">     <div th:replace="~{index::nav-menu}"></div>     <div class="ui segment" style="text-align: center">         <h3>Level-1-2</h3>     </div> </div> <script th:src="@{/qinjiang/js/jquery-3.1.1.min.js}"></script> <script th:src="@{/qinjiang/js/semantic.min.js}"></script>  </body> </html> 

其他页面都是这样,改变一下h3标签里面的信息就行了,就是用来做测试而已
控制器添加我们访问页面的路劲

@RequestMapping({"/","/index"}) public String index(){     return "index"; }  @RequestMapping("toLogin") public String toLogin(){     return "views/login"; }  @RequestMapping("/level1/{id}") public String level1(@PathVariable("id") int id){     return "views/level1/"+id; }  @RequestMapping("/level2/{id}") public String level2(@PathVariable("id") int id){     return "views/level2/"+id; }  @RequestMapping("/level3/{id}") public String level3(@PathVariable("id") int id){     return "views/level3/"+id; } 

并在我们的properties中配置一个关闭缓存的功能
spring.thymeleaf.cache=false
thymeleaf是一个模板引擎,缓存的意思是加载一次模板之后便不会在加载了,对于生产环境应该加上缓存,但是在开发过程中如果打开缓存,不方便开发人员调试。试想一下,改一行html,就需要重启服务器,肯定是不方便的。总结一下:本地开发环境下,需要把缓存关闭,否则调试成本太大。其他环境下缓存都需要打开。
然后我们添加我们的security依赖

<dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-security</artifactId>     <version>2.2.1.RELEASE</version> </dependency> 

搭配好上面的环境,我们就开始配置类,先创建一个config包用来装我们的配置,
然后创建一个类 SecurityConfig ,让他继承WebSecurityConfigurerAdapter(适配器)
//链式编程

   @Override    protected void configure(HttpSecurity http) throws Exception {     //首页所有人可以访问,功能页只有对应有权限的人才能访问员     //请求授权的规则      http.authorizeRequests()             .antMatchers("/").permitAll()             .antMatchers("/level1/**").hasRole("vip1")             .antMatchers("/level2/**").hasRole("vip2")             .antMatchers("/level3/**").hasRole("vip3"); 		 	//没有权限默认回到登录页面,需要开启登录的页面 	http.formLogin();  }  @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception {     //这些数据正常应该从数据库中读     auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())             .withUser("ajie").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3")             .and()             .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3"); } 

认证完成后
然后在configure(HttpSecurity http)在添加注销功能
//注销,开启了注销功能
http.logout();

然后在页面写一个注销按钮,给一个默认的logout路径。
跳到首页
http.logout().logoutSuccessUrl("/");

完成登录注销后,我们去调整一下我们的页面,我们登录成功时应该显示注销按钮,没有登录的时候就显示我们的登录按钮,怎么才能做到这种效果呢,我们先在pom.xml中添加thymeleaf整合security的依赖

		<dependency> 		    <groupId>org.thymeleaf.extras</groupId> 		    <artifactId>thymeleaf-extras-springsecurity4</artifactId> 		    <version>3.0.4.RELEASE</version> 		</dependency> 

然后在页面使用我们的thymeleaf整合security,通过它来判断我们什么时候该显示什么,

<div sec:authorize="!isAuthenticated()">     <a class="item" th:href="@{/toLogin}">         <i class="address card icon"></i> 登录     </a> </div>  <!--如果以登录:用户名,注销--> <div sec:authorize="isAuthenticated()">     <a class="item">         用户名:<span sec:authentication="name"></span>      <!--   角色:<span sec:authentication="principal.getAuthorities()"></span>-->     </a> </div> <div sec:authorize="isAuthenticated()">     <a class="item" th:href="@{/logout}">         <i class="sign-out icon"></i> 注销     </a> </div> 

如果上面的用户名显示不出来,那我们可以把我的springboot的版本降低成 : 2.0.9.RELEASE

修改之后我们的数据就能正常显示了,然后我们点击注销,再次登录,我们就会发现报错,然后我们需要在我们配置类权限添加一下代码
http.csrf().disable();

版权声明:玥玥 发表于 2021-05-10 10:05:37。
转载请注明:Spring Security | 女黑客导航