【Spring Security】打造安全无忧的Web应用--入门篇

🥳🥳Welcome Huihui's Code World ! !🥳🥳

接下来看看由辉辉所写的关于Spring Security的相关操作吧 

目录

🥳🥳Welcome Huihui's Code World ! !🥳🥳

一.Spring Security是什么

  1.概念

2.工作原理

二.为什么要用Spring Security

三.Spring Security怎么使用

0.创建项目

1.导入依赖

2.yml配置

3.获取security默认密码

4.Web安全配置类

5.controller

6.总体说明

①配置多用户角色访问

②配置相关页面及请求路径

③配置自定义登录

④配置安全退出

⑤配置自定义异常处理器

四.Spring Security中的常用方法

HttpSecurity介绍


一.Spring Security是什么

  1.概念

   `Spring Security`是一个基于`Spring`框架的安全性框架,可用于对Java应用程序进行身份验证、授权和其他安全性功能的添加。它不仅可以对Web应用程序进行保护,还可以保护非Web环境下的应用程序,如远程服务和命令行应用程序等。`Spring Security`提供了一系列可插拔的安全性特性,如基于标记的身份验证、权限控制、单点登录、密码加密等。它还支持多种安全性协议和标准,如`OAuth`、`SAML`、`OpenID`等,可与各种身份提供商集成。

2.工作原理

权限框架一般包含两大核心模块:认证(Authentication)和鉴权(Authorization)。

  • 认证:认证模块负责验证用户身份的合法性,生成认证令牌,并保存到服务端会话中(如TLS)。

  • 鉴权:鉴权模块负责从服务端会话内获取用户身份信息,与访问的资源进行权限比对。

核心组件介绍:

  • AuthenticationManager:管理身份验证,可以从多种身份验证方案中选择一种。

  • Authentication:用于验证用户的身份。

  • SecurityContextHolder:用于管理 SecurityContextThreadLocal,以便在整个请求上下文中进行访问,方便用户访问。

  • AccessDecisionManager:负责对访问受保护的资源的请求进行决策(即决定是否允许用户访问资源)

  • AccessDecisionVoter:是AccessDecisionManager的实现组件之一,它用于对用户请求的访问受保护的资源所需要的角色或权限进行投票。

  • ConfigAttribute:用于表示受保护资源或URL需要的访问权限,它可以理解为是访问控制策略的一部分

二.为什么要用Spring Security

        SpringBoot 没有发布之前,Shiro 应用更加广泛,因为 Shiro 是一个强大且易用的 Java 安全框架,能够非常清晰的处理身份验证、授权、管理会话以及密码加密。利用其易于理解的API,可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。但是 Shiro 只是一个框架而已,其中的内容需要自己的去构建,前后是自己的,中间是Shiro帮我们去搭建和配置好的。

  SpringBoot 发布后,随着其快速发展,Spring Security(前身叫做Acegi Security) 重新进入人们的视野。SpringBoot 解决了 Spring Security 各种复杂的配置,Spring Security 在我们进行用户认证以及授予权限的时候,通过各种各样的拦截器来控制权限的访问,从而实现安全,也就是说 Spring Security 除了不能脱离 SpringShiro 的功能它都有。

  • 在用户认证方面,Spring Security 框架支持主流的认证方式,包括 HTTP 基本认证、HTTP 表单验证、HTTP 摘要认证、OpenIDLDAP 等。

  • 在用户授权方面,Spring Security 提供了基于角色的访问控制和访问控制列表(Access Control List,ACL),可以对应用中的领域对象进行细粒度的控制。

  • Shiro在这个环境下实际已经不具备优势了。因为Spring这个生态链现在是太强大了。

总之就是,我们使用这个框架是用来帮助我们提高系统的安全性能的,假设我们没用这个框架来做安全认证,那么我们就需要手动编写很多的代码去完成权限的功能

三.Spring Security怎么使用

0.创建项目

这里依赖可以先选这三个,后面再pom中也可以自行添加(free marker等)

1.导入依赖

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








<!-- freemarker -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- web -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

spring-boot-starter-security包含了以下几个主要的依赖:

  • spring-security-coreSpring Security的核心模块,提供了基于权限的访问控制以及其他安全相关功能。

  • spring-security-config:提供了Spring Security的配置实现,例如通过Java配置创建安全策略和配置Token存储等。

  • spring-security-web:提供了Spring Security Web的基本功能,例如Servlet集成和通过HttpSecurity配置应用程序安全策略。

2.yml配置

