2026年SpringSecurity6.x权限控制实战与源码剖析_第1页
2026年SpringSecurity6.x权限控制实战与源码剖析_第2页
2026年SpringSecurity6.x权限控制实战与源码剖析_第3页
2026年SpringSecurity6.x权限控制实战与源码剖析_第4页
2026年SpringSecurity6.x权限控制实战与源码剖析_第5页
已阅读5页,还剩55页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

2026年SpringSecurity6.x权限控制实战与源码剖析

#2026年SpringSecurity6.x权限控制实战与源码剖析

##一、SpringSecurity6.x核心概念与架构概述

SpringSecurity是一款功能强大且高度可定制的安全框架,广泛应用于Java应用程序中,用于提供认证(Authentication)和授权(Authorization)功能。随着Spring框架的不断演进,SpringSecurity也在持续更新,SpringSecurity6.x版本在性能、易用性和扩展性方面进行了重大优化。本文将深入探讨SpringSecurity6.x的权限控制机制,并结合实战案例和源码剖析,帮助读者全面理解其工作原理。

###1.1SpringSecurity6.x的认证与授权流程

在深入探讨权限控制之前,我们需要先理解SpringSecurity的认证与授权流程。认证是指验证用户身份的过程,而授权则是确定用户是否有权访问特定资源的过程。SpringSecurity6.x的认证授权流程可以概括为以下几个关键步骤:

1.**请求拦截**:当用户发起请求时,SpringSecurity的过滤器链(FilterChain)会拦截该请求。默认情况下,SpringSecurity提供了多个内置过滤器,如`UsernamePasswordAuthenticationFilter`、`FilterSecurityInterceptor`等,这些过滤器负责处理不同的安全需求。

2.**认证尝试**:如果请求需要认证(例如,用户未登录或请求了受保护资源),`UsernamePasswordAuthenticationFilter`会尝试从请求中获取用户凭证(如用户名和密码),并将其传递给`AuthenticationManager`进行认证。

3.**AuthenticationManager处理**:`AuthenticationManager`是SpringSecurity的核心组件,负责实际的用户认证工作。默认情况下,`AuthenticationManager`会调用`UserDetailsService`加载用户信息,并验证用户凭证。如果认证成功,`AuthenticationManager`会返回一个`Authentication`对象,其中包含用户的详细信息。

4.**授权检查**:认证成功后,SpringSecurity会检查用户是否有权访问当前请求的资源。这一步骤由`FilterSecurityInterceptor`负责,它会根据配置的`SecurityExpressionHandler`评估安全表达式(如`hasRole("ADMIN")`),并决定是否允许用户访问资源。

5.**响应处理**:根据认证和授权的结果,SpringSecurity会决定如何响应请求。如果认证或授权失败,通常会返回401或403状态码;如果成功,则继续处理请求。

###1.2SpringSecurity6.x的核心组件

SpringSecurity6.x的架构主要由以下几个核心组件构成:

-**FilterChain**:过滤器链是SpringSecurity的核心,负责拦截和处理请求。SpringSecurity6.x提供了更灵活的过滤器链配置,允许开发者自定义过滤器顺序和逻辑。

-**AuthenticationManager**:认证管理器是负责用户认证的核心组件,它接收`Authentication`对象并返回认证结果。SpringSecurity6.x支持多种认证策略,如基于表单的认证、基于JWT的认证等。

-**UserDetailsService**:用户信息服务接口,用于加载用户详细信息。SpringSecurity6.x对`UserDetailsService`进行了优化,支持异步加载用户信息,提高了认证性能。

-**SecurityContextHolder**:安全持有者,用于存储当前认证用户的`Authentication`对象。SpringSecurity6.x对`SecurityContextHolder`进行了改进,支持线程本地存储,确保线程安全。

-**SecurityExpressionHandler**:安全表达式处理器,用于评估安全表达式(如`hasRole("ADMIN")`)。SpringSecurity6.x提供了更丰富的表达式支持,如方法调用、属性访问等。

