SpringSecurity

server/2024/9/25 8:47:18/

目录

认证授权概念

1.1 什么是认证

1.2 什么是授权

 权限数据类型

 常见的认证方式

一:Cookie-Session

二: jwt令牌无状态认证

 JWT

一.JWT简介

二.JWT组成

 三.JWT使用

1.导入jwt依赖

2.生成JWT令牌

3.JWT令牌校验

 四.JWT在前端保存方案

SpringSecurity

SpringSecurity简介

SpringSecurity基本使用

controller

一.导入依赖 

二.SpringSecurity自定义认证配置

 三.SpringSecurity自定义授权配置

 四.使用注解自定义授权

1.开启SpringSecurity注解支持

2.添加注解


认证授权概念

1.1 什么是认证

​ 在互联网中,我们每天都会使用到各种各样的APP和网站,在使用过程中通常还会遇到需要注册登录的情况,输入你的用户名和密码才能正常使用,也就是说成为这个应用的合法身份才可以访问应用的资源,这个过程就是认证。认证是为了保护系统的隐私数据与资源,用户的身份合法方可访问该系统的资源。

​ 当然认证的方式有很多,常见的账号密码登录,手机验证码登录,指纹登录,刷脸登录等等。

​ 简单说: 认证就是让系统知道我们是谁。

1.2 什么是授权

​ 认证是为了保护身份的合法性,授权则是为了更细粒度的对数据进行划分,授权是在认证通过的前提下发生的。控制不同的用户能够访问不同的资源。

**授权是用户认证通过后根据用户的权限来控制用户访问资源的过程**,拥有资源的访问权限则正常访问,没有权限则拒绝访问。

 权限数据类型

授权过程中,我们需要知道如何对用户访问的资源进行控制,需要了解一些简单的授权数据模型。

授权可以非常简单的理解成谁(Who)对什么资源(What)进行怎么样(How)的操作。

名词含义备注
Who主体(Subject)一般指用户,也可以是应用程序
What资源(Resource)例如商品信息,订单信息,页面按钮或程序中的接口等信息
How权限(Permission)规定了用户或程序对资源操作的许可。例如普通用户只能查看订单,管理员可修改或删除订单,这是因为普通用户和管理员用户对订单资源的操作权限不一样。

 常见的认证方式

一:Cookie-Session

​ 早期互联网以 web 为主,客户端是浏览器,所以 Cookie-Session 方式最那时候最常用的方式,直到现在,一些 web 网站依然用这种方式做认证;

认证过程大致如下:

A. 用户输入用户名、密码或者用短信验证码方式登录系统;

B. 服务端验证后,创建一个 Session 记录用户登录信息 ,并且将 SessionID 存到 cookie,响应回浏览器;

C. 下次客户端再发起请求,自动带上 cookie 信息,服务端通过 cookie 获取 Session 信息进行校验;

弊端

  • 只能在 web 场景下使用,如果是 APP 中,不能使用 cookie 的情况下就不能用了;
  • 即使能在 web 场景下使用,也要考虑跨域问题,因为 cookie 不能跨域;(域名或者ip一致,端口号一致,协议要一致)
  • cookie 存在 CSRF(跨站请求伪造)的风险;
  • 如果是分布式服务,需要考虑 Session 同步(同步)问题;
  • session-cookie机制是有状态的方式(后端保存主题的用户信息-浪费后端服务器内存)

二: jwt令牌无状态认证

JSON Web Token(JWT-字符串)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。

**认证过程: **

A. 依然是用户登录系统;

B. 服务端验证,并通过指定的算法生成令牌返回给客户端;

C. 客户端(浏览器)拿到返回的 Token,存储到 local storage(关闭浏览器后,token不会消失)/session Storate(关闭浏览器后,token会消失)/Cookie中;

D. 下次客户端再次发起请求,将 Token 附加到 header 中;

E. 服务端获取 header 中的 Token ,通过相同的算法对 Token 进行验证,如果验证结果相同,则说明这个请求是正常的,没有被篡改。这个过程可以完全不涉及到查询 Redis 或其他存储;