spring:
  freemarker:
    # 设置freemarker模板后缀
    suffix: .ftl
    # 设置freemarker模板前缀
    template-loader-path: classpath:/templates/
    enabled: true
server:
  port: 8080

3.获取security默认密码

也可以自己在yml中先配置密码(因为今天使用模拟代码,没有连接数据库)

自己设置初始的默认的密码

spring:
  security:
    user:
      name: 自定义用户名
      password: 自定义密码

4.Web安全配置类

package com.wh.security.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

    @Bean
    public PasswordEncoder bcryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        //设置账户--admin--以及这个账户的角色
        UserDetails admin = User.withUsername("admin")
                .password(bcryptPasswordEncoder().encode("1234"))
                .roles("ADMIN", "USER").build();
        //设置账户--user--以及这个账户的角色
        UserDetails user = User.withUsername("user")
                .password(bcryptPasswordEncoder().encode("1234"))
                .roles("USER").build();
        return new InMemoryUserDetailsManager(admin, user);
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        //配置需要处理的url
        http.authorizeRequests()
                //antMatchers指可以配置多个url  permitAll使用这个方法代表其中的url都不需要进行认证
                .antMatchers("/toLogin").permitAll()
                //antMatchers指可以配置多个url  hasRolel使用这个方法代表其中的url需要是这个角色才可以访问
                .antMatchers("/admin/**").hasRole("ADMIN")
                //antMatchers指可以配置多个url  hasAnyRole使用这个方法代表其中的url只有指定了的那些角色才能访问
                .antMatchers("/user/**").hasAnyRole("ADMIN", "USER")
                //匹配任意`url`,其他的都需要认证
                .anyRequest().authenticated()
                //and表示后面继续追加条件
                .and()
                //**登录formLogin**的相关设置
                .formLogin()
                //登录进入的界面
                .loginPage("/toLogin")
                //设置登录请求的 URL,即表单提交的 URL
                .loginProcessingUrl("/userLogin")
                .successForwardUrl("/successLogin")
                //登录所需要传递的参数
                .usernameParameter("username")
                .passwordParameter("password")
                //and表示后面继续追加条件
                .and()
                //退出登录的相关配置
                .logout()
                //退出登录的url地址
                .logoutUrl("/logout")
                //成功退出登录之后进入的界面
                .logoutSuccessUrl("/");
        http.csrf().disable();
        //处理异常的界面(没有权限的时候所看到的界面)
        http.exceptionHandling().accessDeniedPage("/noAccess");
        return http.build();
    }

}

5.controller

package com.wh.security.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class UserController {

    @RequestMapping("/successLogin")
    public String successLogin() {
        return "default";
    }

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

    @RequestMapping("/userLogin")
    public String userLogin(String username, String password) {
        System.out.println("username=" + username + ",password=" + password);
        return "default";
    }

    @RequestMapping("/admin/toAddUser")
    public String toAddUser() {
        return "admin/addUser";
    }

    @RequestMapping("/admin/toListUser")
    public String toListUser() {
        return "admin/listUser";
    }

    @RequestMapping("/admin/toResetPwd")
    public String toResetPwd() {
        return "admin/resetPwd";
    }

    @RequestMapping("/admin/toUpdateUser")
    public String toUpdateUser() {
        return "admin/updateUser";
    }

    @RequestMapping("/user/toUpdatePwd")
    public String toUpdatePwd() {
        return "user/updatePwd";
    }

    @RequestMapping("/noAccess")
    public String noAccess() {
        return "accessDenied";
    }

}

6.总体说明

在我们没有使用web安全配置类之前,主要登录进去了,便可以访问所有的界面,但是当我们在安全配置类中配置了多用户角色访问之后,就只可以使用其中配置的用户(类比于数据库中的用户)进行登录了,我们还需要在其中配置相关页面及请求路径(登录的界面,登录的表单提交界面路径,登录成功之后进入的界面路径...),以及配置很重要的自定义异常处理器,配置了之后,当用户是没有权限去访问此页面时,就不会是纯粹的报错403等信息了,而是一个我们自定义的提示界面

配置多用户角色访问
@Bean
    public UserDetailsService userDetailsService() {
        //设置账户--admin--以及这个账户的角色
        UserDetails admin = User.withUsername("admin")
                .password(bcryptPasswordEncoder().encode("1234"))
                .roles("ADMIN", "USER").build();
        //设置账户--user--以及这个账户的角色
        UserDetails user = User.withUsername("user")
                .password(bcryptPasswordEncoder().encode("1234"))
                .roles("USER").build();
        return new InMemoryUserDetailsManager(admin, user);
    }

接下来的操作都需要在创建的SecurityConfig配置类中完成(规范)

②配置相关页面及请求路径

其中有不需要进行认证的页面,比如说登录,那么我们就可以在其中进行配置。还有一些界面是需要特定的身份才可以访问的界面

 //配置需要处理的url
        http.authorizeRequests()
                //antMatchers指可以配置多个url  permitAll使用这个方法代表其中的url都不需要进行认证
                .antMatchers("/toLogin").permitAll()
                //antMatchers指可以配置多个url  hasRolel使用这个方法代表其中的url需要是这个角色才可以访问
                .antMatchers("/admin/**").hasRole("ADMIN")
                //antMatchers指可以配置多个url  hasAnyRole使用这个方法代表其中的url只有指定了的那些角色才能访问
                .antMatchers("/user/**").hasAnyRole("ADMIN", "USER")
                //匹配任意`url`,其他的都需要认证
                .anyRequest().authenticated()
③配置自定义登录
.and()
                //**登录formLogin**的相关设置
                .formLogin()
                //登录进入的界面
                .loginPage("/toLogin")
                //设置登录请求的 URL,即表单提交的 URL
                .loginProcessingUrl("/userLogin")
                .successForwardUrl("/successLogin")
                //登录所需要传递的参数
                .usernameParameter("username")
                .passwordParameter("password")

默认的登录界面

④配置安全退出
//and表示后面继续追加条件
                .and()
                //退出登录的相关配置
                .logout()
                //退出登录的url地址
                .logoutUrl("/logout")
                //成功退出登录之后进入的界面
                .logoutSuccessUrl("/");
⑤配置自定义异常处理器
//处理异常的界面(没有权限的时候所看到的界面)
        http.exceptionHandling().accessDeniedPage("/noAccess");

四.Spring Security中的常用方法

HttpSecurity介绍

HttpSecuritySpring Security 的一个核心类,用于配置应用程序的安全策略。

HttpSecurity 类通常包含许多方法,可以用于配置以下内容:

  1. HTTP 请求的安全策略,例如访问控制、跨站点请求伪造 (CSRF) 防护等。

  2. HTTP 验证的安全策略,例如基于表单、HTTP 基本身份验证、OAuth 等。

  3. 访问受保护资源时所需的身份验证和授权方式。

方法说明
authorizeRequests()用于配置如何处理请求的授权,默认情况下所有的请求都需要进行认证和授权才能访问受保护的资源
formLogin()用于配置基于表单的身份验证,包括自定义登录页面、登录请求路径、用户名和密码的参数名称、登录成功和失败的跳转等。
httpBasic()用于配置基于HTTP Basic身份验证,包括定义使用的用户名和密码、realm名称等。
logout()用于配置退出登录功能,包括定义退出登录请求的URL、注销成功后的跳转URL、清除会话、删除Remember-Me令牌等。
csrf()用于配置跨站请求伪造保护,包括定义CSRF Token的名称、保存方式、忽略某些请求等。
sessionManagement()用于配置会话管理,包括定义并发控制、会话失效、禁用URL重定向、会话固定保护等。
rememberMe()用于配置Remember-Me功能,包括定义Remember-Me令牌的名称、有效期、加密方法、登录成功后的处理方式等。
exceptionHandling()用于配置自定义的异常处理,包括定义异常处理器和异常处理页面等。
headers()用于配置HTTP响应头信息,包括定义X-Content-Type-Options、X-XSS-Protection、Strict-Transport-Security等头信息。
cors()用于配置跨域资源共享,包括定义可访问的来源、Headers等。
addFilter()用于向当前HttpSecurity中添加自定义的Filter
and()用于在配置中添加另一个安全规则,并将两个规则合并。

匹配规则:

  • URL匹配

方法说明
requestMatchers()配置一个request Mather数组,参数为RequestMatcher对象,其match规则自定义,需要的时候放在最前面,对需要匹配的的规则进行自定义与过滤
authorizeRequests()URL权限配置
antMatchers()配置一个request Matherstring数组,参数为ant路径格式, 直接匹配url
anyRequest()匹配任意url,无参 ,最好放在最后面

  • 保护URL

方法说明
authenticated()保护Url,需要用户登录
permitAll()指定URL无需保护,一般应用与静态资源文件
hasRole(String role)限制单个角色访问
hasAnyRole(String… roles)允许多个角色访问
access(String attribute)该方法使用 SPEL, 所以可以创建复杂的限制
hasIpAddress(String ipaddressExpression)限制IP地址或子网

  • 登录formLogin

