SpringBoot快速整合SpringSecurity,新手都会的详细步骤

Posted IT学习小镇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot快速整合SpringSecurity,新手都会的详细步骤相关的知识,希望对你有一定的参考价值。

一、什么是SpringSecurity?

Spring Security是一个基于Spring框架的安全性框架,提供了一组轻量级的API和工具,用于实现身份验证、授权、防止攻击等常见的安全性功能。它支持各种身份验证方式,例如基本身份验证、表单身份验证、OAuth2.0和OpenID Connect等。Spring Security还提供了许多可配置选项,允许开发人员根据应用程序的需求进行定制。Spring Security已经成为了Java企业级应用程序中使用最广泛的安全框架之一。

二、SpringSecurity的原理

Spring Security的核心原理是基于过滤器链(Filter Chain)来保护应用程序资源。在这个过滤器链中,不同的过滤器负责不同的安全功能,例如身份验证、授权、攻击防御等。

当一个请求到达应用程序时,它首先会被最外层的过滤器拦截。这个过滤器将请求传递给下一个过滤器,并继续执行一些前置处理(例如日志记录、跨域请求处理等)。接下来,在过滤器链中的每个过滤器都会进行自己的处理,直到请求被最内层的过滤器处理完毕并返回响应。

Spring Security通过配置过滤器链来保护应用程序资源。每个过滤器都有不同的职责,例如:

(1)AuthenticationFilter:身份验证过滤器,用于对用户进行身份验证。
(2)AuthorizationFilter:授权过滤器,用于检查用户是否有权限访问某个资源。
(3)CsrfFilter:防止跨站点请求伪造(CSRF)过滤器,用于防止CSRF攻击。
(4)ExceptionTranslationFilter:异常转换过滤器,用于处理安全相关的异常。
(5)SessionManagementFilter:会话管理过滤器,用于管理用户的会话。

开发人员可以基于Spring Security提供的API和工具,定制自己的安全性策略,并将它们添加到过滤器链中。这样,当应用程序收到请求时,它就会遵循这些安全性策略来保护应用程序资源。

三、SpringBoot整合SpringSecurity

  1. 添加依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
  1. 配置Spring Security
# 设置默认用户
spring.security.user.name=user
spring.security.user.password=pass

# 关闭CSRF保护
spring.security.csrf.enabled=false
  1. 编写安全性配置类。编写一个安全性配置类来配置Spring Security。这个类应该扩展WebSecurityConfigurerAdapter并覆盖一些方法来配置安全性。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter 
    
    // 配置用户信息
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception 
        auth.inMemoryAuthentication()
            .withUser("user").password("nooppass").roles("USER");
    
    
    // 配置HTTP请求安全性
    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.authorizeRequests()
            .antMatchers("/public/**").permitAll() // 允许/public/**路径下的所有请求
            .anyRequest().authenticated() // 所有其他请求都需要身份验证
            .and()
            .formLogin() // 启用表单登录
            .loginPage("/login") // 指定登录页面
            .defaultSuccessUrl("/", true) // 登录成功后重定向到主页
            .permitAll() // 允许所有用户访问登录页面
            .and()
            .logout() // 启用注销
            .logoutUrl("/logout") // 注销URL
            .logoutSuccessUrl("/login") // 注销成功后重定向到登录页面
            .permitAll(); // 允许所有用户注销
    

在上面的配置中,我们配置了一个内存身份验证(使用用户名和密码)和HTTP请求安全性(允许某些路径下的请求,要求所有其他请求都需要身份验证,并开启表单登录和注销)。

  1. 编写控制器。最后,您需要编写一个控制器来处理登录和注销请求。
@Controller
public class LoginController 
    
    // 处理登录请求
    @GetMapping("/login")
    public String login() 
        return "login";
    
    
    // 处理注销请求
    @PostMapping("/logout")
    public String logout() 
        return "redirect:/login?logout=true";
    

在上面的代码中,我们定义了一个login()方法来处理登录页面请求,并返回一个名为login的模板。logout()方法用于处理注销请求,并重定向到登录页面。

  1. 写html模板。最后,我们需要编写一个名为login.html的模板来呈现登录页面。
<!DOCTYPE html>
<html>
<head>
    <title>Login</title>
</head>
<body>
    <h1>Login</h1>
    <form action="/login" method="post">
        <div>
            <label for="username">Username:</label>
            <input type="text" id="username" name="username" required autofocus />
        </

springBoot快速开发+配置使用+整合mvcjunitdtuidmybatisredis

一、SpringBoot简介

1. 原有Spring优缺点分析

1.1 Spring的优点分析

Spring是Java企业版(Java Enterprise Edition,JEE,也称J2EE)的轻量级代替品。无需开发重量级的Enterprise JavaBean(EJB),Spring为企业级Java开发提供了一种相对简单的方法,通过依赖注入和面向切面编程,用简单的Java对象(Plain Old Java Object,POJO)实现了EJB的功能。

