您的位置:

Spring Security 6.0详解

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上进行查看。