-**AuthorizationManager**:授权管理器,用于检查用户是否有权访问特定资源。SpringSecurity6.x对`AuthorizationManager`进行了优化,支持更复杂的授权逻辑。

###1.3SpringSecurity6.x的配置方式

SpringSecurity6.x支持多种配置方式,包括注解配置、XML配置和Java配置。本文将以Java配置为例,展示如何配置SpringSecurity的权限控制。

importorg.springframework.context.annotation.Configuration;

importorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;

importorg.springframework.security.config.annotation.web.builders.HttpSecurity;

importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

importorg.springframework.security.crypto.password.PasswordEncoder;

@Configuration

@EnableWebSecurity

publicclassSecurityConfigextendsWebSecurityConfigurerAdapter{

privatefinalPasswordEncoderpasswordEncoder;

publicSecurityConfig(PasswordEncoderpasswordEncoder){

this.passwordEncoder=passwordEncoder;

}

@Override

protectedvoidconfigure(AuthenticationManagerBuilderauth)throwsException{

auth.inMemoryAuthentication()

.withUser("user")

.password(passwordEncoder.encode("password"))

.roles("USER")

.and()

.withUser("admin")

.password(passwordEncoder.encode("admin"))

.roles("ADMIN");

}

@Override

protectedvoidconfigure(HttpSecurityhttp)throwsException{

http

.authorizeRequests()

.antMatchers("/public/**").permitAll()

.antMatchers("/admin/**").hasRole("ADMIN")

.anyRequest().authenticated()

.and()

.formLogin()

.and()

.httpBasic();

}

}

在上面的配置中,我们定义了两个用户:`user`和`admin`。`user`具有`USER`角色,只能访问`/public/**`路径;`admin`具有`ADMIN`角色,可以访问`/public/**`和`/admin/**`路径。此外,我们还配置了表单登录和HTTP基本认证。

###1.4SpringSecurity6.x的安全表达式

SpringSecurity6.x提供了强大的安全表达式机制,允许开发者定义复杂的访问控制逻辑。安全表达式基于表达式语言(如SpEL),支持方法调用、属性访问、逻辑运算等。

.hasRole("ADMIN")

.hasAuthority("READ")

.hasAnyRole("USER","ADMIN")

.hasIpAddress("")

.hasAuthority("com.example.security.HasPermission")

在上面的表达式中:

-`hasRole("ADMIN")`:检查用户是否具有`ADMIN`角色。

-`hasAuthority("READ")`:检查用户是否具有`READ`权限。

-`hasAnyRole("USER","ADMIN")`:检查用户是否具有`USER`或`ADMIN`角色中的任意一个。

-`hasIpAddress("")`:检查用户的IP地址是否为``。

-`hasAuthority("com.example.security.HasPermission")`:检查用户是否具有自定义权限。

安全表达式可以在`HttpSecurity`配置中使用,例如:

http

.authorizeRequests()

.antMatchers("/public/**").permitAll()

.antMatchers("/admin/**").hasAuthority("com.example.security.AdminAccess")

.anyRequest().authenticated()

.and()

.formLogin()

.and()

.httpBasic();

在上面的配置中,`/admin/**`路径需要用户具有`com.example.security.AdminAccess`权限。

###1.5SpringSecurity6.x的实战案例

为了更好地理解SpringSecurity6.x的权限控制,我们来看一个实战案例:一个简单的RESTAPI,包含用户认证和授权功能。

####1.5.1项目结构

项目结构如下:

src

├──main

│├──java

││└──com

││└──example

││└──security

││├──SecurityConfig.java

││└──SecurityController.java

│├──resources

││└──perties

│└──webapp

│└──index.html

└──test

└──java

└──com

└──example

└──security

└──SecurityControllerTest.java

####1.5.2配置文件

`perties`:

spring.datasource.url=jdbc:mysql://localhost:3306/security

spring.datasource.username=root

spring.datasource.password=root

spring.jpa.hibernate.ddl-auto=update

spring.jpa.show-sql=true

