1、概览 使用 Spring Security 时,可能需要把日志级别设置得更高一些。例如,可能需要检查用户的角色或端点的安全配置。或者,可能还需要更多关于身份认证或授权的信息,例如查看为什么用户无法访问某个端点。
本文将带你了解如何修改 Spring Security 日志级别。
2、配置 Spring Security 日志 与其他 Spring 或 Java 应用一样,可以使用日志库,并为 Spring Security 模块定义日志级别。
通常,可以进行如下配置:
<logger name="org.springframework.security" level="DEBUG" /> 如果运行的是 Spring Boot 应用,则可以在 application.properties 文件中对此进行配置:
logging.level.org.springframework.security=DEBUG 同样,也可以使用 yaml:
logging: level: org: springframework: security: DEBUG 这样,就可以查看有关身份认证或 Filter Chain 的日志。此外,还可以使用 trace 级别进行更深入的 debug。
Spring Security 还能记录有关请求和应用的 Filter 的特定信息:
@EnableWebSecurity public class SecurityConfig { @Value("${spring.websecurity.debug:false}") boolean webSecurityDebug; @Bean public WebSecurityCustomizer webSecurityCustomizer() { return (web) -> web.debug(webSecurityDebug); } // .
1、概览 本文将带你了解如何使用 Spring OAuth2RestTemplate 进行 OAuth2 REST 调用。
创建一个 Spring Web 应用,用于列出 GitHub 账户下的所有仓库。
2、Maven 依赖 首先,需要在 pom.xml 中添加 spring-boot-starter-security 和 spring-security-oauth2-autoconfigure 依赖。由于构建的是 Web 应用,因此还需要包含 spring-boot-starter-web 和 spring-boot-starter-thymeleaf Starter。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.security.oauth.boot</groupId> <artifactId>spring-security-oauth2-autoconfigure</artifactId> <version>2.6.8</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> 3、OAuth2 Properties 接下来,在 application.properties 文件中添加 OAuth 配置,以连接到 GitHub 账户:
# 替换为你的 CLIENT_ID github.client.clientId=[CLIENT_ID] # 替换为你的 CLIENT_SECRET github.client.clientSecret=[CLIENT_SECRET] github.client.userAuthorizationUri=https://github.com/login/oauth/authorize github.client.accessTokenUri=https://github.com/login/oauth/access_token github.client.clientAuthenticationScheme=form github.resource.userInfoUri=https://api.github.com/user github.resource.repoUri=https://api.github.com/user/repos 注意,需要用 GitHub OAuth App 中的值替换 [CLIENT_ID] 和 [CLIENT_SECRET] 。你可以按照 创建 OAuth App 指南在 GitHub 上注册一个新的应用:
1、什么是 Spring Boot 自动配置 首先介绍一下什么是 Spring Boot,Spring Boost 是基于 Spring 框架开发出来的功能更强大的 Java 程序开发框架,其最主要的特点是:能使程序开发者快速搭建一套开发环境。Spring Boot 能将主流的开发框架(例如 SpringMVC、Dubbo、Mybatis、Redis 等),做到像 Maven 导入 Jar 包一样的简洁快速,做到开箱即用。其中最关键的技术就是 Spring Boot 定制的各种 Starter,通 Maven 引入 Starter 就能快速搭建开发环境。
2、SpringBoot Starter自动装配案例 在以前单独使用 SpringMVC Web 编程框架时,我们需要单独配置 DispatcherServlet 和 Tomcat,使用 Spring Boot 之后,我们只需要引入 spring-boot-Starter-web 就能直接开始编写 Controller 等 Web 相关的代码,这就是 Spring Boot 为们提供的开箱即用的便捷能力,下面就以 spring-boot-Starter-web 来说明 Spring Boot自动配置的关键原理。
3、SpringBoot 自动装配案例源码解析 3.1、DispatcherServlet 的自动配置原理 首先我们定位到 Spring Boot 自动配置的 Maven 依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> <version>${spring-boot.version}</version> </dependency> 在依赖的 Jar 包中我们可以在 META-INF/spring.
WebFlux 最为人所诟病的是数据库的支持问题,毕竟数据是一个应用的生命,我们接触的大部分应用程序都是有数据库的,而 WebFlux 在这一方面的支持行一直比较弱,这也是大家总是吐槽它的原因。
不过从 Spring 5 开始,这一问题得到了一定程度的缓解。
Spring 官方在 Spring5 发布了响应式 Web 框架 Spring WebFlux 之后急需能够满足异步响应的数据库交互 API,不过由于缺乏标准和驱动,Pivotal 团队开始自己研究响应式关系型数据库连接 Reactive Relational Database Connectivity,并提出了 R2DBC 规范 API 用来评估可行性并讨论数据库厂商是否有兴趣支持响应式的异步非阻塞驱动程序。最早只有 PostgreSQL 、H2、MSSQL 三家数据库厂商,不过现在 MySQL 也加入进来了,这是一个极大的利好。目前 R2DBC 的最新版本是 0.9.0.RELEASE。
本系列接下来的文章中将会和大家演示 R2DBC 的用法,但是今天我们还是先来看看 WebFlux + MongoDB 的用法,毕竟这是 WebFlux 较早支持的数据库之一,各种 API 都比较成熟,我们一步一步来。
1、项目创建 方便起见,我们这里就直接创建 Spring Boot 项目,首先创建一个 Spring Boot 项目,引入 MongoDB 依赖和 WebFlux 依赖,如下:
注意我们这里选择的 MongoDB 依赖是 Spring Data Reactive MongoDB,千万别选错了。
项目创建完成后,我们先在 application.properties 中对 MongoDB 进行简单配置,如下:
1. Overview Spring Security 提供了不同的身份认证系统,例如通过数据库和 UserDetailService。
有时可能不想使用 JPA 持久层,而是想使用 MongoDB Repository。本文将带你了解如何使用 Spring Security 和 MongoDB 对用户进行认证。
2、Spring Security 使用 MongoDB 进行认证 MongoDB Repository 与 JPA Repository 类似不过,我们需要设置不同的配置。
2.1、Maven 依赖 本文使用嵌入式 MongoDB。首先,添加 spring-boot-starter-data-mongodb 和 de.flapdoodle.embed.mongo 依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <dependency> <groupId>de.flapdoodle.embed</groupId> <artifactId>de.flapdoodle.embed.mongo</artifactId> <version>3.3.1</version> </dependency> 2.2、配置 创建配置类:
@Configuration public class MongoConfig { private static final String CONNECTION_STRING = "mongodb://%s:%d"; private static final String HOST = "localhost"; @Bean public MongoTemplate mongoTemplate() throws Exception { int randomPort = SocketUtils.
1、概览 在使用 Spring Data MongoDB 时,可能需要比默认级别(INFO)更高的日志,以查看执行语句或查询参数等一些附加信息。
2、配置 MongoDB 查询日志 Spring Data MongoDB 通过 MongoOperations 接口或其主要的实现 MongoTemplate 来访问数据,因此只需为 MongoTemplate 类配置调 Debug 级别的日志即可。
与其他 Spring 或 Java 应用一样,可以使用日志库并为 MongoTemplate 定义日志级别。类似于如下:
<logger name="org.springframework.data.mongodb.core.MongoTemplate" level="DEBUG" /> 如果是 Spring Boot 应用,可以直接在 application.properties 文件中进行配置:
logging.level.org.springframework.data.mongodb.core.MongoTemplate=DEBUG 同样,也可以使用 YAML 文件:
logging: level: org: springframework: data: mongodb: core: MongoTemplate: DEBUG 3、日志测试类 创建一个 Book 类:
@Document(collection = "book") public class Book { @MongoId private ObjectId id; private String bookName; private String authorName; // getter 和 setter 方法 } 创建一个简单的测试类用于测试,并查看输出日志。
1、概览 本文将带你了解 Spring 6.1 中新添加的 JdbcClient 接口,它提供了 Fluent 风格的 API,统一了 JdbcTemplate 和 NamedParameterJdbcTemplate 的 Facade,支持链式操作。
有了 JdbcClient 后就可以使用 Fluent 风格的 API 定义查询、设置参数以及执行数据库操作了。
该功能简化了 JDBC 操作,使其更易读、更易懂。然而,对于 JDBC 批处理操作和存储过程的调用,仍然需要使用 JdbcTemplate 和 NamedParameterJdbcTemplate 类。
本文使用 H2 数据库来演示 JdbcClient 的功能。
2、数据库设置 创建 student 表:
CREATE TABLE student ( student_id INT AUTO_INCREMENT PRIMARY KEY, student_name VARCHAR(255) NOT NULL, age INT, grade INT NOT NULL, gender VARCHAR(10) NOT NULL, state VARCHAR(100) NOT NULL ); -- Student 1 INSERT INTO student (student_name, age, grade, gender, state) VALUES ('John Smith', 18, 3, 'Male', 'California'); -- Student 2 INSERT INTO student (student_name, age, grade, gender, state) VALUES ('Emily Johnson', 17, 2, 'Female', 'New York'); --More insert statements.
DataFieldMaxValueIncrementer 是 spring-jdbc 项目中的一个接口。用于在应用中生成连续、自增的序列。可用于 主键ID、订单号、流水号 等等。
它基于数据库实现,主要有 2 大子类。
AbstractSequenceMaxValueIncrementer:用于支持序列(SEQUENCE)的数据库(如 Oracle),使用标准的数据库序列。 AbstractColumnMaxValueIncrementer:用于不支持序列的数据库(如,MYSQL),使用一张表来模拟。 spring-jdbc 已经为当前流行的关系型数据库提供了具体的实现,类体系结构如下:
DataFieldMaxValueIncrementer |-AbstractDataFieldMaxValueIncrementer |-AbstractSequenceMaxValueIncrementer |-OracleSequenceMaxValueIncrementer # Oracle 数据库 |-PostgresSequenceMaxValueIncrementer # Postgres 数据库 |-SqlServerSequenceMaxValueIncrementer # SqlServer 数据库 |- ... # 还有一些其他的,这里忽略 |-AbstractColumnMaxValueIncrementer |-MySQLMaxValueIncrementer # MYSQL 数据库 DataFieldMaxValueIncrementer DataFieldMaxValueIncrementer 接口只有 3 个方法,很简单。
public interface DataFieldMaxValueIncrementer { int nextIntValue() throws DataAccessException; long nextLongValue() throws DataAccessException; String nextStringValue() throws DataAccessException; } nextIntValue:以 int 类型返回下一个序列。 nextLongValue:以 long 类型返回下一个序列。 nextStringValue:以 String 类型返回下一个序列。 使用 MySQLMaxValueIncrementer 本文以 MySQLMaxValueIncrementer 为例(毕竟 MYSQL 最流行)。
1、简介 本文将带你了解如何自定义从 JWT(JSON Web Token)Claim 到 Spring Security 权限(Authority)的映射。
2、背景 基于 Spring Security 的应用接收到请求时,它会经过一系列步骤,本质上旨在实现两个目标。
认证请求,以便应用知道谁在访问它 决定通过身份认证的请求是否可以执行相关操作 对于使用 JWT 的应用,授权方面包括:
从 JWT payload(通常是 scope 或 scp Claim)中提取 Claim 值 将这些 Claim 声明映射到一组 GrantedAuthority 对象中 一旦 Security 引擎设置了这些权限,它就可以评估是否有任何访问限制适用于当前请求,并决定是否可以继续处理。
3、默认的映射 在开箱即用的情况下,Spring 使用一种直接的策略将 Claim 声明转换为 GrantedAuthority 实例。首先,它会提取 scope 或 scp Claim,并将其拆分成一个字符串列表。接下来,它会为每个字符串创建一个新的 SimpleGrantedAuthority,使用前缀 SCOPE_,后跟 scope 值。
接下来,创建一个简单的端点来演示这个策略。看看 Authentication 实例有哪些关键属性。
@RestController @RequestMapping("/user") public class UserRestController { @GetMapping("/authorities") public Map<String,Object> getPrincipalInfo(JwtAuthenticationToken principal) { Collection<String> authorities = principal.getAuthorities() .
1. 问题 在浏览器中进行跨域请求一个接口时报错如下:
Access to XMLHttoRequest at ‘https://xxx.lzw.me/abc/getToken from origin “http://localhost:3001 has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: The ‘Acess-Control-Allow-Origin’ header contains multiple values ‘*, *”. but only one is allowed.
2. 原因 从报错信息上理解,是 Acess-Control-Allow-Origin 的值为 *, *,设置了多个。从 nginx 配置上查看设置的值是 *。以非跨域的方式请求该接口,则可以在 Response 中看到 header 信息中包含了两个 Acess-Control-Allow-Origin 的设置。那么原因就是在 nginx 之外的其它网关或应用程序中还设置了该 header 值。找到它并移除个性化的设置逻辑即可。
3. 解决方法 如果 nginx 出口网关的设置是多余的,CORS 在应用程序层已有管理,则可以直接移除此处的配置。
如果是应用程序内部针对该接口添加了设置,考虑到需支持允许所有接口跨域访问,应修改应用程序移除相关逻辑。
如果希望在 nginx 层作统一配置管理,也可在应用程序出口网关层作 header 过滤。例如针对 Spring zuul 网关的设置实例: