最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中Spring Security的使用及最佳實(shí)踐

 更新時間:2025年07月28日 16:22:36   作者:冉成未來  
Spring Security是Spring生態(tài)中的安全框架,提供認(rèn)證、授權(quán)、攻擊防護(hù)及OAuth2/JWT集成等核心功能,支持靈活配置如內(nèi)存/數(shù)據(jù)庫認(rèn)證與密碼加密,適用于構(gòu)建安全應(yīng)用,本文給大家介紹Java中Spring Security的使用及最佳實(shí)踐,感興趣的朋友一起看看吧

1. Spring Security 簡介

Spring Security 是一個功能強(qiáng)大且高度可定制的身份驗(yàn)證和訪問控制框架,它是 Spring 生態(tài)系統(tǒng)中的標(biāo)準(zhǔn)安全框架。主要提供以下功能:

  • 認(rèn)證(Authentication):驗(yàn)證用戶身份
  • 授權(quán)(Authorization):控制用戶訪問權(quán)限
  • 防護(hù)攻擊:防止 CSRF、會話固定等攻擊
  • 與其他技術(shù)集成:如 OAuth2、LDAP 等

2. 快速開始

2.1 添加依賴

對于 Maven 項(xiàng)目,在 pom.xml 中添加:

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

對于 Gradle 項(xiàng)目:

implementation 'org.springframework.boot:spring-boot-starter-security'

2.2 基本配置

創(chuàng)建一個配置類繼承 WebSecurityConfigurerAdapter

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/", "/home").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }
    @Bean
    @Override
    public UserDetailsService userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
            .username("user")
            .password("password")
            .roles("USER")
            .build();
        return new InMemoryUserDetailsManager(user);
    }
}

3. 詳細(xì)配置

3.1 認(rèn)證配置

內(nèi)存認(rèn)證

WebSecurityConfigurerAdapter.java

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth
        .inMemoryAuthentication()
            .withUser("user").password("{noop}password").roles("USER")
            .and()
            .withUser("admin").password("{noop}admin").roles("ADMIN");
}

JDBC 認(rèn)證(可選)

WebSecurityConfigurerAdapter.java

@Autowired
private DataSource dataSource;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth
        .jdbcAuthentication()
            .dataSource(dataSource)
            .usersByUsernameQuery("select username,password,enabled from users where username=?")
            .authoritiesByUsernameQuery("select username,authority from authorities where username=?");
}

自定義 UserDetailsService

@Service
public class CustomUserDetailsService implements UserDetailsService {
    @Autowired
    private UserRepository userRepository;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username)
            .orElseThrow(() -> new UsernameNotFoundException("User not found"));
        return new org.springframework.security.core.userdetails.User(
            user.getUsername(), 
            user.getPassword(), 
            getAuthorities(user.getRoles()));
    }
    private Collection<? extends GrantedAuthority> getAuthorities(Collection<Role> roles) {
        return roles.stream()
            .map(role -> new SimpleGrantedAuthority(role.getName()))
            .collect(Collectors.toList());
    }
}

3.2 授權(quán)配置

WebSecurityConfigurerAdapter.java

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
            .antMatchers("/public/**").permitAll()
            .anyRequest().authenticated()
        .and()
        .formLogin()
            .loginPage("/login")
            .defaultSuccessUrl("/dashboard")
            .failureUrl("/login?error=true")
            .permitAll()
        .and()
        .logout()
            .logoutUrl("/logout")
            .logoutSuccessUrl("/login?logout=true")
            .invalidateHttpSession(true)
            .deleteCookies("JSESSIONID")
            .permitAll()
        .and()
        .rememberMe()
            .key("uniqueAndSecret")
            .tokenValiditySeconds(86400);
}

3.3 密碼加密

推薦使用 BCrypt 密碼編碼器:
WebSecurityConfigurerAdapter.java

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

然后在用戶注冊時加密密碼:
WebSecurityConfigurerAdapter.java

@Autowired
private PasswordEncoder passwordEncoder;
public void registerUser(User user) {
    user.setPassword(passwordEncoder.encode(user.getPassword()));
    userRepository.save(user);
}

4. 高級特性

4.1 CSRF 防護(hù)

Spring Security 默認(rèn)啟用 CSRF 防護(hù)。在表單中添加 CSRF 令牌:

<form method="post">
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
    <!-- 其他表單字段 -->
</form>

或者在 AJAX 請求中添加:

var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$(document).ajaxSend(function(e, xhr, options) {
    xhr.setRequestHeader(header, token);
});

4.2 方法級安全

啟用方法級安全:

@Configuration
@EnableGlobalMethodSecurity(
    prePostEnabled = true,
    securedEnabled = true,
    jsr250Enabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
}

然后在方法上使用注解:

@PreAuthorize("hasRole('ADMIN')")
public void deleteUser(Long userId) {
    // ...
}
@PostAuthorize("returnObject.owner == authentication.name")
public Document getDocument(Long docId) {
    // ...
}
@Secured("ROLE_ADMIN")
public void updateUser(User user) {
    // ...
}