`SecurityConfig.java`:

importorg.springframework.context.annotation.Configuration;

importorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;

importorg.springframework.security.config.annotation.web.builders.HttpSecurity;

importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

importorg.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration

@EnableWebSecurity

publicclassSecurityConfigextendsWebSecurityConfigurerAdapter{

privatefinalBCryptPasswordEncoderpasswordEncoder=newBCryptPasswordEncoder();

@Override

protectedvoidconfigure(AuthenticationManagerBuilderauth)throwsException{

auth.inMemoryAuthentication()

.withUser("user")

.password(passwordEncoder.encode("password"))

.roles("USER")

.and()

.withUser("admin")

.password(passwordEncoder.encode("admin"))

.roles("ADMIN");

}

@Override

protectedvoidconfigure(HttpSecurityhttp)throwsException{

http

.authorizeRequests()

.antMatchers("/public/**").permitAll()

.antMatchers("/admin/**").hasRole("ADMIN")

.anyRequest().authenticated()

.and()

.formLogin()

.and()

.httpBasic();

}

}

####1.5.3控制器

`SecurityController.java`:

importorg.springframework.security.access.prepost.PreAuthorize;

importorg.springframework.web.bind.annotation.GetMapping;

importorg.springframework.web.bind.annotation.RestController;

@RestController

publicclassSecurityController{

@GetMapping("/public/hello")

publicStringhelloPublic(){

return"Hello,public!";

}

@PreAuthorize("hasRole('ADMIN')")

@GetMapping("/admin/hello")

publicStringhelloAdmin(){

return"Hello,admin!";

}

@PreAuthorize("hasAuthority('com.example.security.Read')")

@GetMapping("/read/hello")

publicStringhelloRead(){

return"Hello,read!";

}

}

在上面的控制器中:

-`/public/hello`:无需认证即可访问。

-`/admin/hello`:需要`ADMIN`角色才能访问。

-`/read/hello`:需要`com.example.security.Read`权限才能访问。

####1.5.4测试

`SecurityControllerTest.java`:

```java

importorg.junit.jupiter.api.Test;

importorg.springframework.beans.factory.annotation.Autowired;

importorg.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;

importorg.springframework.boot.test.context.SpringBootTest;

importorg.springframework.security.test.context.support.WithMockUser;

importorg.springframework.test.web.servlet.MockMvc;

importstaticorg.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;

importstaticorg.springframework.test.web.servlet.result.MockMvcResultMatchers.content;

importstaticorg.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest

@AutoConfigureMockMvc

publicclassSecurityControllerTest{

@Autowired

privateMockMvcmockMvc;

@Test

publicvoidtestPublic()throwsException{

mockMvc.perform(get("/public/hello"))

.andExpect(status().isOk())

.andExpect(content().string("Hello,public!"));

}

@Test

publicvoidtestAdmin()throwsException{

mockMvc.perform(get("/admin/hello"))

.andExpect(status().isOk())

.andExpect(content().string("Hello,admin!"));

}

@Test

publicvoidtestRead()throwsException{

mockMvc.perform(get("/read/hello"))

.andExpect(status().isOk())

.andExpect(content().string("Hello,read!"));

}

@Test

publicvoidtestAdminFail()throwsException{

mockMvc.perform(get("/admin/hello"))

.andExpect(status().isUnauthorized());

}

@Test

@WithMockUser(username="user",roles="USER")

publicvoidtestReadFail()throwsException{

mockMvc.perform(get("/read/hello"))

.andExpect(status().isUnauthorized());

}

}

在上面的测试中:

-`testPublic`:测试公开路径。

-`testAdmin`:测试需要`ADMIN`角色的路径。

-`testRead`:测试需要`com.example.security.Read`权限的路径。

-`testAdminFail`:测试没有`ADMIN`角色的用户访问`/admin/hello`路径,预期返回401。

-`testReadFail`:测试没有`com.example.security.Read`权限的用户访问`/read/hello`路径,预期返回401。

##一、SpringSecurity6.x核心概念与架构概述(续)

###1.6SpringSecurity6.x与OAuth2的集成

SpringSecurity6.x提供了对OAuth2的全面支持,包括OAuth2客户端和资源服务器。开发者可以通过配置SpringSecurityOAuth2来轻松实现OAuth2认证和授权。

```java

