Spring-Security

Spring Security 使用 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.

自定义从 JWT Claim 到 Spring Security Authority 的映射

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() .

处理 Spring Security 异常

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.

Spring Security 中的 HttpSecurity 与 WebSecurity

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 的身份认证

本文将会带你了解在 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 项目:

使用 @ExceptionHandler 处理 Spring Security 异常

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.

Spring Security OAuth 2 教程 - 10:使用“客户端凭证模式”进行服务间的通信

在本文中,我们将学习如何使用 “客户端凭证模式”(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” 页面。

Spring Security OAuth 2 教程 - 9:客户端调用资源服务器 API

在前面的文章中,我们创建了 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,以便将其注入到其他组件中。

Spring Security OAuth 2 教程 - 8:资源服务器

在 上一篇文章 中,我们创建了 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.

Spring Security OAuth 2 教程 - 7:Spring MVC 客户端应用

在本文中,我们将创建一个名为 messages-webapp 的 Spring MVC + Thymeleaf Web 应用,并使用 Keycloak 进行访问控制,使用 Spring Security OAuth 2.0 进行认证。 你可以在 Github 上找到该项目的完整源码。 使用 Docker Compose 安装 Keycloak 在上一篇文章中,我们已经了解了如何使用 Docker Compose 安装 Keycloak。 创建 docker-compose.yml 文件,内容如下: version: '3.8' name: spring-security-oauth2-microservices-demo services: keycloak: image: quay.io/keycloak/keycloak:22.0.3 command: ['start-dev'] container_name: keycloak hostname: keycloak environment: - KEYCLOAK_ADMIN=admin - KEYCLOAK_ADMIN_PASSWORD=admin1234 ports: - "9191:8080" 运行以下命令启动 Keycloak 实例: $ docker compose up -d 现在,你可以访问 Keycloak 管理控制台 http://localhost:9191/,并使用 admin/admin1234 登录。 创建 Keycloak Realm、客户端和用户 在前面的文章中,我们已经学习了如何创建 Realm、客户端和用户。请按照 前文 中提到的步骤创建新的 Realm、客户端和用户,只需更改 “Valid redirect URIs”。