优点

A. 使用 json 作为数据传输,有广泛的通用型,并且体积小,便于传输;

B. 不需要在服务器端保存相关信息,节省内存资源的开销;

C. jwt 载荷部分可以存储业务相关的信息(非敏感的),例如用户信息、角色等;

 JWT

一.JWT简介

JSON Web Token(JWT)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。该token被设计为紧凑且安全的,特别适用于前后端无状态认证的场景。

二.JWT组成

  • 头部(Header)(非敏感)
    • 头部用于描述关于该JWT的最基本的信息,例如数据类型以及签名所用的算法等,本质是一个JSON格式对象;
    • 举例说明
      • {"typ":"JWT","alg":"HS256"} 解释:在头部指明了签名算法是HS256算法,整个JSON对象被BASE64编码形成JWT头部字符串信息;
      • BASE64编码详见:https://tool.oschina.net/encrypt,编码后的字符串:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
      • 值得注意的是BASE64不是加密算法,可进行正向编码和反向解码处理;
  • 载荷(playload)(非敏感数据)
    • 载荷就是存放有效信息的地方,该部分的信息是可以自定义的;
    • 载荷payload格式:{"sub":"1234567890","name":"John Doe","admin":true}
    • 载荷相关的JSON对象经过BASE64编码形成JWT第二部分:eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG7CoERvZSIsImFkbWluIjp0cnVlfQ==
  • 签证(signature)
    • jwt的第三部分是一个签证信息,这个签证信息由三部分组成:签名算法( header (base64后的).payload (base64后的) . secret )
    • 这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret秘钥组合加密,然后就构成了jwt的第三部分:TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

最后将这三部分用●连接成一个完整的字符串,构成了最终的jwt:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG7CoERvZSIsImFkbWluIjp0cnVlfQ==.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

 三.JWT使用

1.导入jwt依赖

<dependencies><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>
</dependencies>

2.生成JWT令牌

java">@Test
public void testGenerate(){String compact = Jwts.builder().setId(UUID.randomUUID().toString())//设置唯一标识.setSubject("JRZS") //设置主题.claim("name", "nineclock") //自定义信息.claim("age", 88) //自定义信息.setExpiration(new Date()) //设置过期时间.setIssuedAt(new Date()) //令牌签发时间.signWith(SignatureAlgorithm.HS256, "hhH")//签名算法, 秘钥.compact();System.out.println(compact);
}

3.JWT令牌校验

java">@Test
public void testVerify(){String jwt = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI5MzljNjU4MC0yMTQyLTRlOWEtYjcxOC0yNzlmNzRhODVmNDMiLCJzdWIiOiJOSU5FQ0xPQ0siLCJuYW1lIjoibmluZWNsb2NrIiwiYWdlIjo4OCwiaWF0IjoxNjE3MDMxMjUxfQ.J-4kjEgyn-Gkh0ZuivUCevrzDXt0K9bAyF76rn1BfUs";Claims claims = Jwts.parser().setSigningKey("hhh").parseClaimsJws(jwt).getBody();System.out.println(claims);
}

当我们对令牌进行任何部分(header , payload , signature)任何部分进行篡改, 都会造成令牌解析失败 ;

 四.JWT在前端保存方案

后端基于JWT生成的Token信息在前端有如下保存方式:

  • LocalStorage(浏览器关闭后,token不会消失)
  • SessionStorage(浏览器关闭后,token会消失)
  • cookie
  • 页面中
  • 其它

以LocalStorage为例:

javascript"><script>//保存信息localStorage.setItem("token", "xxx");//获取信息alert(localStorage.getItem("token"))//删除信息localStorage.removeItem("token");
</script>

SpringSecurity