importorg.springframework.context.annotation.Configuration;

importorg.springframework.security.authentication.AuthenticationManager;

importorg.springframework.security.oauth2.client.OAuth2ClientContext;

importorg.springframework.security.oauth2.client.OAuth2ClientEnvironment;

importorg.springframework.security.oauth2.client.config.annotation.web.configuration.EnableAuthorizationCodeResourceOwnerClientRegistries;

importorg.springframework.security.oauth2.client.config.annotation.web.configuration.EnableAuthorizationCodeResourceOwnerClientRegistry;

importorg.springframework.security.oauth2.client.config.annotation.web.configuration.EnableResourceServer;

importorg.springframework.security.oauth2.client.config.annotation.web.configuration.ResourceServerConfigurerAdapter;

importorg.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;

importorg.springframework.security.oauth2.client.resource.OAuth2ResourceServer;

importorg.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceServer;

importorg.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceServer;

importorg.springframework.security.oauth2.client.token.grant.code.flow.AuthorizationCodeFlowResourceServer;

importorg.springframework.security.oauth2.client.token.store.JwtAccessTokenConverter;

importorg.springframework.security.oauth2.client.token.store.JwtClientCredentials;

@Configuration

@EnableAuthorizationCodeResourceOwnerClientRegistries

@EnableResourceServer

publicclassSecurityConfigextendsResourceServerConfigurerAdapter{

privatefinalAuthenticationManagerauthenticationManager;

publicSecurityConfig(AuthenticationManagerauthenticationManager){

this.authenticationManager=authenticationManager;

}

@Override

publicvoidconfigure(ResourceServerRequestMatcherRegistryregistry){

registry.resourceServer("/api/**")

.jwt()

.jwtAuthenticationConverter(jwtAccessTokenConverter());

}

@Override

publicvoidconfigure(ClientDetailsServiceConfigurerclients)throwsException{

clients.inMemory()

.withClient("client_id")

.secret("client_secret")

.authorizedGrantTypes("authorization_code","client_credentials")

.scopes("read","write")

.redirectUris("http://localhost:8080/callback");

}

@Override

publicvoidconfigure(AuthorizationCodeResourceOwnerClientRegistryregistry){

registry.register("resource_owner")

.authorizationCodeFlow(flow())

.scopes("read","write")

.redirectUris("http://localhost:8080/callback");

}

privateAuthorizationCodeFlowResourceServerflow(){

returnnewAuthorizationCodeFlowResourceServer(authenticationManager,resourceServer());

}

privateOAuth2ResourceServerresourceServer(){

returnnewClientCredentialsResourceServer(newJwtClientCredentials("client_id","client_secret"),jwtAccessTokenConverter());

}

privateJwtAccessTokenConverterjwtAccessTokenConverter(){

JwtAccessTokenConverterconverter=newJwtAccessTokenConverter();

converter.setSecret("secret");

returnconverter;

}

}

在上面的配置中,我们定义了一个OAuth2客户端,支持授权码和客户端凭证两种授权方式。同时,我们还配置了一个资源服务器,用于处理JWT令牌。

###1.7SpringSecurity6.x的异步认证与授权

SpringSecurity6.x支持异步认证和授权,这可以显著提高应用程序的性能,尤其是在高并发场景下。异步处理可以通过配置`AuthenticationManager`和`AuthorizationManager`来实现。