1.2 Spring的缺点分析

虽然Spring的组件代码是轻量级的,但它的配置却是重量级的。一开始,Spring用XML配置,而且是很多XML配置。Spring 2.5引入了基于注解的组件扫描,这消除了大量针对应用程序自身组件的显式XML配置。Spring 3.0引入了基于Java的配置,这是一种类型安全的可重构配置方式,可以代替XML。

所有这些配置都代表了开发时的损耗。因为在思考Spring特性配置和解决业务问题之间需要进行思维切换,所以编写配置挤占了编写应用程序逻辑的时间。和所有框架一样,Spring实用,但与此同时它要求的回报也不少。

除此之外,项目的依赖管理也是一件耗时耗力的事情。在环境搭建时,需要分析要导入哪些库的坐标,而且还需要分析导入与之有依赖关系的其他库的坐标,一旦选错了依赖的版本,随之而来的不兼容问题就会严重阻碍项目的开发进度。

2. SpringBoot的概述

2.1 SpringBoot解决上述Spring的缺点

SpringBoot对上述Spring的缺点进行的改善和优化,基于约定优于配置的思想,可以让开发人员不必在配置与逻辑业务之间进行思维的切换,全身心的投入到逻辑业务的代码编写中,从而大大提高了开发的效率,一定程度上缩短了项目周期。

2.2 SpringBoot的特点

  • 为基于Spring的开发提供更快的入门体验
  • 开箱即用,没有代码生成,也无需XML配置。同时也可以修改默认值来满足特定的需求
  • 提供了一些大型项目中常见的非功能性特性,如嵌入式服务器、安全、指标,健康检测、外部配置等
  • SpringBoot不是对Spring功能上的增强,而是提供了一种快速使用Spring的方式

2.3 SpringBoot的核心功能

  • 起步依赖

    起步依赖本质上是一个Maven项目对象模型(Project Object Model,POM),定义了对其他库的传递依赖,这些东西加在一起即支持某项功能。

    简单的说,起步依赖就是将具备某种功能的坐标打包到一起,并提供一些默认的功能。

  • 自动配置

    Spring Boot的自动配置是一个运行时(更准确地说,是应用程序启动时)的过程,考虑了众多因素,才决定Spring配置应该用哪个,不该用哪个。该过程是Spring自动完成的。

二、开发快速入门

1. Spring Initializr方式

spring官网 Spring Initializr

1.点击上述地址,直接来到springboot官网的工程创建页面
2.根据官网提示,配置坐标依赖等等。
3.等待工程下载,直接使用idea工具打开即可
4.在启动类同级或者自己目录下创建controller
5.运行启动类即可
6.浏览器访问测试

image-20210612155538795

下载完成解压后,直接在idea打开,然后在Controller层编写如下代码

@RestController
public class DemoController {

    @RequestMapping("/demo")
    public String demo(){

        return "hello springBoot";
    }
}

运行启动类即可

image-20210612160523630

访问/demo

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7KWy4HEj-1624425855541)(C:\\Users\\16096\\AppData\\Roaming\\Typora\\typora-user-images\\image-20210612160612819.png)]

注意:我们创建的所有的包必须是启动类的同级或者子级。

2. idea(Spring Initializr)

1.根据idea工具中提供的Spring Initializr,根据步骤提示创建,和官网差不多
2.编写controller
3.运行启动类
4.浏览器测试
image-20210612161500180

同上创建Controller层编写代码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KE2gmsTa-1624425855544)(C:\\Users\\16096\\AppData\\Roaming\\Typora\\typora-user-images\\image-20210612163443679.png)]

运行启动类,访问/demo

3. idea手动方式(推荐)

1.创建普通maven工程
2.引入springBoot父工程
3.引入springBoot的web启动依赖
4.编写controller
5.编写启动类,执行启动类

pom.xml

引入springBoot父工程
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0.RELEASE</version>
 </parent>

引入springBoot的web启动依赖
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

同上创建Controller层编写代码

编写启动类,执行启动类

package com.ahcfl.springBoot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootStart {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootStart.class,args);
    }
}

话外(工程的启动方式)

1、 启动类

2、springBoot插件

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
image-20210612164929642

3、 java -jar jar包名成来执行

1.引入上述的插件
2.通过maven命令打成jar包
3.来到工作磁盘的工程目录的target中,cmd
4.通过  java -jar  jar包名成来执行

注意:
正常开发环境,都是启动类直接启动
生产环境,一般都是打jar包启动
   注意:打jar包一定要引入springboot的插件,否则打成的jar包无法执行。

三、springBoot配置

1. 父工程依赖版本管理

回忆maven中的父工程的作用:统一管理依赖和插件的版本