4.3 OAuth2 集成

添加依賴:

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

配置 OAuth2 客戶端:

spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: your-client-id
            client-secret: your-client-secret
            scope: email, profile

4.4 JWT 集成

添加依賴:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

創(chuàng)建 JWT 工具類:

public class JwtTokenUtil {
    private String secret = "your-secret-key";
    private long expiration = 86400000; // 24小時
    public String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        return Jwts.builder()
            .setClaims(claims)
            .setSubject(userDetails.getUsername())
            .setIssuedAt(new Date())
            .setExpiration(new Date(System.currentTimeMillis() + expiration))
            .signWith(SignatureAlgorithm.HS512, secret)
            .compact();
    }
    public Boolean validateToken(String token, UserDetails userDetails) {
        final String username = getUsernameFromToken(token);
        return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
    }
    // 其他工具方法...
}

配置 JWT 過濾器:

public class JwtRequestFilter extends OncePerRequestFilter {
    @Autowired
    private CustomUserDetailsService userDetailsService;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
        final String authorizationHeader = request.getHeader("Authorization");
        String username = null;
        String jwt = null;
        if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
            jwt = authorizationHeader.substring(7);
            username = jwtTokenUtil.getUsernameFromToken(jwt);
        }
        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
            if (jwtTokenUtil.validateToken(jwt, userDetails)) {
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                    userDetails, null, userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }
        chain.doFilter(request, response);
    }
}

在安全配置中添加過濾器:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .authorizeRequests()
            .antMatchers("/authenticate").permitAll()
            .anyRequest().authenticated()
        .and()
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}

5. 測試安全配置

5.1 測試控制器

@RestController
public class TestController {
    @GetMapping("/admin")
    @PreAuthorize("hasRole('ADMIN')")
    public String adminAccess() {
        return "Admin Board";
    }
    @GetMapping("/user")
    @PreAuthorize("hasRole('USER') or hasRole('ADMIN')")
    public String userAccess() {
        return "User Content";
    }
    @GetMapping("/all")
    public String allAccess() {
        return "Public Content";
    }
}

5.2 測試安全配置

@SpringBootTest
@AutoConfigureMockMvc
public class SecurityTest {
    @Autowired
    private MockMvc mockMvc;
    @Test
    @WithMockUser(username = "user", roles = {"USER"})
    public void givenUserRole_whenAccessUserEndpoint_thenOk() throws Exception {
        mockMvc.perform(get("/user"))
            .andExpect(status().isOk());
    }
    @Test
    @WithMockUser(username = "user", roles = {"USER"})
    public void givenUserRole_whenAccessAdminEndpoint_thenForbidden() throws Exception {
        mockMvc.perform(get("/admin"))
            .andExpect(status().isForbidden());
    }
    @Test
    public void givenUnauthenticated_whenAccessPublicEndpoint_thenOk() throws Exception {
        mockMvc.perform(get("/all"))
            .andExpect(status().isOk());
    }
}

6. 最佳實(shí)踐

  1. 最小權(quán)限原則:只授予必要的權(quán)限
  2. 密碼安全:始終使用強(qiáng)密碼哈希算法(如 BCrypt)
  3. HTTPS:在生產(chǎn)環(huán)境中強(qiáng)制使用 HTTPS
  4. 安全頭:啟用安全頭(如 X-Frame-Options, X-XSS-Protection 等)
  5. 定期更新:保持 Spring Security 版本更新
  6. 審計日志:記錄重要的安全事件
  7. 輸入驗(yàn)證:不要依賴 Spring Security 進(jìn)行所有輸入驗(yàn)證

7. 常見問題解決

7.1 自定義登錄頁面

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()
            .antMatchers("/login*").permitAll()
            .anyRequest().authenticated()
        .and()
        .formLogin()
            .loginPage("/login.html")
            .loginProcessingUrl("/perform_login")
            .defaultSuccessUrl("/home.html", true)
            .failureUrl("/login.html?error=true");
}

7.2 處理 AccessDeniedException

創(chuàng)建自定義訪問拒絕處理器:

@Component
public class CustomAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response,
            AccessDeniedException accessDeniedException) throws IOException, ServletException {
        response.sendRedirect(request.getContextPath() + "/access-denied");
    }
}

然后在配置中使用:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .exceptionHandling()
            .accessDeniedHandler(accessDeniedHandler);
}

7.3 多 HTTP 安全配置

@Configuration
@Order(1)
public class ApiSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .antMatcher("/api/**")
            .authorizeRequests()
                .anyRequest().hasRole("API_USER")
            .and()
            .httpBasic();
    }
}
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
            .and()
            .formLogin();
    }
}

8. 總結(jié)