SpringSecurity简介

  • Spring Security是基于Spring的安全框架,提供了包含认证和授权的落地方案;
  • Spring Security底层充分利用了Spring IOC和AOP功能,为企业应用系统提供了声明式安全访问控制解决方案;
  • SpringSecurity可在Web请求级别和方法调用级别处理身份认证和授权,为应用系统提供声明式的安全访问控制功能;

SpringSecurity基本使用

controller

java">@RestController
public class UserController {@GetMapping("/hello")public String hello(){return "hello security";}@GetMapping("/say")public String say(){return "say security";}@GetMapping("/register")public String register(){return "register security";}
}

一.导入依赖 

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

二.SpringSecurity自定义认证配置

声明配置类,定义用户名密码信息 

java">@Configuration
@EnableWebSecurity//开启web安全设置生效
public class SecurityConfig extends WebSecurityConfigurerAdapter {//使用该方法创建用户,并为用户赋予权限/*** 构建认证服务,并将对象注入spring IOC容器,用户登录时,会调用该服务进行用户合法信息认证*/@Beanprotected UserDetailsService userDetailsService() {//从内存获取用户认证信息的服务类(了解)后期用户的信息要从表中获取InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();//创建用户,这里自定义用户,以后通过数据库进行用户创建UserDetails u1= User.withUsername("hhh").password("{noop}123456")//{noop}-->表示no operation 就是直接明文比对.authorities("P1","ROLE_SELECT")//用户的权限信息.build();UserDetails u2=User.withUsername("aaa").password("{noop}123456").authorities("P2","ROLE_ADMIN").build();//构建用户inMemoryUserDetailsManager.createUser(u1);inMemoryUserDetailsManager.createUser(u2);return inMemoryUserDetailsManager;}
}

说明:

1.在userDetailsService()方法中 返回了一个UserDetailsService对象给spring容器管理,当用户发生登录认证行为时,Spring Security底层会自动调用UserDetailsService类型bean提供的用户信息进行合法比对,如果比对成功则资源放行,否则就认证失败;

2.当前暂时使用InMemoryUserDetailsManager实现类,后续我们也可手动实现UserDetailsService接口,做最大程度的自定义;

可以发现,在访问所有的资源时,必须进行认证才能访问 

 

 三.SpringSecurity自定义授权配置

给每个路径分配权限 ,访问某一个路径时,需要访问某一个路径时,需要进行用户认证,只有这个用户拥有访问这个路径的权限时,才能访问这个路径

permitAll()这个方法不用进行用户认证,可以直接访问

java">    @Overrideprotected void configure(HttpSecurity http) throws Exception {http.formLogin()//开启默认form表单登录方式.and().logout()//登出用默认的路径登出 /logout.permitAll()//允许所有的用户访问登录或者登出的路径.and().csrf().disable()//启用CSRF,防止CSRF攻击.authorizeRequests()//授权方法,该方法后有若干子方法进行不同的授权规则处理//允许所有账户都可访问(不登录即可访问),同时可指定多个路径.antMatchers("/register").permitAll()//允许所有的用户访问.antMatchers("/hello").hasAuthority("P1") //具有P5权限才可以访问.antMatchers("/say").hasRole("SELECT") //具有ROLE_ADMIN 角色才可以访问,会自动加上ROLE_.antMatchers("/aa","/bb").hasAnyAuthority("P1","ROLE_SELECT")//有任意一个权限都可以访问.antMatchers("/aa","/bb").hasAnyRole("SELECT","ADMIN)//有任意一个权限都可以访问.antMatchers("/aa","/bb").hasIpAddress("192.168.xxx.xxx")//必须是192.168.地址才能访问.antMatchers("/aa","/bb").denyAll()//任何用户都不可以访问.anyRequest().authenticated(); //除了上边配置的请求资源,其它资源都必须授权才能访问}

 四.使用注解自定义授权

1.开启SpringSecurity注解支持

 @EnableGlobalMethodSecurity(prePostEnabled = true)

