后端进阶之路——综述Spring Security认证,授权(一)

2023-11-01

前言

在这里插入图片描述
「作者主页」雪碧有白泡泡
「个人网站」雪碧的个人网站
「推荐专栏」

java一站式服务
前端炫酷代码分享
uniapp-从构建到提升
从0到英雄,vue成神之路
解决算法,一个专栏就够了
架构咱们从0说
数据流通的精妙之道
后端进阶之路

请添加图片描述

文章目录


以下是在每个标题前添加#符号后的文本:

✍1. 引言

✌ 背景介绍:网络安全的重要性

网络安全的重要性无法被低估。随着我们越来越依赖互联网和数字技术,网络安全问题变得愈发严峻。以下是网络安全的几个重要方面:

  1. 防止数据泄露:网络安全确保我们的个人信息、敏感数据和商业机密不会落入未授权的人手中。这包括银行账户信息、社交媒体账号、医疗记录等。

  2. 防范黑客攻击:黑客可以通过各种方式入侵网络系统,窃取信息、破坏系统或勒索金钱。网络安全措施有助于防止这些攻击,并保护我们的计算机、移动设备和网络连接。

  3. 维护企业安全:对于企业而言,网络安全至关重要。保护公司的数据和机密信息,防止竞争对手或恶意行为者获取敏感信息,确保业务的连续性和声誉。

  4. 保护个人隐私:在数字时代,我们的个人隐私面临威胁。网络安全可以帮助我们保护个人身份和隐私,避免成为身份盗窃、网络欺诈或网络骚扰的受害者。

  5. 防止网络犯罪:网络安全对于打击网络犯罪至关重要。网络犯罪包括电信诈骗、网络钓鱼、恶意软件传播等。通过加强网络安全,可以降低这些犯罪行为的发生率,并维护社会的安全和秩序。

✌ Spring Security简介:什么是Spring Security,它的作用和优势

Spring Security是一个用于在Java应用程序中实现身份验证和授权的框架。它对应用程序进行保护,以防止未经授权的访问,并确保只有经过身份验证的用户可以执行特定操作。

Spring Security的主要作用是提供全面的安全性解决方案,包括用户认证、授权、会话管理和密码加密等功能。它可以轻松集成到Spring应用程序中,并通过配置和自定义来满足各种安全需求。

以下是Spring Security的几个优点:

  1. 统一的安全管控:Spring Security提供了一套完善的安全管理框架,使得开发者可以方便地集中管理应用程序的安全性,而无需重复编写安全相关的代码。

  2. 灵活的身份验证和授权机制:Spring Security支持多种身份验证方式,如基于表单的身份验证、HTTP Basic和Digest身份验证、LDAP身份验证等。它还提供了细粒度的授权机制,可以通过注解或配置的方式定义权限规则。

  3. 安全性扩展性:Spring Security具有良好的扩展性,可以与其他框架和技术无缝集成,例如Spring框架、OAuth、OpenID等。这使得开发人员可以根据项目需求选择合适的安全性解决方案。

  4. 内置防护措施:Spring Security提供了对常见安全威胁的内置防护机制,如跨站点请求伪造(CSRF)保护、点击劫持保护、会话管理等。这些功能可以有效地提高应用程序的安全性。

在这里插入图片描述

✍2. Spring Security基本概念

Spring Security是一个基于Java的身份验证和访问控制框架,用于保护Web应用程序和服务。它提供了一套功能强大的安全性特性,帮助开发人员在应用程序中实现各种身份验证和授权方案。

在这里插入图片描述

✌认证(Authentication):验证用户身份

认证是确认用户身份的过程。当用户尝试登录系统时,Spring Security会验证用户提供的凭据是否有效,并根据验证结果构建一个代表用户身份的对象,称为Authentication对象。

代码演示

当使用Spring Security进行身份验证时,可以通过以下代码片段来理解认证过程:

1. 创建一个自定义的 UserDetailsService 实现来加载用户信息:
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("User not found with username: " + username);
        }
        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
                getAuthorities(user.getRoles()));
    }

    private Collection<? extends GrantedAuthority> getAuthorities(Set<Role> roles) {
        return roles.stream()
                .map(role -> new SimpleGrantedAuthority(role.getName()))
                .collect(Collectors.toList());
    }
}
2. 配置 Spring Security 来使用上述的 UserDetailsService 实现:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    // 密码加密器
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/admin/**").hasRole("ADMIN")
                .antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
                .anyRequest().authenticated()
                .and()
                .formLogin().permitAll()
                .and()
                .logout().permitAll();
    }
}
3. 在控制器中处理登录请求:
@Controller
public class LoginController {

    @GetMapping("/login")
    public String login() {
        return "login";
    }

    @GetMapping("/")
    public String home() {
        return "home";
    }
}

在这里插入图片描述

以上代码演示了一个基本的Spring
Security身份验证过程。当用户尝试访问受保护的资源时,会被重定向到登录页面(/login)。用户输入用户名和密码后,Spring
Security将通过 UserDetailsService 加载用户信息,并使用提供的凭据进行验证。如果验证成功,将创建一个
Authentication 对象表示用户身份,并允许用户访问受保护的资源。

✌授权(Authorization):授予用户访问权限

授权是确定用户是否有权限执行某个操作或访问某个资源的过程。Spring Security提供了丰富的授权机制,包括基于角色(Role)和权限(Permission)的授权方式。

代码演示

当涉及到授权时,Spring Security提供了几种常见的授权方式。下面是一些代码片段来帮助理解这些授权机制。

1. 基于角色(Role)的授权:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
            .anyRequest().authenticated()
            .and()
            .formLogin();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user").password("{noop}password").roles("USER")
            .and()
            .withUser("admin").password("{noop}password").roles("ADMIN");
    }
}

在上面的示例中,我们使用了基于角色的授权方式。通过hasRole()hasAnyRole()方法,我们可以指定哪些角色有访问权限。在configureGlobal()方法中,我们使用了一个简单的内存身份验证,其中包含了具有不同角色的两个用户。

2. 基于权限(Permission)的授权:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/admin/**").hasAuthority("ADMIN")
            .antMatchers("/user/**").hasAnyAuthority("USER", "ADMIN")
            .anyRequest().authenticated()
            .and()
            .formLogin();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user").password("{noop}password").authorities("USER")
            .and()
            .withUser("admin").password("{noop}password").authorities("ADMIN");
    }
}

在上面的示例中,我们使用了基于权限的授权方式。通过hasAuthority()hasAnyAuthority()方法,我们可以指定哪些权限有访问权限。在configureGlobal()方法中,我们使用了相同的内存身份验证,但是这次我们分配了不同的权限。

✌安全上下文(Security Context):保存已认证的用户信息

用户详情(User Details):用户详情是Spring Security中表示用户信息的接口,通常由开发人员实现以提供自定义用户信息。它包含用户的用户名、密码、角色等属性。

代码演示

以下是自定义用户详情(User Details)并在安全上下文(Security Context)中保存已认证的用户信息。

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;

public class CustomUserDetails implements UserDetails {
    private String username;
    private String password;
    private Collection<? extends GrantedAuthority> authorities;

    public CustomUserDetails(String username, String password, Collection<? extends GrantedAuthority> authorities) {
        this.username = username;
        this.password = password;
        this.authorities = authorities;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    // 下面的方法可以根据实际需求进行实现

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

在上述代码中,CustomUserDetails 类实现了 UserDetails
接口,并提供了必要的方法来获取用户名、密码和用户角色等属性。这个类是开发人员自定义的用户详情实现。

一旦你在认证过程中验证了用户的凭据,你可以创建 CustomUserDetails 实例,并将其放入安全上下文中:
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

public class AuthenticationService {
    public void authenticateUser(String username, String password) {
        // 通过验证用户名和密码

        // 创建用户详情
        UserDetails userDetails = new CustomUserDetails(username, password, authorities);

        // 创建认证对象
        Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, password, authorities);

        // 将认证对象放入安全上下文
        SecurityContextHolder.getContext().setAuthentication(authentication);
    }
}

在上述代码中,authenticateUser 方法创建了一个 CustomUserDetails 实例,并使用该实例创建了一个
UsernamePasswordAuthenticationToken
对象。然后,它将认证对象放入安全上下文中,以便后续可以访问已认证的用户信息。

✌过滤器链(Filter Chain):处理请求的过程

过滤器链(Filter Chain):过滤器链是Spring Security的核心组件之一,负责处理请求的安全性。它由多个过滤器组成,每个过滤器负责执行特定的安全操作,例如身份验证、授权检查等。

下面是一个基本的Spring Security过滤器链配置

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/public/**").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .and()
            .logout();
    }
}

在上面的示例中,SecurityConfig类继承了WebSecurityConfigurerAdapter,这是一个方便的基类,用于配置Spring
Security。

configure()方法用于配置HttpSecurity对象,它定义了过滤器链的行为。在该示例中,过滤器链执行以下操作:

  1. authorizeRequests():配置请求授权规则。
  2. .antMatchers("/public/**").permitAll():允许所有用户访问以/public/开头的URL。
  3. .anyRequest().authenticated():对于其他所有请求,要求用户进行身份验证。
  4. .formLogin():启用基于表单的身份验证。
  5. .logout():启用退出功能。

✍小结

Spring Security是一个功能强大的Java框架,用于在应用程序中实现认证(Authentication)和授权(Authorization)功能。它提供了一套细粒度的安全性控制机制,帮助保护应用程序免受恶意攻击和未经授权的访问。
在这里插入图片描述
下一篇我们会详细讲述Spring Security配置问题

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

后端进阶之路——综述Spring Security认证,授权(一) 的相关文章

  • 使用 Ant 将非代码资源添加到 jar 文件

    我正在将 java 应用程序打包成 jar 文件 我正在使用 ant 和 eclipse 我实际上需要在 jar 中直接在根文件夹下包含几个单独的非代码文件 xml 和 txt 文件 而不是与代码位于同一位置 我正在尝试使用includes
  • 使用 GWT 读取非常大的本地 XML 文件

    我正在使用 GWT 构建我的第一个 Java 应用程序 它必须从一个非常大的 XML 文件中读取数据 当我尝试发送对文件中信息的请求时遇到问题 并且我不太确定它是否与文件的大小或我的语义有关 在我的程序中 我有以下内容 static fin
  • Spring RestTemplate 使用 cookie 遵循重定向

    最近我遇到了一个问题 我需要做一个GET请求远程服务 我假设使用一个简单的 servlet 并且 RestTemplate 返回Too many redirects 经过一番调查 似乎对指定远程服务发出的第一个请求实际上只是一个 302 重
  • 使用 JUnit 时,有没有办法验证测试方法中是否调用了 try/catch 指令的 Catch 部分?

    例如 如果我想测试以下课程 public class SomeClass public void someMethod try Some code where comething could go wrong catch Exception
  • ConcurrentHashMap 内部是如何工作的?

    我正在阅读有关 Java 并发性的 Oracle 官方文档 我想知道Collection由返回 public static
  • 是否可以通过编程方式查找 logback 日志文件?

    自动附加日志文件以支持电子邮件会很有用 我可以以编程方式设置路径 如以编程方式设置 Logback Appender 路径 https stackoverflow com questions 3803184 setting logback
  • 如何检测 Java 字符串中的 unicode 字符?

    假设我有一个包含 的字符串 我如何找到所有这些 un icode 字符 我应该测试他们的代码吗 我该怎么做呢 例如 给定字符串 A X 我想将其转换为 AYXY 我想对其他 unicode 字符做同样的事情 并且我不想将它们存储在某种翻译映
  • 从 GitHub 上托管的 Spring Cloud Config Server 访问存储库的身份验证问题

    我在 GitHub 上的存储库中托管配置 如果我将回购公开 一切都好 但如果我将其设为私有 我将面临 org eclipse jgit errors TransportException https github com my user m
  • @Autowire注释的问题(空)

    我在验证器类中自动连接的两个服务有问题 这些服务工作正常 因为在我的控制器中是自动连接的 我有一个 applicationContext xml 文件和 MyApp servlet xml 文件 我的基础包是 es unican meteo
  • 读取电子邮件的文本文件转换为 Javamail MimeMessage

    我有一个电子邮件原始来源的文本文件 直接从 gmail 复制 如果您单击 查看原始文件 您就会看到它 我想读入该文件并将其转换为 MimeMessage 如果您好奇为什么 我设置了 JavaMaildir 并且需要用电子邮件填充它的收件箱以
  • 流中的非终结符 forEach() ?

    有时 在处理 Java Stream 时 我发现自己需要一个非终端 forEach 来触发副作用但不终止处理 我怀疑我可以用 map item gt f item 之类的方法来做到这一点 其中方法 f 执行副作用并将项目返回到流中 但这似乎
  • 在 SWT/JFace RCP 应用程序中填充巨大的表

    您将如何在 SWT 表中显示大量行 巨大是指超过 20K 行 20 列的东西 不要问我为什么需要展示那么多数据 这不是重点 关键是如何让它尽可能快地工作 这样最终用户就不会厌倦等待 每行显示某个对象的实例 列是其属性 一些 我想使用 JFa
  • QuerySyntaxException:无法找到类

    我正在使用 hql 生成 JunctionManagementListDto 类的实际 Java 对象 但我最终在控制台上出现以下异常 org hibernate hql internal ast QuerySyntaxException
  • JMenu 中的文本居中

    好吧 我一直在网上寻找有关此问题的帮助 但我尝试的任何方法似乎都不起作用 我想让所有菜单文本都集中在菜单按钮上 当我使用setHorizontalTextPosition JMenu CENTER 没有变化 事实上 无论我使用什么常量 菜单
  • Spring-ws:如何从没有“Request”元素的 xsd 创建 Wsdl

    尝试为客户端实现 SOAP Web 服务 我需要一个 wsdl 文件来通过soapUI 测试该服务 但正如您在下面看到的 这个 xsd 没有 Request 和 Response 方法 所有请求和响应都被定义为基本 ServiceProvi
  • Java Swing:需要一个高质量的带有复选框的开发 JTree

    我一直在寻找一个 Tree 实现 其中包含复选框 其中 当您选择一个节点时 树中的所有后继节点都会被自动选择 当您取消选择一个节点时 树中其所有后继节点都会自动取消选择 当已经选择了父节点 并且从其后继之一中删除了选择时 节点颜色将发生变化
  • Android:无法发送http post

    我一直在绞尽脑汁试图弄清楚如何在 Android 中发送 post 方法 这就是我的代码的样子 public class HomeActivity extends Activity implements OnClickListener pr
  • 使用按钮作为列表的渲染器

    我想使用一个更复杂的渲染器 其中包含列表的多个组件 更准确地说 类似于this https stackoverflow com questions 10840498 java swing 1 6 textinput like firefox
  • Java中HashMap和ArrayList的区别?

    在爪哇 ArrayList and HashMap被用作集合 但我不明白我们应该在哪些情况下使用ArrayList以及使用时间HashMap 他们两者之间的主要区别是什么 您具体询问的是 ArrayList 和 HashMap 但我认为要完
  • 将 Apache Camel 执行器指标发送到 Prometheus

    我正在尝试转发 添加 Actuator Camel 指标 actuator camelroutes 将交换 交易数量等指标 发送到 Prometheus Actuator 端点 有没有办法让我配置 Camel 将这些指标添加到 Promet

随机推荐

  • Windows上提示 api-ms-win-core-path-l1-1-0.dll 丢失怎么办?

    Windows上提示 api ms win core path l1 1 0 dll 丢失怎么办 最近有用户在开启电脑的photoshop软件使用的时候 出现另外无法启动软件的情况 因为系统中缺失了对应的dll文件 那么这个情况怎么去进行问
  • 电源学习总结(三)——线性稳压的参数

    前文提到了一些线性稳压的主要特点 本文作者将结合NXP智能车大赛实际案例 说一下电源设计容易踩的坑和线性稳压选型过程 文章目录 主要参数 输出电压 输入电压 热阻 基准电压 压降 最大电流 输入电容 纹波抑制 选型实例 主要参数 在为实际应
  • 二十八.刷题.18

    输入三个字符 可以重复 后 按各字符的ASCII码从小到大的顺序输出这三个字符 include
  • 解密 QQ 号-队列-c语言

    问题描述 分析 每次从最前面拿两个 第 1 个扔掉 第 2 个 放到尾部 需要一个数组来存储这一串数即 int q 101 并初始化这个数组即 int q 101 0 6 3 1 7 5 8 9 2 4 head 用来记录队列的队首 即第一
  • 动态规划-货币问题

    动态规划 货币问题 题目一 arr是货币数组 其中的值都是正数 再给定一个正数aim 每个值都认为是一张货币 即便是值相同的货币也认为每一张都是不同的 返回组成aim的方法数 例如 arr 1 1 1 aim 2 第0个和第1个能组成2 第
  • 机器学习 之线性回归(包含推导过程)

    参考B站视频新手狂喜 目前B站最全最清晰的 机器学习算法 教程 从零开始详细解读 原理 代码实现 通通都在这里了 收藏慢慢学 决策树 随机森林 聚类分析 人工智能 哔哩哔哩 bilibili 线性回归 eg 银行贷款 数据 工资和年龄 特征
  • C Primer Plus(第六版)

    1 开发一个包含你需要的预处理器定义的头文件 写一个 h的头文件 包含你此次练习的题目就可以了 注意防止头文件被重复引用导致的错误 需要用 ifndef或者 pragma once 下面题目需要的声明和结构都在对应题目中 方法1 使用 if
  • mysql使用查询结果作为临时表

    一 select查询作为临时表 select cou name from select count AS cou enabled AS name from user group by enabled as a where cou gt 0
  • 基于微信小程序的新冠疫苗预约系统

    末尾获取源码 开发语言 Java Java开发工具 JDK1 8 后端框架 SSM 前端 微信小程序 Vue 数据库 MySQL5 7和Navicat管理工具结合 服务器 Tomcat8 5 开发软件 IDEA Eclipse 是否Mave
  • ArrayList集合及常用方法的使用

    ArrayLise
  • Spring IOC容器初始化过程 源码分析

    本文主要记录Spring容器创建 源码分析过程 首先贴上一张时序图 好久没画 忘的差不多了 画的不好 可以凑合看一下 接下来 贴上一份测试代码 这里使用AnnotationConfigApplicationContext来初始化Spring
  • upload-labs(11~12)通关笔记

    环境准备 1 php版本 lt 5 3 4 2 magic quotes gpc Off php我用的是upload labs官方推荐的5 2 17 搭建平台用的是phpStudy2018 修改magic quotes gpc magic
  • Java实现邮件发送功能

    确定发件人邮箱和密码 某些邮箱服务器为了增加邮箱本身密码的安全性 给 SMTP 客户端设置了独立密码 有的邮箱称为 授权码 对于开启了独立密码的邮箱 这里的邮箱密码必需使用这个独立密码 授权码 确认发件人邮箱的 SMTP 服务器地址 发件人
  • python人工智能:模型关系(泉舟时代)

    1 授课 林德尧 泉舟时代 未来城市技术总监 2 主要文章内容 通常下 Flask SQLAlchemy 的行为就像一个来自 declarative 扩展配置正确的 declarative 基类 因此 我们强烈建议您阅读 SQLAlchem
  • 《机器学习》Chapter 5 神经网络笔记

    机器学习 Chapter 5 神经网络 1 神经元模型 神经元接收到来自n个其它神经元传递过来的输入信号 这些输入信号通过带权重的连接进行传递 神经元接收到的总输入值将与神经元的阈值进行比较 然后通过激活函数处理以产生神经元的输出 2 感知
  • 使用css去除input边框

  • 不同CUDA版本对应的最小GPU运算能力和最低兼容驱动

    The minimum compute capability for various CUDA versions CUDA Version Minimum Compute Capability Default Compute Capabil
  • 使用 Python 进行游戏脚本编程 [翻译]

    翻译自 GDC 2002 上 Bruce Dawson 的 Game Scripting in Python 简单介绍 Python 作为游戏脚本语言的优势 原文 Game Scripting in Python 作者 Bruce Daws
  • 机器学习的环境搭建流程

    一 需要 python解释器 pycharm anaconda 机器学习需要的第三方包 二 流程 1 先确定进行机器学习需要的主要包之间的依赖关系及对应的python版本 建议python版本不要太高 3 6或者3 7比较好 因为许多第三方
  • 后端进阶之路——综述Spring Security认证,授权(一)

    前言 作者主页 雪碧有白泡泡 个人网站 雪碧的个人网站 推荐专栏 java一站式服务 前端炫酷代码分享 uniapp 从构建到提升 从0到英雄 vue成神之路 解决算法 一个专栏就够了 架构咱们从0说 数据流通的精妙之道 后端进阶之路 文章