java springboot总结-security

时间:2025-08-28 08:36:02来源:互联网

下面小编就为大家分享一篇java springboot总结-security,具有很好的参考价值,希望对大家有所帮助。

 简介

spring-boot-starter-security是Spring Boot提供的用于安全性集成的依赖库,它简化了在Spring Boot应用程序中添加安全性功能的过程。

这个starter基于Spring Security构建,用于处理应用程序的身份验证和授权。

以下是关于spring-boot-starter-security的详细介绍:

  1. 身份验证和授权spring-boot-starter-security为你的Spring Boot应用程序提供了全面的身份验证和授权支持。你可以轻松地配置和管理用户的身份验证,以及用户对应用程序的访问权限。

  2. 自定义认证方式:Spring Security允许你使用各种身份验证方式,如基本身份验证、表单登录、OAuth等。你可以根据你的需求选择适当的认证方式,并进行定制化配置。

  3. 用户存储:你可以将用户存储在内存、数据库或其他用户存储后端中。Spring Security提供了多种选项,包括使用JDBC、LDAP、OAuth等方式进行用户管理。

  4. 注解支持spring-boot-starter-security提供了注解支持,允许你在方法级别或类级别进行安全性控制。通过@PreAuthorize@PostAuthorize等注解,你可以定义谁可以访问特定的方法或资源。

  5. CSRF保护:默认情况下,Spring Security提供了跨站请求伪造(CSRF)保护,以增加应用程序的安全性。

  6. 会话管理:你可以配置和管理用户会话,包括会话过期时间和并发会话数。

  7. 集成第三方身份验证:Spring Security允许你集成第三方身份验证提供者,如OAuth 2.0、OpenID Connect等,以支持单点登录和安全的API访问。

  8. 定制化配置:你可以使用Java配置或XML配置来定制Spring Security的行为,以满足你的应用程序需求。

  9. 默认安全性配置spring-boot-starter-security提供了默认的安全性配置,包括基本的HTTP基本认证和禁用了CSRF保护。你可以根据需要进行自定义配置,或者完全禁用它并从头开始构建自己的安全性配置。

  10. 自动配置:Spring Boot自动配置了许多常见的安全性设置,使得在Spring Boot应用程序中启用安全性非常容易。

使用

加入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security </artifactId>
        </dependency>

启动项目,控制台会输出生成的登录密码(如果控制台没有看到,看配置的spring的日志级别,info级别可以输出),默认的账号是user

生成的密码是调用的uuid随机生成的,所以每次启动都会生成不同的密码

访问项目,会跳转到security自带的一个登录页面

身份验证和授权功能

