Spring Security是一种基于Spring框架的安全选项,在Spring Boot应用程序中支持对应用程序进行身份验证和授权。Spring Security 5.5.0于2021年6月发布,这个版本引入了许多新特性和重大变化,其中一些经验在Spring Security 6.0中得以发扬光大。
一、Web安全
一个Web应用程序通常由许多不同的Web资源组成,包括静态文件、视图模板、控制器和RESTful服务。Spring Security 6.0 提供了基于路径和基于方法的安全性,以保护应用程序中的每个资源。
首先,我们需要在pom.xml中添加以下依赖项:
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>6.0.0</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-config</artifactId> <version>6.0.0</version> </dependency>
我们定义一个WebSecurityConfiguration以向应用程序添加基于路径的安全性。在此示例中,我们定义了基本身份验证的用户名和密码。
@Configuration @EnableWebSecurity public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/**").permitAll() .and().httpBasic(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("admin").password("{noop}admin").roles("ADMIN") .and() .withUser("user").password("{noop}password").roles("USER"); } }
以上代码定义了两个用户admin和user,其中admin用户拥有ROLE_ADMIN角色,而user用户没有特殊的角色。使用antMatchers()方法定义了访问特定URL时所需的角色。在这种情况下,我们定义了/admin/**URL需要ADMIN角色来访问,其他URL可以从任何角色访问。HTTP基本身份验证还被注册以保护路径。
二、OAuth2.0安全
OAuth 2.0是常用的API安全协议,允许用户授权第三方应用程序访问他们在其他资源服务器上的数据。Spring Security 6.0 提供了一个OAuth 2.0客户端和服务端的实现。
我们需要在pom.xml中添加以下依赖项:
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-oauth2-client</artifactId> <version>6.0.0</version> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-oauth2-jose</artifactId> <version>6.0.0</version> </dependency>
现在我们可以定义一个OAuth2认证服务器,它将接收来自客户端的请求,并确认用户身份认证。
@Configuration @EnableAuthorizationServer public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter { private final JwtAccessTokenConverter jwtAccessTokenConverter; public AuthorizationServerConfiguration(JwtAccessTokenConverter jwtAccessTokenConverter) { this.jwtAccessTokenConverter = jwtAccessTokenConverter; } @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory() .withClient("my-client") .secret("{noop}secret") .authorizedGrantTypes("client_credentials") .scopes("read", "write") .accessTokenValiditySeconds(3600); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.tokenStore(new JwtTokenStore(jwtAccessTokenConverter)); } }
在这里,我们定义了一个名为my-client的客户端,该客户端使用client_credentials授予类型获得OAuth 2.0令牌。还定义了读取和写入哪些作用域,并设置令牌有效期为3600秒。最终,我们将JWT令牌存储在JwtTokenStore中。
三、全局安全性
Spring Security 6.0引入了全局安全性特性,通过默认全局安全配置保护应用程序的每个资源。全局安全配置成为应用程序所有端点的默认安全配置,从而提供了内置的安全性。
我们需要在pom.xml中添加以下依赖项:
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> <version>6.0.0</version> </dependency>
我们还需要定义一个全局安全配置类。
@Configuration public class GlobalSecurityConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated() .and().formLogin() .and().httpBasic(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("admin").password("{noop}admin").roles("ADMIN") .and() .withUser("user").password("{noop}password").roles("USER"); } }
在这里,我们定义了全局身份验证和授权,默认情况下所有请求都需要经过身份验证。我们也定义了两个用户,admin和user用户,以及他们的角色和密码。
四、个性化登录页面
Spring Security 6.0支持自定义登录页面,该页面可以替换默认登录页面。我们可以通过配置添加自己的loginPage()方法来实现这个目标。
@Configuration @EnableWebSecurity public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .successHandler(customAuthenticationSuccessHandler) .permitAll() .and() .logout().permitAll(); } }
在这里,我们定义了一个loginPage()方法,将使用自定义登录页面作为登录页面。我们还定义了一个自定义登录成功处理程序,该处理程序需要继承AuthenticationSuccessHandler以提供自己的身份验证成功逻辑。
五、结语
Spring Security 6.0是一个非常有用和强大的安全性框架,它提供了全面的安全性选项,包括Web安全,OAuth2.0安全和全局安全性。在我们的应用程序中使用Spring Security 6.0可以保护我们的资源免受未经授权的访问和攻击。
完整代码示例,可以在Github上进行查看。