微服务安全与权限-springSecurity

384 阅读3分钟

这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战

springSecurity

介绍

Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架。它实际上是保护基于spring的应用程序的标准。

Spring Security是一个框架,侧重于为Java应用程序提供身份验证和授权。与所有Spring项目一样,Spring安全性的真正强大之处在于它可以轻松地扩展以满足定制需求

功能

Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案。一般来说,Web 应用的安全性包括用户认证(Authentication)用户授权(Authorization) 两个部分。用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。

对于上面提到的两种应用情景,Spring Security 框架都有很好的支持。在用户认证方面,Spring Security 框架支持主流的认证方式,包括 HTTP 基本认证、HTTP 表单验证、HTTP 摘要认证、OpenID 和 LDAP 等。在用户授权方面,Spring Security 提供了基于角色的访问控制和访问控制列表(Access Control List,ACL) ,可以对应用中的领域对象进行细粒度的控制。

前提

1.创建项目,选择web和sql API , MySQL Driver

2.导入themyleaf模板

3.创建静态资源

4.编写controller

@org.springframework.stereotype.Controller
public class Controller {
​
   @RequestMapping({"/","/index"})
   public String index(){
       return "index";
  }
​
   @RequestMapping("/toLogin")
   public String tologin(){
       return "views/login";
  }
​
//   秒啊,根据id跳转对应的网页
   @RequestMapping("/level1/{id}")
   public String leavel1(@PathVariable("id") int id){
       return "views/level1/"+id;
  }
​
   @RequestMapping("/level2/{id}")
   public String leavel2(@PathVariable("id") int id){
       return "views/level2/"+id;
  }
​
   @RequestMapping("/level3/{id}")
   public String leavel3(@PathVariable("id") int id){
       return "views/level3/"+id;
  }
}

开始配置

引入spring-boot-starter-security模块

配置类

  • WebSecurityConfigurerAdapter 自定义Security策略
  • AuthenticationManagerBuilder 自定义认证策略
  • @EnableWebSercurity 开启WebSecurity模式

1.导包

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

2.创建配置类,继承WebSecurityConfigurerAdapter,添加@EnableWebSercurity注解

设置访问内容需要的权限

@EnableWebSecurity
public class SecurityConfig extends 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();
  }
}

3.运行 1588847000934.png 4.加入语句http.formLogin();没有权限就跳转到登录页 可以将security创建的登录页替换为自己编写的登录页

//             定制登录页 loginPage
       http.formLogin().loginPage("/toLogin");

5.用户认证权限

创建几个用户并给予权限

//   认证   springboot版本2.1.x以上可以能会报错 提示密码编码为null
//   添加密码编码.passwordEncoder
   @Override
   protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//       这些数据可以从数据库中读,也可以从内存中读,速度较快
       auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
        .withUser("YY").password(newBCryptPasswordEncoder().encode("123456")).roles("vip1")
              .and().withUser("YZY").password(newBCryptPasswordEncoder().encode("123456")).roles("vip2");
  }
}

6.登录“YY”账号(权限VIP1),选择vip2的网页,forbidden被禁止的

image.png

7.注销账号

注销源码

image.png 在formLogin后面加 http.logout();

8.想让拥有指定权限的用户不能看见其他权限的内容

首页

<!--如果未登录,显示登录按钮
                          认可:“没有登录” ,然后显示登录按钮-->
               <div sec:authorize="!isAuthenticated()">
                   <a class="item" th:href="@{/toLogin}">
                       <i class="address card icon"></i> 登录
                   </a>
               </div>
<!--               如果已登录,显示注销按钮和用户权限对应的n内容-->
               <div sec:authorize="isAuthenticated()">
​
                   <a class="item">
                      用户名: <div sec:authentication="name"></div>
                        权限 :<div sec:authentication="authorities"></div>
                   </a>
                   <a class="item" th:href="@{/logout}">
                       <i class="address card icon"></i> 注销
                   </a>
               </div><!--       信息根据权限显示-->
   <div sec:authorize="hasRole('vip2')" class="column"></div>
<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 sec:authorize="hasRole('vip3')" class="column"></div>

image.png