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. 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、简介 本文将带你了解如何自定义从 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、概览 本文通过一个示例来带你了解如何处理 Spring Security Resource Server 产生的 Spring Security 异常。
2、Spring Security Spring Security 是 Spring 的一个子项目。它试图将 Spring 项目中的所有用户访问控制功能进行整合。访问控制允许限制特定用户或角色在应用中可以执行的选项。
在本例中,我们重点关注 Exception Handler 的配置。Spring Security 提供了三种不同的接口来实现这一目的并控制产生的事件:
Authentication Success(认证成功)Handler Authentication Failure(认证失败)Handler Access Denied(拒绝访问)Handler 3、Security Configuration 首先,配置类必须创建一个 SecurityFilterChain Bean。它将负责管理应用的所有安全配置。因此,我们必须在这里引入 Handler。
定义所需的配置:
@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.csrf() .disable() .httpBasic() .disable() .authorizeRequests() .antMatchers("/login") .permitAll() .antMatchers("/customError") .permitAll() .antMatchers("/access-denied") .permitAll() .antMatchers("/secured") .hasRole("ADMIN") .anyRequest() .authenticated() .and() .formLogin() .failureHandler(authenticationFailureHandler()) .successHandler(authenticationSuccessHandler()) .and() .exceptionHandling() .accessDeniedHandler(accessDeniedHandler()) .and() .logout(); return http.
1、概览 Spring Security 有 2 个核心的组件:HttpSecurity 和 WebSecurity。
2、Spring Security Spring Security 是 Spring Framework 的扩展,是一个功能强大、高度可定制的安全框架。它为基于 Jakarta® EE 的企业软件应用提供全面的安全服务。它旨在处理身份验证、授权、防止常见安全漏洞等问题。
Spring Security 与两个重要组件 HttpSecurity 和 WebSecurity 紧密集成。
HttpSecurity 主要负责配置 HTTP 请求的安全,而 WebSecurity 则侧重于配置基于 Web 的安全。
Spring Security 的核心依赖于 AuthenticationManager、UserDetailsService 和 UserDetails 等基本组件。这些组件构成了 Spring Security 的基础。通过它们,我们可以实现身份认证、管理用户详情并有效定义访问控制。
3、HttpSecurity HttpSecurity 在配置 HTTP 请求的授权方面起到核心作用。它允许我们基于各种条件定义访问规则,包括 URL、HTTP 方法和用户角色,以确保对应用程序的不同部分进行安全访问。
链式方法调用是 HttpSecurity 的一个强大特性,它使我们能够流畅地表达安全配置。通过方法链,我们可以定义特定端点的安全行为,处理身份认证机制,并无缝设置自定义访问规则。这种方式让安全配置更加灵活和易于管理。
HttpSecurity 的一个关键特性是基于角色和权限进行访问配置。我们可以指定访问特定URL 所需的角色或权限。因此,我们可以对应用程序的安全性进行细粒度控制。
HttpSecurity 还可以实现平滑处理登录和注销功能。因此,我们可以配置自定义的登录页面、认证成功和失败的处理方式。它还允许我们实现自定义的注销行为,提升用户体验和安全性。
在使用 HttpSecurity 配置授权时,重要的是要解决安全问题。这些包括防止未经授权的访问、确保安全的身份认证机制、防止会话固定攻击,并防范常见的Web漏洞。
使用 HttpSecurity 来配置授权。
@Configuration @EnableWebSecurity public class HttpSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.
本文将会带你了解在 Spring Boot 中如何使用 Spring Security、JWT 和 MySQL 数据库实现基于 Token 的身份认证。
JWT (JSON Web Token)概览 JWT 是 JSON Web Token 的缩写,是一种安全地在各方之间传输信息的开放标准。它是一种紧凑、自包含的数据传输方法,通常用于客户端和服务器之间的数据传输。
JWT 通常用于认证和授权,服务器通过验证 JWT 中包含的数字签名来验证用户。
JWT 由三部分组成:Header、Payload 和 Signature(签名)。
Header 包含 Token 类型和 Token 签名算法的元数据。 Payload 包含关于被验证用户或实体的声明(Claim)或陈述。这些声明可包括用户 ID、用户名或电子邮件地址等信息。 Signature(签名)使用秘钥和 Header 及 Payload 生成,以确保 JWT 的完整性。 使用 JWT 的一个好处是它们是无状态的,这意味着服务器无需跟踪用户的身份认证状态。这可以提高可扩展性和性能。此外,JWT 可以在不同的域和服务中使用,只要它们共享相同的秘钥来验证签名即可。
Spring Security 概览 Spring Security 是一个提供身份认证、授权和防护常见攻击的框架。它为确保 Web 和响应式应用程序的安全提供一流的支持,是保护基于 Spring 的应用程序的事实标准。
Spring Security 用于保护 Web 应用程序、REST API 和微服务的安全,为身份认证和授权提供内置支持。
数据库表结构 添加 Maven 依赖 添加如下依赖到 Spring Boot 项目:
1、概览 本文将会带你了解如何使用 @ExceptionHandler 和 @ControllerAdvice 全局处理 Spring Security 异常。
Controller Advice 是一种拦截器,常用于处理全局异常。
2、Spring Security 异常 Spring Security 核心异常(如 AuthenticationException 和 AccessDeniedException)属于运行时异常。由于这些异常是由 DispatcherServlet 后面的 Authentication Filter 在调用 Controller 方法之前抛出的,因此 @ControllerAdvice 无法捕获这些异常。
通过添加自定义 Filter 和构建响应体,可以直接处理 Spring Security 异常。要通过@ExceptionHandler 和 @ControllerAdvice 在全局级别处理这些异常,需要自定义 AuthenticationEntryPoint 的实现。AuthenticationEntryPoint 用于发送 HTTP 响应,要求客户端提供凭证。虽然已经有多个内置实现,但是我们仍然需要自己实现,以发送自定义响应。
首先,让我们看看如何在不使用 @ExceptionHandler 的情况下全局处理 Security 异常。
3、不使用 @ExceptionHandler Spring Security 异常是从 AuthenticationEntryPoint 开始的。让我们编写一个 AuthenticationEntryPoint 的实现,用于拦截 Security 异常。
3.1、配置 AuthenticationEntryPoint 实现 AuthenticationEntryPoint 并覆写 commence() 方法:
@Component("customAuthenticationEntryPoint") public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint { @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException { RestError re = new RestError(HttpStatus.
在本文中,我们将学习如何使用 “客户端凭证模式”(Client Credentials Flow)实现服务间的通信。我们将创建 archival-service,在其中通过定时任务使用 “客户端凭证模式” 来调用 messages-service API 以归档消息。
我们还会在 archival-service 中实现 POST /api/messages/archive API 端点,只有拥有 ROLE_ADMIN 角色的用户才能调用。
有鉴于此,archival-service 既是资源服务器(Resource Server),也是客户端。
资源服务器 - 暴露 POST /api/messages/archive API 端点,该端点将由 messages-webapp 调用。 客户端 - 调用 messages-service API 来归档消息。 你可以从 Github 仓库 获取到当前项目的完整源码。
在 Keycloak 中启用客户端凭证模式,创建 archival-service 客户端 创建一个名为 archival-service 的新客户端:
General Settings: Client type:OpenID Connect Client ID:archival-service Capability config: Client authentication:On Authorization:Off Authentication flow:选中 Service accounts roles,取消选中其余复选框 Login settings: Root URL: http://localhost:8282 Home URL: http://localhost:8282 使用上述配置创建客户端后,你将进入新创建的客户端 “Settings” 页面。
在前面的文章中,我们创建了 messages-webapp 和 messages-service,并使用 Postman 调用了 API 端点。在本文中,我们将学习如何从客户端应用 messages-webapp 调用受保护的 messages-service API 端点。
你可以从 Github 仓库 获取到完整的源码。
展示消息列表 由于 messages-service 中的 GET /api/messages API 端点是可公开访问的,因此我们可以从 messages-webapp 调用它,而无需任何身份认证。
RestTemplate 和 RestClient
我们使用传统的 RestTemplate 来调用 messages-service 中的 API 端点。但在 Spring Boot 3.2.0 后,建议改用 RestClient。
在 messages-webapp 中,创建 AppConfig 类,如下:
package com.sivalabs.messages.config; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class AppConfig { @Bean public RestTemplate restTemplate(RestTemplateBuilder builder) { return builder.build(); } } 我们注册了一个 RestTemplate Bean,以便将其注入到其他组件中。
在 上一篇文章 中,我们创建了 messages-webapp,并使用 “授权码模式” 通过 Spring Security OAuth 2.0 对其进行了访问控制。在本文中,我们将创建 messages-service(Spring Boot 资源服务器),并使用 Spring Security OAuth 2.0 进行访问控制。
你可以在 Github 仓库 找到该项目完整的源码。
创建 messages-service 点击此 链接 可使用 Spring Initializr 生成 messages-service。我们选择了 Web、Validation、Security 和 OAuth2 Resource Server Starter。应用生成后,在 IDE 打开它。
配置 OAuth 2.0 资源服务器属性 messages-service 是 bearer-only 类型的资源服务器。这意味着如果有人使用有效的 access_token 作为 Authorization 头发送请求到受保护的 API 端点,该服务将返回响应。否则,它将只会返回 401 或 403 的 HTTP 状态码,而不会启动 OAuth 2.0 的授权流程。
bearer-only 类型的资源服务器无需向授权服务器(Keycloak)注册。我们只需在 application.properties 文件中配置 issuer-uri 如下:
spring.application.name=messages-service server.