Spring Security 是一個功能全面且靈活的安全框架,本教程涵蓋了從基礎(chǔ)配置到高級特性的主要內(nèi)容。實(shí)際應(yīng)用中,應(yīng)根據(jù)具體需求選擇合適的認(rèn)證和授權(quán)方式,并遵循安全最佳實(shí)踐。

對于更復(fù)雜的場景,建議參考 Spring Security 官方文檔 和社區(qū)資源。

到此這篇關(guān)于Java中Spring Security的使用的文章就介紹到這了,更多相關(guān)Spring Security使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Mybatis-plus插入數(shù)據(jù)遇到主鍵沒有默認(rèn)值的情況

    Mybatis-plus插入數(shù)據(jù)遇到主鍵沒有默認(rèn)值的情況

    這篇文章主要介紹了Mybatis-plus插入數(shù)據(jù)遇到主鍵沒有默認(rèn)值的情況,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • springboot yml中profiles的巧妙用法(小白必看多環(huán)境配置)

    springboot yml中profiles的巧妙用法(小白必看多環(huán)境配置)

    這篇文章主要介紹了springboot yml中profiles的巧妙用法,非常適合多環(huán)境配置場景,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • Java模擬rank/over函數(shù)實(shí)現(xiàn)獲取分組排名的方法詳解

    Java模擬rank/over函數(shù)實(shí)現(xiàn)獲取分組排名的方法詳解

    這篇文章主要為大家詳細(xì)介紹了Java模擬rank()、over()函數(shù)獲取分組排名的方法設(shè)計及實(shí)現(xiàn),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2023-04-04
  • springboot啟動bat/bash腳本實(shí)現(xiàn)過程

    springboot啟動bat/bash腳本實(shí)現(xiàn)過程

    請?zhí)峁┚唧w錯誤信息或腳本內(nèi)容,以便分析Spring Boot項(xiàng)目中Controller、Entity、Service層的依賴問題,跨平臺腳本需注意路徑兼容性和環(huán)境變量配置,確保依賴項(xiàng)正確引入
    2025-08-08
  • 老生常談java中cookie的使用

    老生常談java中cookie的使用

    下面小編就為大家?guī)硪黄仙U刯ava中cookie的使用。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-12-12
  • SpringBoot使用Docx4j實(shí)現(xiàn)DOCX轉(zhuǎn)PDF功能

    SpringBoot使用Docx4j實(shí)現(xiàn)DOCX轉(zhuǎn)PDF功能

    在當(dāng)今的企業(yè)級應(yīng)用中,文檔格式轉(zhuǎn)換是一個高頻但又容易被低估的需求,從合同簽署、報表生成到知識庫管理,DOCX轉(zhuǎn)PDF的需求無處不在,今天我們就介紹一款使用純Java實(shí)現(xiàn) DOCX 轉(zhuǎn) PDF的方案,超級簡單,簡直不要太爽,需要的朋友可以參考下
    2026-02-02
  • Mybatis-plus如何開啟二級緩存

    Mybatis-plus如何開啟二級緩存

    這篇文章主要介紹了Mybatis-plus如何開啟二級緩存問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • java中抽象類和接口的相同和不同點(diǎn)介紹

    java中抽象類和接口的相同和不同點(diǎn)介紹

    大家好,本篇文章主要講的是java中抽象類和接口的相同和不同點(diǎn)介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • Spring boot 4 搞懂MyBatis-Plus的用法解析

    Spring boot 4 搞懂MyBatis-Plus的用法解析

    MyBatis-Plus是MyBatis的增強(qiáng)工具,提供了CRUD操作和自動填充等功能,通過繼承BaseMapper接口,可以快速實(shí)現(xiàn)數(shù)據(jù)庫操作,MyBatis-Plus提供了多種插件,如分頁、樂觀鎖、多租戶等,以增強(qiáng)系統(tǒng)的功能和性能,本文介紹Spring boot 4 搞懂MyBatis-Plus的用法,感興趣的朋友一起看看吧
    2026-01-01
  • Java中@DateTimeFormat和@JsonFormat注解介紹

    Java中@DateTimeFormat和@JsonFormat注解介紹

    @DateTimeFormat和@JsonFormat都是處理時間格式化問題的,把其他類型轉(zhuǎn)換成自己需要的時間類型,下面這篇文章主要給大家介紹了關(guān)于Java中@DateTimeFormat和@JsonFormat注解介紹的相關(guān)資料,需要的朋友可以參考下
    2022-11-11

最新評論

阜阳市| 天祝| 方城县| 海宁市| 临沂市| 鱼台县| 北流市| 海口市| 阳东县| 汶上县| 黄石市| 乾安县| 通州区| 岐山县| 广南县| 呼和浩特市| 漠河县| 大连市| 札达县| 金塔县| 宝坻区| 北海市| 长宁区| 临夏市| 安宁市| 宜城市| 青海省| 繁昌县| 南郑县| 象州县| 吉林省| 湘潭县| 杂多县| 萝北县| 安阳市| 富裕县| 泸定县| 皮山县| 乌拉特前旗| 甘洛县| 通州区|