方法说明
loginPage()设置登录页面的 URL
defaultSuccessUrl()设置登录成功后的默认跳转页面
failuerHandler()登录失败之后的处理器
successHandler()登录成功之后的处理器
failuerUrl()登录失败之后系统转向的url,默认是this.loginPage + “?error”
loginProcessingUrl()设置登录请求的 URL,即表单提交的 URL
usernameParameter()设置登录表单中用户名字段的参数名,默认为 username
passwordParameter()设置登录表单中密码字段的参数名,默认为 password

  • 登出logout

方法说明
logoutUrl()登出url , 默认是/logoutl
logoutSuccessUrl()登出成功后跳转的 url 默认是/login?logout
logoutSuccessHandler()登出成功处理器,设置后会把logoutSuccessUrl 置为null

好啦,今天的分享就到这了,希望能够帮到你呢!😊😊   

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/259937.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FFmepeg——视频处理工具安装以及简单命令学习。

FFmpeg 是一个免费、开源且高度可定制的多媒体处理工具&#xff0c;它是一个强大的跨平台框架&#xff0c;用于处理音频、视频、多媒体流和图像。FFmpeg 的主要功能包括解码、编码、转码、流处理、多路复用、分离、合并、过滤等&#xff0c;支持多种音视频格式&#xff0c;包括…

研发管理-代码管理篇

前言&#xff1a; 工作了这些年&#xff0c;工作了三家公司&#xff0c;也用过主流的代码管理平台&#xff0c;比如SVN&#xff0c;git系列&#xff08;gitlib,gitee&#xff09;,各有优点&#xff0c;我个人比较喜欢SVN&#xff0c;多人协作的代码管理难免会有代码冲突&#…

【QT表格-6】QTableWidget的currentCellChanged实现中途撤销

背景&#xff1a; 【QT表格-1】QStandardItem的堆内存释放需要单独delete&#xff0c;还是随QStandardItemModel的remove或clear自动销毁&#xff1f;-CSDN博客 【QT表格-2】QTableWidget单元格结束编辑操作endEditting_qtablewidget 单元格编辑事件-CSDN博客 【QT表格-3】Q…

LLama Factory 安装部署实操记录(二)

1. 项目地址 GitHub - hiyouga/LLaMA-Factory: Easy-to-use LLM fine-tuning framework (LLaMA, BLOOM, Mistral, Baichuan, Qwen, ChatGLM)Easy-to-use LLM fine-tuning framework (LLaMA, BLOOM, Mistral, Baichuan, Qwen, ChatGLM) - GitHub - hiyouga/LLaMA-Factory: Easy…

hive命令启动出现classnotfound

环境&#xff1a;ambari集群三个节点node104、node105和node106&#xff0c;其中node105上有hiveserver2&#xff0c;并且三个节点均有HIVE CLIENT 注意&#xff1a;“./”指hive安装目录 其中装有hiveserver2的node105节点&#xff0c;由于某种需要向lib目录下上传了某些jar包…

无人机支持的空中无蜂窝大规模MIMO系统中上行链路分布式检测

无人机支持的空中无蜂窝大规模MIMO系统中上行链路分布式检测 无人机支持的空中无蜂窝大规模MIMO系统中上行链路分布式检测介绍题目一. 背景&#xff08;解决的问题&#xff09;二. 系统模型2.1 信道模型2.1.1 信道系数2.1.2 进行标准化 2.2 信道估计 和 数据传输2.2.1 信道估计…

环境搭建及源码运行_java环境搭建_idea版本下载及安装

1、介绍 Idea是一款被广泛使用的Java集成开发环境&#xff0c;它提供了丰富的功能和工具来帮助开发人员更高效地编写和调试代码。作为一款开源软件&#xff0c;Idea不仅提供了基本的代码编辑、自动完成和调试功能&#xff0c;还支持大量的插件和扩展&#xff0c;可为开发人员提…

将Abp默认事件总线改造为分布式事件总线

文章目录 原理创建分布式事件总线实现自动订阅和事件转发 使用启动Redis服务配置传递Abp默认事件传递自定义事件 项目地址 原理 本地事件总线是通过Ioc容器来实现的。 IEventBus接口定义了事件总线的基本功能&#xff0c;如注册事件、取消注册事件、触发事件等。 Abp.Events…

MySQL之表的约束

目录 前言 not null约束 default约束 同时设置not null约束和default约束 comment约束 zerofill约束 primary key约束&#xff08;又称主键约束&#xff09; 复合主键约束 auto_increment约束&#xff08;又称自增长约束&#xff09; unique约束&#xff08;又称唯一…