```java

importorg.springframework.context.annotation.Bean;

importorg.springframework.context.annotation.Configuration;

importorg.springframework.security.authentication.AuthenticationManager;

importorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;

importorg.springframework.security.core.Authentication;

importorg.springframework.security.core.AuthenticationException;

importorg.springframework.security.core.context.SecurityContextHolder;

importorg.springframework.security.core.userdetails.UserDetailsService;

importorg.springframework.security.core.userdetails.UsernameNotFoundException;

importorg.springframework.security.crypto.password.PasswordEncoder;

importorg.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;

importorg.springframework.security.oauth2.client.registration.ClientRegistrationRepository;

importorg.springframework.security.oauth2.client.userinfo.OAuth2UserService;

importorg.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;

importorg.springframework.security.oauth2.core.user.OAuth2UserRequest;

importorg.springframework.security.oauth2.core.user.OAuth2User;

importorg.springframework.security.oauth2.core.user.DefaultOAuth2User;

importorg.springframework.security.oauth2.core.user.OAuth2UserAttributes;

importorg.springframework.security.oauth2.core.OAuth2AuthenticationException;

importorg.springframework.scheduling.annotation.Async;

importorg.springframework.scheduling.annotation.EnableAsync;

importorg.springframework.beans.factory.annotation.Autowired;

importorg.springframework.context.annotation.Bean;

importorg.springframework.context.annotation.Configuration;

@Configuration

@EnableAsync

publicclassSecurityConfigextendsWebSecurityConfigurerAdapter{

privatefinalUserDetailsServiceuserDetailsService;

privatefinalPasswordEncoderpasswordEncoder;

privatefinalClientRegistrationRepositoryclientRegistrationRepository;

@Autowired

publicSecurityConfig(UserDetailsServiceuserDetailsService,PasswordEncoderpasswordEncoder,ClientRegistrationRepositoryclientRegistrationRepository){

this.userDetailsService=userDetailsService;

this.passwordEncoder=passwordEncoder;

this.clientRegistrationRepository=clientRegistrationRepository;

}

@Override

protectedvoidconfigure(AuthenticationManagerBuilderauth)throwsException{

auth.userDetailsService(userDetailsService)

.passwordEncoder(passwordEncoder);

}

@Bean

publicAuthenticationManagerauthenticationManagerBean()throwsException{

returnsuper.authenticationManagerBean();

}

@Bean

publicOAuth2UserService<OAuth2UserRequest,OAuth2User>oAuth2UserService(){

returnnewDefaultOAuth2UserService(){

@Override

@Async

publicOAuth2UserloadUser(OAuth2UserRequestuserRequest)throwsOAuth2AuthenticationException{

OAuth2UserAttributesattributes=super.loadUser(userRequest).getAttributes();

Stringusername=attributes.getName();

try{

returnuserDetailsService.loadUserByUsername(username);

}catch(UsernameNotFoundExceptione){

thrownewOAuth2AuthenticationException("Usernotfound",e);

}

}

};

}

}

在上面的配置中,我们使用了`@Async`注解来异步加载用户信息。`OAuth2UserService`的`loadUser`方法被标记为异步,这意味着用户信息的加载不会阻塞主线程,从而提高了认证性能。

###1.8SpringSecurity6.x的安全事件与日志

SpringSecurity6.x提供了丰富的安全事件和日志功能,帮助开发者监控和记录安全相关的操作。SpringSecurity的事件系统基于`ApplicationEvent`,而日志功能则依赖于SLF4J和Logback。

```java

importorg.slf4j.Logger;

importorg.slf4j.LoggerFactory;

importorg.springframework.context.ApplicationListener;

importorg.springframework.context.annotation.Configuration;

importorg.springframework.security.core.Authentication;

importorg.springframework.security.core.AuthenticationEvent;

importorg.springframework.security.core.AuthenticationException;

importorg.springframework.security.core.session.SessionCreatedEvent;

importorg.springframework.security.core.session.SessionDestroyedEvent;

importorg.springframework.security.web.authentication.AuthenticationSuccessHandler;

importorg.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;

@Configuration