我们创建了一个SecurityConfig类,它继承自WebSecurityConfigurerAdapter,并使用@EnableWebSecurity注解启用Spring Security。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/public/**").permitAll() // 允许所有用户访问公开的URL
                .antMatchers("/admin/**").hasRole("ADMIN") // 需要ADMIN角色才能访问
                .anyRequest().authenticated() // 所有其他请求需要认证
                .and()
            .formLogin()
                .loginPage("/login") // 自定义登录页面
                .permitAll()
                .and()
            .logout()
                .logoutUrl("/logout") // 自定义登出URL
                .permitAll();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 配置使用内存身份验证方式
        auth
            .inMemoryAuthentication()
                .withUser("user")
                .password(passwordEncoder().encode("password"))
                .roles("USER");
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

配置的关键部分是configure(HttpSecurity http)方法,它定义了URL的访问规则和认证方式。在示例中:

  • /public/**路径的URL是公开的,所有用户都可以访问。
  • /admin/**路径的URL需要用户具有ADMIN角色才能访问。
  • 所有其他请求都需要进行身份认证。

此外,我们定义了自定义的登录页面和登出URL

身份验证方式

内存身份验证方式:

配置类中:

 @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 配置使用内存身份验证方式
        auth
            .inMemoryAuthentication()
                .withUser("user")
                .password(passwordEncoder().encode("password"))
                .roles("USER");
    }

 

UserDetailsService身份认证

配置类中:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomUserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/public/**").permitAll() // 允许所有用户访问公开的URL
                .antMatchers("/secured/**").authenticated() // 需要身份验证的URL
                .and()
            .formLogin()
                .loginPage("/login") // 自定义登录页面的URL
                .permitAll()
                .and()
            .logout()
                .logoutUrl("/logout") // 自定义登出URL
                .permitAll();
    }
}

创建一个实现UserDetailsService接口的自定义类

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class CustomUserDetailsService implements UserDetailsService {

    // 实现loadUserByUsername方法来检索用户信息
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        if ("user".equals(username)) {
                    return User.builder()
                            .username("user")
                            .password(passwordEncoder().encode("password"))
                            .roles("USER")
                            .build();
                } else if ("admin".equals(username)) {
                    return User.builder()
                            .username("admin")
                            .password(passwordEncoder().encode("adminpassword"))
                            .roles("ADMIN")
                            .build();
                } else {
                    throw new UsernameNotFoundException("User not found.");
                }
            }
    }
}

上面是使用的Spring Security提供的User类。也可以自定义用户实体类,这个类通常需要实现UserDetails接口。

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;

public class CustomUserDetails implements UserDetails {

    private String username;
    private String password;
    private Collection<? extends GrantedAuthority> authorities;

    // 构造函数、getter和setter方法

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return authorities;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    // 其他UserDetails接口方法的实现
}

 静态资源访问策略

WebSecurity用于配置Spring Security的静态资源访问策略,如CSS、JavaScript、图片等静态资源的访问。

在WebSecurityConfigurerAdapter的实现类中添加如下

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/css/**","/fonts/**","/images/**","/js/**");
}
  • web.ignoring() 表示你要忽略某些路径的访问策略。
  • .antMatchers("/css/**","/fonts/**","/images/**","/js/**") 指定了要忽略的路径模式,/**通配符表示匹配任何深度的路径。

告诉Spring Security不要对这些静态资源路径应用任何安全性控制,因此它们可以被所有用户直接访问,而不需要登录或授权。

HttpSecurity常见配置

  1. URL权限控制:

    • .authorizeRequests(): 用于配置URL的访问权限规则。
      • .antMatchers("/public/**").permitAll(): 允许所有用户访问/public/**路径的URL。
      • .antMatchers("/secured/**").authenticated(): 需要用户进行身份验证才能访问/secured/**路径的URL。
      • .antMatchers("/admin/**").hasRole("ADMIN"): 需要用户具有ADMIN角色才能访问/admin/**路径的URL。
      • .anyRequest().authenticated(): 所有其他请求都需要进行身份验证。
  2. 登录配置:

    • .formLogin(): 配置表单登录。
      • .loginPage("/login"): 自定义登录页面的URL。
      • .permitAll(): 允许所有用户访问登录页面。
    • .loginProcessingUrl("/login"): 指定登录请求的URL。
    • .defaultSuccessUrl("/home"): 登录成功后的默认重定向URL。
    • .failureUrl("/login?error=true"): 登录失败后的重定向URL。
  3. 注销配置:

    • .logout(): 配置注销功能。
      • .logoutUrl("/logout"): 自定义注销URL。
      • .permitAll(): 允许所有用户注销。
      • .logoutSuccessUrl("/login?logout=true"): 注销成功后的重定向URL。
  4. 记住我功能配置:

    • .rememberMe(): 配置"记住我"功能。
      • .rememberMeParameter("remember-me"): 指定"记住我"的参数名称。
      • .rememberMeCookieName("remember-me-cookie"): 指定"记住我"的cookie名称。
      • .tokenValiditySeconds(604800): 指定记住我token的有效期(秒)。
  5. CSRF保护:

    • .csrf(): 配置CSRF(Cross-Site Request Forgery)保护。
      • .disable(): 禁用CSRF保护。
      • .csrfTokenRepository(csrfTokenRepository): 配置自定义的CSRF Token仓库。
  6. HTTP Basic认证配置:

    • .httpBasic(): 配置HTTP Basic认证。
      • .realmName("My Realm"): 指定HTTP Basic认证的Realm名称。
  7. 会话管理:

    • .sessionManagement(): 配置会话管理。
      • .sessionCreationPolicy(SessionCreationPolicy.STATELESS): 使用无状态会话。
      • .maximumSessions(1).maxSessionsPreventsLogin(true): 同时只允许一个用户登录,阻止其他用户登录。
  8. 安全头部配置:

    • .headers(): 配置HTTP响应头部的安全性。
      • .contentSecurityPolicy("default-src 'self'"): 配置内容安全策略。
  9. 异常处理:

    • .exceptionHandling(): 配置异常处理。
      • .accessDeniedPage("/access-denied"): 指定访问被拒绝时的错误页面。
  10. 自定义过滤器和拦截器:

    • .addFilterBefore(filter, beforeFilter): 在指定的过滤器之前添加自定义过滤器。
    • .addFilterAfter(filter, afterFilter): 在指定的过滤器之后添加自定义过滤器。
    • .addFilterAt(filter, atFilter): 在指定位置添加自定义过滤器。
    • .addFilterBefore(filter, beforeFilter): 在指定的拦截器之前添加自定义拦截器。

以上是一些常见的HttpSecurity配置选项,你可以根据你的应用程序的具体需求来组合和配置这些选项。

用户存储

默认情况下,它使用了内存中的用户存储来简化开发和测试。这意味着你可以轻松地在你的Spring Boot应用程序中配置一些用户,而不需要连接到数据库或其他持久化存储。

允许你在配置文件或Java代码中定义用户、密码和角色。这些用户数据仅在应用程序运行时存在,不会持久化到任何数据库或文件中。

你也可以轻松地切换到其他用户存储方式,如数据库

注解支持

@EnableWebSecurity:这个注解通常在一个配置类上使用,用于启用Spring Security的Web安全性功能。在配置类上使用该注解后,你可以自定义身份验证和授权规则。

@Secured@Secured注解用于在方法级别进行授权。你可以在希望受保护的方法上添加@Secured注解,并指定允许访问的角色或权限。例如:

@Secured("ROLE_ADMIN")
public void adminMethod() {
    // 只有具有ROLE_ADMIN角色的用户才能访问此方法
}

@PreAuthorize 和 @PostAuthorize:这两个注解允许你在方法执行前和执行后进行访问控制。@PreAuthorize用于在方法执行前进行授权检查,而@PostAuthorize用于在方法执行后进行授权检查。你可以使用SpEL表达式定义授权规则。例如:

@PreAuthorize("hasRole('ROLE_ADMIN')")
public void adminMethod() {
    // 只有具有ROLE_ADMIN角色的用户才能访问此方法
}

@RolesAllowed@RolesAllowed注解是Java EE的标准注解,可以在方法级别指定允许访问的角色。它与@Secured类似,但不支持SpEL表达式。

@AuthenticationPrincipal@AuthenticationPrincipal注解允许你在方法参数中获取当前认证用户的Principal(主体)。你可以使用它来方便地获取已认证用户的信息。例如:

@GetMapping("/profile")
public String userProfile(@AuthenticationPrincipal CustomUserDetails userDetails) {
    // 使用@AuthenticationPrincipal注解获取已认证用户的信息
    String username = userDetails.getUsername();
    // ...
}

@EnableGlobalMethodSecurity:通过在配置类上使用@EnableGlobalMethodSecurity注解,你可以启用全局方法级别的安全性注解,例如@Secured@PreAuthorize@PostAuthorize等。这样你可以在多个方法中共享相同的安全性规则。、

会话管理

可以帮助你控制和管理用户的会话,包括会话的创建、并发控制、会话过期等。以下是spring-boot-starter-security提供的会话管理功能的主要方面:

  1. 会话创建策略

    • SessionCreationPolicy.ALWAYS(默认):始终创建会话,无论用户是否经过身份验证。
    • SessionCreationPolicy.IF_REQUIRED:仅在需要时创建会话,即用户进行身份验证后。
    • SessionCreationPolicy.NEVER:从不创建会话。
    • SessionCreationPolicy.STATELESS:会话是无状态的,不会创建或使用HTTP会话。
  2. 并发控制

    • 你可以配置每个用户允许的最大并发会话数量,以防止多个登录会话同时进行。
    • maximumSessions(int maxSessions)方法用于配置允许的最大会话数量。
    • maxSessionsPreventsLogin(boolean maxSessionsPreventsLogin)方法用于确定当会话达到最大数量时是否阻止新的登录。
  3. 会话过期策略

    • invalidSessionUrl(String invalidSessionUrl)方法用于指定会话过期后的重定向URL。
    • sessionFixation()方法用于配置会话固定保护策略,以防止会话固定攻击。
  4. 会话注册

    • 你可以注册会话监听器来处理会话的创建、销毁和过期事件。
    • sessionRegistry()方法用于配置会话注册表,以跟踪活动会话和已过期的会话。
  5. 会话保护

    • invalidSessionUrl(String invalidSessionUrl)方法用于指定在会话无效(例如,过期或无效)时的重定向URL。
    • 你可以使用HttpSessionEventPublisher来启用会话事件发布,以便Spring Security可以检测到会话过期等事件。
  6. 记住我功能

    • rememberMe()方法用于配置"记住我"功能,允许用户在会话过期后继续保持登录状态。
    • tokenValiditySeconds(int seconds)方法用于指定"记住我"令牌的有效期。
  7. 自定义会话管理

    • 你可以创建自定义的会话管理器,以实现更高级的会话控制和管理逻辑。

下面是一个示例配置,演示了如何在Spring Security中配置会话管理:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/public/**").permitAll()
                .antMatchers("/secured/**").authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .logoutUrl("/logout")
                .permitAll()
                .and()
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) // 会话创建策略
                .maximumSessions(1) // 最大并发会话数量
                .maxSessionsPreventsLogin(true) // 当会话达到最大数量时阻止新的登录
                .expiredUrl("/login?expired=true") // 会话过期后的重定向URL
                .and()
            .and()
            .rememberMe()
                .tokenValiditySeconds(604800); // 记住我功能,设置令牌有效期为一周
    }
}

 

本站部分内容转载自互联网,如果有网站内容侵犯了您的权益,可直接联系我们删除,感谢支持!