Redis分布式缓存-Redis持久化

RDB持久化 RDB全称Redis Database Backup file&#xff08;Redis数据备份文件&#xff09;&#xff0c;也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后&#xff0c;从磁盘读取快照文件&#xff0c;恢复数据。快照文件称为RDB文…

cpp_04_类_对象_this指针_常对象_常(成员)函数

1 类 1.1 类的定义 类的作用是抽象事物&#xff08;抽取事物特征&#xff09;的规则。 类的外化表现是用户自定义的复合数据类型&#xff08;包括成员变量、成员函数&#xff09;&#xff1a; 成员变量用于表达事物的属性&#xff0c;成员函数用于表达事物的行为。 类的表现…

力扣79. 单词搜索(java DFS解法)

Problem: 79. 单词搜索 文章目录 题目描述思路解题方法复杂度Code 题目描述 思路 该问题可以归纳为一类遍历二维矩阵的题目&#xff0c;此类中的一部分题目可以利用DFS来解决&#xff0c;具体到本题目&#xff08;该题目可以的写法大体不变可参看前面几个题目&#xff1a;&…

校园圈子交友系统,APP小程序H5,三端源码交付,支持二开!实名认证,大V认证,地图找伴,二手平台!

校园圈子交友系统&#xff0c;是属于自主定义开发的系统&#xff0c;内容有很多&#xff0c;先截取一些给大家看看&#xff0c;让大家更多的了解本系统&#xff0c;然后再做评价&#xff01; 校园后端下载地址&#xff1a;校园圈子系统小程序&#xff0c;校园拼车&#xff0c;校…

Netty Review - StringEncoder字符串编码器和StringDecoder 解码器的使用与源码解读

文章目录 概念概述StringEncoderStringDecoder Code源码分析StringEncoderStringDecoder 小结 概念 概述 Netty是一个高性能的网络应用程序框架&#xff0c;它提供了丰富的功能&#xff0c;包括编解码器&#xff0c;这些编解码器用于在网络中发送和接收数据时进行数据的编码和…

mac电脑安装虚拟机教程

1、准备一台虚拟机&#xff0c;安装CentOS7 常用的虚拟化软件有两种&#xff1a; VirtualBoxVMware 这里我们使用VirtualBox来安装虚拟机&#xff0c;下载地址&#xff1a;Downloads – Oracle VM VirtualBox 001 点击安装 002 报错&#xff1a;he installer has detected an…

uni-app 用于开发H5项目展示饼图,使用ucharts 饼图示例

先下载ucharts H5示例源码&#xff1a; uCharts: 高性能跨平台图表库&#xff0c;支持H5、APP、小程序&#xff08;微信小程序、支付宝小程序、钉钉小程序、百度小程序、头条小程序、QQ小程序、快手小程序、360小程序&#xff09;、Vue、Taro等更多支持canvas的框架平台&#…

在Windows系统平台下部署运行服务端Idea工程的jar服务

前言 目前云原生docker等技术&#xff0c;加上部署流水线大大的简化了各种流程&#xff0c;我们后端开发的人员只需要提交代码后&#xff0c;构建、部署、测试、发布等环节都无需人员接入&#xff0c;完全的自动化交付了。那么你肯定不禁想问&#xff0c;如题的需求不是点击一…

pyCharm 创建一个FastApi web项目,实现接口调用

FastApi和Django区别 我这边演示项目使用的fastApi作为web框架&#xff0c;当然主流一般都是使用Django做web框架&#xff0c;但是Django是一个重量级web框架他有很多组件&#xff0c;如授权&#xff0c;分流等全套web功能。我这边呢只需要有个接口可以被别人调用&#xff0c;…

python 绘制网格图/马赛克图

python 绘制网格图/马赛克图 文章目录 python 绘制网格图/马赛克图前言 前言 python绘制网格并在相应的坐标填充颜色 参考博客 def mplot_intf(t, data):plt.rcParams["figure.figsize"] (t, len(data))plt.rcParams["xtick.major.size"] 0plt.rcParams…

ios微信小程序table头部与左侧固定双重滚动会抖动的坑,解决思路

正常情况是左右滑动时&#xff0c;左侧固定不动&#xff0c;上下滑动时表头不动&#xff1b;而且需求不是完整页面滚动。而是单独这个表滚动&#xff1b; 第一个坑是他有一个ios自带的橡胶上下回弹效果。导致滚动时整个表都跟着回弹&#xff1b; 这个是很好解决。微信开发官网…