publicclassSecurityEventConfig{

privatestaticfinalLoggerlogger=LoggerFactory.getLogger(SecurityEventConfig.class);

@Bean

publicAuthenticationSuccessHandlerauthenticationSuccessHandler(){

SimpleUrlAuthenticationSuccessHandlersuccessHandler=newSimpleUrlAuthenticationSuccessHandler();

successHandler.setSuccessUrl("/home");

returnsuccessHandler;

}

@Configuration

publicstaticclassAuthenticationSuccessEventListenerimplementsApplicationListener<AuthenticationSuccessEvent>{

@Override

publicvoidonApplicationEvent(AuthenticationSuccessEventevent){

Authenticationauthentication=event.getAuthentication();

("Authenticationsuccessforuser:{}",authentication.getName());

}

}

@Configuration

publicstaticclassSessionCreatedEventListenerimplementsApplicationListener<SessionCreatedEvent>{

@Override

publicvoidonApplicationEvent(SessionCreatedEventevent){

("Sessioncreatedforuser:{}",event.getPrincipal());

}

}

@Configuration

publicstaticclassSessionDestroyedEventListenerimplementsApplicationListener<SessionDestroyedEvent>{

@Override

publicvoidonApplicationEvent(SessionDestroyedEventevent){

("Sessiondestroyedforuser:{}",event.getPrincipal());

}

}

}

在上面的配置中,我们定义了三个事件监听器:

-`AuthenticationSuccessEventListener`:监听认证成功事件,记录成功认证的用户。

-`SessionCreatedEventListener`:监听会话创建事件,记录创建会话的用户。

-`SessionDestroyedEventListener`:监听会话销毁事件,记录销毁会话的用户。

###1.9SpringSecurity6.x的跨站请求伪造(CSRF)防护

跨站请求伪造(CSRF)是一种常见的网络攻击方式,SpringSecurity6.x提供了内置的CSRF防护机制。默认情况下,SpringSecurity会禁用CSRF保护,但在某些场景下(如单页应用程序)需要启用CSRF保护。

```java

importorg.springframework.context.annotation.Configuration;

importorg.springframework.security.config.annotation.web.builders.HttpSecurity;

importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration

@EnableWebSecurity

publicclassSecurityConfigextendsWebSecurityConfigurerAdapter{

@Override

protectedvoidconfigure(HttpSecurityhttp)throwsException{

http

.csrf()

.enable()

.and()

.authorizeRequests()

.antMatchers("/public/**").permitAll()

.antMatchers("/admin/**").hasRole("ADMIN")

.anyRequest().authenticated()

.and()

.formLogin()

.and()

.httpBasic();

}

}

在上面的配置中,我们通过`.csrf().enable()`启用了CSRF保护。SpringSecurity会自动生成CSRF令牌,并在表单中嵌入该令牌,以防止CSRF攻击。

###1.10SpringSecurity6.x的会话管理

会话管理是SpringSecurity的重要组成部分,它负责管理用户的会话状态。SpringSecurity6.x提供了多种会话管理策略,如HTTP会话、数据库会话和分布式会话。

```java

importorg.springframework.context.annotation.Configuration;

importorg.springframework.security.config.annotation.web.builders.HttpSecurity;

importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration

@EnableWebSecurity

publicclassSecurityConfigextendsWebSecurityConfigurerAdapter{

@Override

protectedvoidconfigure(HttpSecurityhttp)throwsException{

http

.sessionManagement()

.sessionFixation()

.none()

.and()

.sessionCreationPolicy(HttpSecuritySessionCreationPolicy.NEVER)

.and()

.authorizeRequests()

.antMatchers("/public/**").permitAll()

.antMatchers("/admin/**").hasRole("ADMIN")

.anyRequest().authenticated()

.and()

.formLogin()

.and()

.httpBasic();

}

}

在上面的配置中,我们通过`.sessionManagement()`配置了会话管理策略:

-`.sessionFixation().none()`:禁用会话固定攻击。

-`.sessionCreationPolicy(HttpSecuritySessionCreationPolicy.NEVER)`:禁止创建新的会话。

##一、SpringSecurity6.x核心概念与架构概述(续)

###1.11SpringSecurity6.x的记住我功能