java">@Configuration
@EnableWebSecurity//开启web安全设置生效
//开启SpringSecurity相关注解支持
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {}
2.添加注解
java">@RestController
public class UserController {//拥有ROLE_ADMIN权限的用户才能访问此接口@PreAuthorize("hasRole('ADMIN')")@GetMapping("/hello")public String hello(){return "hello security";}//拥有ROLE_SELECT权限的用户才能访问此接口@PreAuthorize("hasRole('SELECT')")@GetMapping("/say")public String say(){return "say security";}@PermitAll//任何用户都可以访问此接口,不需要进行认证@GetMapping("/register")public String register(){return "register security";}
}

 


http://www.ppmy.cn/server/121739.html

相关文章

CSS——网格布局(display: grid)之下篇

CSS——网格布局&#xff08;display: grid&#xff09;之下篇 前面我们介绍了网格布局的基础的创建以及一些比较基础的属性&#xff0c;下面我们将介绍网格布局的剩余部分&#xff0c;还将结合实例来进行细致的讲解&#xff08;图文并茂&#xff0c;生动形象有内涵&#xff0…

云栖实录 | 阿里云 OpenLake 解决方案重磅发布:多模态数据统一纳管、引擎平权联合计算、数据共享统一读写

新一轮人工智能浪潮正在重塑世界&#xff0c;以生成式 AI 为代表的技术快速应用&#xff0c;推动了数据与智能的深化融合&#xff0c;同时也给数据基础设施带来了全新的变革与挑战。面向 AI 时代的数据基础设施如何构建&#xff1f;底层数据平台架构在 AI 时代如何演进&#xf…

DAY80服务攻防-中间件安全HW2023-WPS 分析WeblogicJettyJenkinsCVE

知识点 1、中间件-Jetty-CVE&信息泄漏 2、中间件-Jenkins-CVE&RCE执行 3、中间件-Weblogic-CVE&反序列化&RCE 4、应用WPS-HW2023-RCE&复现&上线CS 中间件-Jetty-CVE&信息泄漏 Jetty是一个开源的servlet容器&#xff0c;它为基于Java的Web容器…

技术成神之路:设计模式(十四)享元模式

介绍 享元模式&#xff08;Flyweight Pattern&#xff09;是一种结构性设计模式&#xff0c;旨在通过共享对象来有效地支持大量细粒度的对象。 1.定义 享元模式通过将对象状态分为内部状态&#xff08;可以共享&#xff09;和外部状态&#xff08;不可共享&#xff09;&#xf…

网站建设中常见的网站后台开发语言有哪几种,各自优缺点都是什么?

市场上常见的网站后台开发语言有PHP、Python、JavaScript、Ruby、Java和.NET等。这些语言各有其独特的优缺点&#xff0c;适用于不同的开发场景和需求。以下是对这些语言的具体介绍&#xff1a; PHP 优点&#xff1a;PHP是一种广泛用于Web开发的动态脚本语言&#xff0c;特别适…

linux安装solr

Solr Downloads - Apache Solr 直接下载&#xff1a;https://dlcdn.apache.org/solr/solr/9.7.0/solr-9.7.0.tgz 这个包依赖jdk11以上版本 需要jdk1.8版本的&#xff0c;下载Index of /dist/lucene/solr/7.1.0 # 解压 tar -zxvf solr-9.7.0.tgz # 进入启动目录 cd solr-9.7…

【算法】递归

【ps】本篇有 5 道 leetcode OJ。 目录 一、算法简介 二、相关例题 1&#xff09;汉诺塔问题 .1- 题目解析 .2- 代码编写 2&#xff09;合并两个有序链表 .1- 题目解析 .2- 代码编写 3&#xff09;反转链表 .1- 题目解析 .2- 代码编写 4&#xff09;两两交换链表中…

JVM的基本组成

一、JDK\JRE\JVM JDK: 全称 "Java Development Kit" &#xff0c;Java 开发工具包&#xff0c;提供 javac 编译器、jheap、jconsole 等监控工具;JRE: 全称"Java Runtime Environment"&#xff0c;Java 运行环境&#xff0c;提供Class Library 核心类库 JV…