引入springBoot父工程:鼠标 Ctrl+左击 点进去
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.0.RELEASE</version>
</parent>

发现其又继承父工程:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.3.11.RELEASE</version>
</parent>
<artifactId>spring-boot-starter-parent</artifactId>
<packaging>pom</packaging>
<name>spring-boot-starter-parent</name>

继续点进去,可看到依赖版本的声明:

 <properties>
    <activemq.version>5.15.15</activemq.version>
    <antlr2.version>2.7.7</antlr2.version>
    <appengine-sdk.version>1.9.88</appengine-sdk.version>
    <artemis.version>2.12.0</artemis.version>
    <aspectj.version>1.9.6</aspectj.version>
    <assertj.version>3.16.1</assertj.version>
    <atomikos.version>4.0.6</atomikos.version>
    <awaitility.version>4.0.3</awaitility.version>
    <bitronix.version>2.1.4</bitronix.version>
    <build-helper-maven-plugin.version>3.1.0</build-helper-maven-plugin.version>
     ...............
     ...............
</properties> 

springBoot的父工程中声明了很多依赖的版本,已经帮我们避免了依赖冲突的情况。

所以我们声明依赖时,只需要填写坐标,不需要依赖版本

例如:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
starter-web真实引入了我们web开发所需要的基本依赖。

image-20210612171108882

对于springBoot工程来说:
1.引入springBoot父工程,来声明依赖的版本
2.引入web工程需要的starter-web,引入依赖和相关的自动化配置类
3.引入springBoot工程的打包插件,用于后期的打包。
4.编写启动类,即可执行

2. 配置文件的分类

1.springBoot的配置有几种?
2.如果同时存在的会怎样?

配置文件的作用:

修改SpringBoot自动配置的默认值;SpringBoot在底层都给我们自动配置好;
SpringBoot官方讲解:约定 优于 配置 优于 编码

通过spring-boot-starter-parent依赖发现:

<resource>
    <directory>${basedir}/src/main/resources</directory>
    <filtering>true</filtering>
    <includes>
        <include>**/application*.yml</include>
        <include>**/application*.yaml</include>
        <include>**/application*.properties</include>
    </includes>
</resource>

springBoot的配置分为yaml和properties:

基于上面开发入门代码演示:

1、在resources目录下新建 application.properties 配置文件,

添加端口号: 启动项目端口修改为 8088

server.port=8088
componey1=ahcfl

2、添加 application.yml配置文件

启动项目端口修改为 8090

server:
  port: 8090
componey2: cfl

3、修改controller,依赖注入读取配置信息:

package com.ahcfl.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

    @Value("${componey1}")
    private String componey1;
    @Value("${componey2}")
    private String componey2;

    @RequestMapping("/demo")
    public String demo(){
        return "hello springBoot--->"+componey1+" , "+componey2;
    }
}

启动,查看控制台启动日志:

image-20210612172559156

因此,浏览器访问 127.0.0.1/8088/demo

hello springBoot--->ahcfl , cfl

结论:

1. 约定 优于 配置 优于 编码两类配置文件如果同时存在,

2. 若 key 相同则 properties 优先级高,若key不同则合并

3. YAML配置文件基本使用

YAML 是 “YAML Ain’t Markup Language”的递归缩写 ,(YAML 不是一种标记语言)

SpringBoot默认读取的配置文件名称可以是application.properties或者application.yml,

其中application.yml采用一种完全不同与properties的语法风格。

基本语法:

1.大小写敏感
2.数据值前边必须有空格,作为分隔符
3.使用缩进表示层级关系
4.缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
5. # 表示注释,从这个字符一直到行尾,都会被解析器忽略。

properties加载的优先级高于 yaml文件,避免冲突,可以将applicaiton.properties文件注掉或删掉

yml文件配置:

# 缩进表示层级
jdbc:
  username: root
  password: 123

# 对象(map集合)
person:
  name: zhangsan
# 或者行内写法
person1: {name: lisi}

# 数组或者集合
address:
  - beijing
  - shanghai

# 纯量,不可分割
msg1: 'hello \\n world' # 单引号忽略转义字符
msg2: "hello \\n world" # 双引号,识别转义字符

# 参数引用
name: ahcfl
person2: ${name} # 引用上面定义的参数值
package com.ahcfl.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController
@RequestMapping("/yaml")
public class YamlBasicController {
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    //获取对象的值或者map的值
    @Value("${person.name}")
    private String name1;
    @Value("${person1.name}")
    private String name2;

    //获取数组的值
    @Value("${address[0]}")
    private String address1;

    //获取纯量:
    @Value("${msg1}")
    private String msg1;
    @Value("${msg1}")
    private String msg2;

    //参数引用
    @Value("${person2}")
    private String name3;

    @RequestMapping("/demo")
    public String demo(){
        System.out.println("数据库连接参数:"+username+":"+password);
        System.out.println("map或者对象值:"+name1+":"+name2);
        System.out.println("数组的值:"+address1);
        System.out.println("纯量值:msg1:"+msg1);
        System.out.println("纯量值:msg2:"+msg2);
        System.out.println("参数引用:"+name3);

        return "yaml基本使用";
    }
}

4. YAML配置文件自动装配到实体对象

1.编写yaml配置信息
2.定义实体类JdbcConfig和Person
3.给实体添加注解进行配置文件的读取
4.编写controller,依赖注入测试

yml文件配置:

# 对象(map集合)
person:
  name: ahcfl
  age: 20
  address:
    - beijing
    - shanghai
  jdbc:
    username: root
    password: 123
  daughter:
    name: jingtian
    age: 18
package com.ahcfl.pojo;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@ConfigurationProperties(prefix = "jdbc" ) //自动解析yaml前缀为jdbc的配置,并且自动进行依赖注入
@Component
public class JdbcConfig {
    private String username; // root 
    private String password; // 123
}
package com.ahcfl.pojo;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Map;

@Data
@ConfigurationProperties(prefix = "person")
@Component
public class Person {
    private String name;  // ahcfl
    private int age;      // 20
    private String[] address;
    private JdbcConfig jdbc;
    private Map<String,Object> daughter;  // jingtian:18
}

第二种配置方式:

@ConfigurationProperties(prefix=“xxx”)+@EnableConfigurationProperties(xxx.class)

此时就不需要在pojop配置类上加@Component,

给启动类添加注解@EnableConfigurationProperties(xxx.class)

package com.ahcfl.controller;

import com.ahcfl.pojo.JdbcConfig;
import com.ahcfl.pojo.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/yaml")
public class YamlSuperController {

    @Autowired
    private JdbcConfig jdbcConfig;

    @Autowired
    private Person person;

    @RequestMapping("/demo2")
    public String demo(){
        System.out.println("jdbc配置:"+jdbcConfig);
        System.out.println("人员信息:"+person);
        return "demo2";
    }
}

5. YAML配置文件之配置文件自动提示

image-20210612175029900

在springBoot的classpath中找不到该注解。在pom添加依赖配置:

<!--解决SpringBoot自定义配置提示问题-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-configuration-processor</artifactId>
  <optional>true</optional>
</dependency>

6. 配置文件切换

实际企业开发中,开发环境和生产环境连接的数据库是不同的,
所以我们需要不同的配置进行相互之间的切换。

步骤:
1.创建3个配置文件
	application.yml
	application-dev.yml
	application-prod.yml
2.dev和prod配置内容不一致	
3.application.yml中通过 spring.profiles.active=dev/prod 来激活指定配置

application-dev.yml

# 开发环境

# 对象(map集合)
person:
  name: zhangsan
  age: 20
  address:
    - beijing
    - shanghai
  jdbc:
    username: root
    password: 123
  daughter:
    name: lisi
    age: 18

application-prod.yml

# 对象(map集合)
person:
  name: zhangsan
  age: 20
  address:
    - beijing
    - shanghai
  jdbc:
    username: ahcfl
    password: 123
  daughter:
    name: lisi
    age: 18

application.yml中通过 spring.profiles.active=dev/prod 来激活指定配置

spring:
  profiles:
    active: dev

7. 项目内部配置文件的加载顺序

查看官网,可以看出给了17种方式的配置加载形式

按照官网说明,添加配置实现

优先级:由高到底

  • file:./config/:当前项目下的/config目录下
  • file:./ :当前项目的根目录
  • classpath:/config/:classpath的/config目录
  • classpath:/ :classpath的根目录

8. 项目外部配置(了解)

1.保证工程中一个application.yaml配置,打成jar包
2.命令行执行jar包,修改端口配置,访问项目
3.在e盘中创建application.yaml配置,通过jar命令指定配置执行jar包
4.再次运行,查看结果

image-20210612184529324

2.命令行执行jar包,修改端口配置,访问项目

java -jar app.jar --server.port=9000

浏览器访问:http://localhost:9000/demo

显示 classpath_zhangsan

3.在e盘中创建application.yaml配置,通过jar命令指定配置执行jar包

jdbc.username=classpath_lisi<

以上是关于SpringBoot快速整合SpringSecurity,新手都会的详细步骤的主要内容,如果未能解决你的问题,请参考以下文章

springBoot快速开发+配置使用+整合mvcjunitdtuidmybatisredis

SpringBoot整合Swagger-ui快速生成在线API文档

SpringBoot整合mybatis快速入门

SpringBoot学习—— springboot快速整合RabbitMQ

SpringBoot学习—— springboot快速整合Redis

SpringBoot学习—— springboot快速整合Redis