记住我(RememberMe)功能允许用户在一定时间内自动登录,从而提高用户体验。SpringSecurity6.x提供了内置的记住我功能,支持多种记住我实现方式,如Cookie-based和数据库-based。

```java

importorg.springframework.context.annotation.Configuration;

importorg.springframework.security.config.annotation.web.builders.HttpSecurity;

importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration

@EnableWebSecurity

publicclassSecurityConfigextendsWebSecurityConfigurerAdapter{

@Override

protectedvoidconfigure(HttpSecurityhttp)throwsException{

http

.rememberMe()

.key("rememberMeKey")

.rememberMeParameter("rememberMe")

.and()

.authorizeRequests()

.antMatchers("/public/**").permitAll()

.antMatchers("/admin/**").hasRole("ADMIN")

.anyRequest().authenticated()

.and()

.formLogin()

.and()

.httpBasic();

}

}

在上面的配置中,我们通过`.rememberMe()`配置了记住我功能:

-`.key("rememberMeKey")`:设置记住我Cookie的密钥。

-`.rememberMeParameter("rememberMe")`:设置表单中的记住我参数。

###1.12SpringSecurity6.x的HTTP头安全

HTTP头安全是提高应用程序安全性的重要手段,SpringSecurity6.x提供了多种HTTP头安全配置,如X-Frame-Options、X-Content-Type-Options、Strict-Transport-Security等。

```java

importorg.springframework.context.annotation.Configuration;

importorg.springframework.security.config.annotation.web.builders.HttpSecurity;

importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration

@EnableWebSecurity

publicclassSecurityConfigextendsWebSecurityConfigurerAdapter{

@Override

protectedvoidconfigure(HttpSecurityhttp)throwsException{

http

.headers()

.frameOptions().sameOrigin()

.and()

.contentSecurityPolicy("default-src'self';script-src'self''unsafe-inline';")

.and()

.authorizeRequests()

.antMatchers("/public/**").permitAll()

.antMatchers("/admin/**").hasRole("ADMIN")

.anyRequest().authenticated()

.and()

.formLogin()

.and()

.httpBasic();

}

}

在上面的配置中,我们通过`.headers()`配置了HTTP头安全:

-`.frameOptions().sameOrigin()`:设置X-Frame-Options为`SAMEORIGIN`,防止点击劫持。

-`.contentSecurityPolicy("default-src'self';script-src'self''unsafe-inline';")`:设置内容安全策略,限制脚本来源。

###1.13SpringSecurity6.x的数据库集成

SpringSecurity6.x支持与多种数据库集成,如MySQL、PostgreSQL、MongoDB等。通过集成数据库,我们可以存储用户信息、权限数据等,从而实现更灵活的安全管理。

```java

importorg.springframework.context.annotation.Bean;

importorg.springframework.context.annotation.Configuration;

importorg.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;

importorg.springframework.security.config.annotation.web.builders.HttpSecurity;

importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

importorg.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

importorg.springframework.security.core.userdetails.User;

importorg.springframework.security.core.userdetails.UserDetailsService;

importorg.springframework.security.core.userdetails.jdbc.JdbcDaoImpl;

importorg.springframework.security.crypto.password.PasswordEncoder;

importvisioning.JdbcUserDetailsManager;

importjavax.sql.DataSource;

@Configuration

@EnableWebSecurity

publicclassSecurityConfigextendsWebSecurityConfigurerAdapter{

privatefinalDataSourcedataSource;

privatefinalPasswordEncoderpasswordEncoder;

publicSecurityConfig(DataSourcedataSource,PasswordEncoderpasswordEncoder){

this.dataSource=dataSource;

this.passwordEncoder=passwordEncoder;

}

@Override

protectedvoidconfigure(AuthenticationManagerBuilderauth)throwsException{

auth.userDetailsService(userDetailsService())

.passwordEncoder(passwordEncoder);

}

@Override

protectedvoidconfigure(HttpSecurityhttp)throwsException{

http

.authorizeRequests()

.antMatchers("/public/**").permitAll()

.antMatchers("/admin/**").hasRole("ADMIN")

.anyRequest().authenticated()

.and()

.formLogin()

.and()

.httpBasic();

}

@Bean

@Override

publicUserDetailsServiceuserDetailsService(){

returnnewJdbcDaoImpl(){

@Override

protectedvoidadditionalConfig(){

setDataSource(dataSource);

}

};

}

@Bean

publicJdbcUserDetailsManageruserDetailsManager(){

JdbcUserDetailsManagermanager=newJdbcUserDetailsManager();

manager.setDataSource(dataSource);

manager.setPasswordEncoder(passwordEncoder);

returnmanager;

}

}

在上面的配置中,我们通过`JdbcDaoImpl`和`JdbcUserDetailsManager`将SpringSecurity与数据库集成:

-`JdbcDaoImpl`:用于从数据库加载用户信息。

-`JdbcUserDetailsManager`:用于管理用户详细信息。

###1.14SpringSecurity6.x的单元测试

单元测试是确保SpringSecurity配置正确性的重要手段。SpringSecurity提供了丰富的测试支持,包括`MockMvc`、`SecurityMockMvc`等。

```java

importorg.junit.jupiter.api.Test;

importorg.springframework.beans.factory.annotation.Autowired;

importorg.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;

importorg.springframework.boot.test.context.SpringBootTest;

importorg.springframework.security.test.context.support.WithMockUser;

importorg.springframework.test.web.servlet.MockMvc;

importstaticorg.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;

importstaticorg.springframework.test.web.servlet.result.MockMvcResultMatchers.content;

importstaticorg.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest

@AutoConfigureMockMvc

publicclassSecurityConfigTest{

@Autowired

privateMockMvcmockMvc;

@Test

publicvoidtestPublic()throwsException{

mockMvc.perform(get("/public/hello"))

.andExpect(status().isOk())

.andExpect(content().string("Hello,public!"));

}

@Test

@WithMockUser(username="admin",roles="ADMIN")

publicvoidtestAdmin()throwsException{

mockMvc.perform(get("/admin/hello"))

.andExpect(status().isOk())

.andExpect(content().string("Hello,admin!"));

}

@Test

@WithMockUser(username="user",roles="USER")

publicvoidtestReadFail()throwsException{

mockMvc.perform(get("/admin/hello"))

.andExpect(status().isUnauthorized());

}

}

在上面的测试中,我们使用了`@WithMockUser`注解来模拟不同的用户角色,并测试不同的请求路径。通过这些测试,我们可以验证SpringSecurity的权限控制配置是否正确。

##一、SpringSecurity6.x核心概念与架构概述(续)

###1.15SpringSecurity6.x的模块化设计

SpringSecurity6.x采用了模块化设计,这意味着开发者可以根据需求选择不同的模块进行集成。SpringSecurity的核心模块包括认证、授权、会话管理、CSRF保护等,而扩展模块则包括OAuth2、JWT、SAML等。

这种模块化设计使得SpringSecurity非常灵活,开发者可以根据应用程序的需求选择合适的模块进行集成。例如,如果应用程序需要支持OAuth2认证,开发者只需要引入SpringSecurityOAuth2模块即可。

###1.16SpringSecurity6.x的性能优化

SpringSecurity6.x在性能方面进行了多项优化,包括缓存、异步处理、数据库集成等。以下是一些常见的性能优化策略:

####1.16.1缓存

缓存是提高应用程序性能的重要手段,SpringSecurity6.x支持多种缓存策略,如EHCache、Redis等。通过缓存用户信息、权限数据等,可以显著提高认证和授权的性能。

```java

importorg.springframework.context.annotation.Bean;

importorg.springframework.context.annotation.Configuration;

importorg.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

importorg.springframework.security.core.userdetails.UserCache;

importorg.springframework.security.core.userdetails.cache.ConcurrentMapUserCache;

importorg.springframework.security.core.use

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论