偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

五種方案!保護(hù)Spring Boot API接口安全

開(kāi)發(fā) 前端
Filter 是 Java Servlet 規(guī)范中的一個(gè)組件,可以在請(qǐng)求到達(dá) Servlet 之前或響應(yīng)返回客戶端之前對(duì)請(qǐng)求和響應(yīng)進(jìn)行攔截和處理。通過(guò)在 Filter 中實(shí)現(xiàn)權(quán)限認(rèn)證邏輯,可以有效地控制用戶對(duì) API 接口的訪問(wèn)權(quán)限。

環(huán)境:SpringBoot3.4.2

1. 簡(jiǎn)介

API是系統(tǒng)核心數(shù)據(jù)的出入口,必須防止未授權(quán)訪問(wèn)、數(shù)據(jù)泄露、惡意攻擊等風(fēng)險(xiǎn)。例如:

  • 防止游客查看敏感數(shù)據(jù)(如用戶信息)
  • 阻止越權(quán)操作(如普通用戶刪除管理員數(shù)據(jù))
  • 抵御惡意刷接口或注入攻擊

合理的權(quán)限控制能確保數(shù)據(jù)安全、系統(tǒng)穩(wěn)定,并符合合規(guī)要求。

接下來(lái)我將詳細(xì)的介紹 5 種簡(jiǎn)單好用的保護(hù)方案,讓你能輕松搞定 API 接口安全。

以下是本篇文章要實(shí)現(xiàn)的5種方案:

  • 通過(guò)Filter實(shí)現(xiàn)
  • 使用Interceptor攔截器實(shí)現(xiàn)
  • 基于AOP+Filter實(shí)現(xiàn)
  • 使用Spring Security實(shí)現(xiàn)
  • 整合OAuth2認(rèn)證

2.實(shí)戰(zhàn)案例

準(zhǔn)備如下Controller接口

@RestController
public class ApiController {
  @GetMapping("/api/query")
  public ResponseEntity<?> query() {
    System.err.println(SecurityContext.get()) ;
    return ResponseEntity.ok("query...") ;
  }


  @GetMapping("/create")
  public ResponseEntity<?> create() {
    return ResponseEntity.ok("create...") ;
  }
}

這里提供了2個(gè)接口。其中,/api/query是需要認(rèn)證的接口,/create無(wú)需認(rèn)證,可直接訪問(wèn)。

2.1 通過(guò)Filter實(shí)現(xiàn)

Filter 是 Java Servlet 規(guī)范中的一個(gè)組件,可以在請(qǐng)求到達(dá) Servlet 之前或響應(yīng)返回客戶端之前對(duì)請(qǐng)求和響應(yīng)進(jìn)行攔截和處理。通過(guò)在 Filter 中實(shí)現(xiàn)權(quán)限認(rèn)證邏輯,可以有效地控制用戶對(duì) API 接口的訪問(wèn)權(quán)限。

代碼實(shí)現(xiàn):

@WebFilter("/api/*")
public class JwtAuthFilter implements Filter {
  @Override
  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain)
      throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) req ;
    HttpServletResponse response = (HttpServletResponse) resp ;
    try {
      // 從請(qǐng)求header中讀取token
      String token = JwtUtil.extractToken(request) ;
      // 驗(yàn)證token & 將從token中解析出的數(shù)據(jù)保存到線程上下文中
      if (token != null && JwtUtil.validateToken(token)) {
        Map<String, Object> data = JwtUtil.parseToken(token) ;
        SecurityContext.set(data) ;
        filterChain.doFilter(request, resp) ;
      } else {
        // 認(rèn)證失敗,則直接輸出錯(cuò)誤內(nèi)容
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().println(new ObjectMapper()
            .writeValueAsString(Map.of("code", -1, "msg", "無(wú)效token"))) ;
        return ;
      }
    } finally {
      SecurityContext.clear() ;
    }
  }
}

此過(guò)濾器將只攔截 /api 開(kāi)頭的請(qǐng)求。

運(yùn)行結(jié)果

圖片圖片

圖片圖片

提供正確的token再次訪問(wèn)

圖片圖片

2.2 使用Interceptor攔截器

HandlerInterceptor 是 Spring MVC 提供的一個(gè)接口,可以在請(qǐng)求處理前后進(jìn)行攔截。通過(guò)實(shí)現(xiàn)其 preHandle 方法,可以在請(qǐng)求到達(dá)控制器之前進(jìn)行權(quán)限驗(yàn)證,決定是否允許請(qǐng)求繼續(xù)執(zhí)行。

代碼實(shí)現(xiàn):

@Component
public class AuthInterceptor implements HandlerInterceptor {
  private final ObjectMapper objectMapper ;
  public AuthInterceptor(ObjectMapper objectMapper) {
    this.objectMapper = objectMapper ;
  }
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    String token = JwtUtil.extractToken(request) ;
    if (token != null && JwtUtil.validateToken(token)) {
      Map<String, Object> data = JwtUtil.parseToken(token) ;
      SecurityContext.set(data) ;
      return true ;
    } else {
      response.setContentType("application/json;charset=utf-8");
      response.getWriter().println(objectMapper
          .writeValueAsString(Map.of("code", -1, "msg", "無(wú)效token"))) ;
      return false ;
    }
  }
  @Override
  public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
      throws Exception {
    SecurityContext.clear() ;
  }
}

注冊(cè)攔截器

@Component
public class WebConfig implements WebMvcConfigurer {
  private final AuthInterceptor authInterceptor ;
  public WebConfig(AuthInterceptor authInterceptor) {
    this.authInterceptor = authInterceptor;
  }
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(this.authInterceptor).addPathPatterns("/api/**") ;
  }
}

注意:不要忘記在攔截器的 afterCompletion 中進(jìn)行上下文的清理。

2.3 使用AOP + Filter實(shí)現(xiàn)

AOP用于定義權(quán)限驗(yàn)證的切面邏輯,F(xiàn)ilter 則用于攔截請(qǐng)求并解析處理Token。這種組合方式能夠在請(qǐng)求處理的不同階段進(jìn)行權(quán)限控制,既靈活又高效,適合在需要復(fù)雜權(quán)限管理。

代碼實(shí)現(xiàn):

Filter實(shí)現(xiàn)

@WebFilter("/*")
public class TokenFilter implements Filter {
  @Override
  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain)
      throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) req ;
    try {
      String token = JwtUtil.extractToken(request) ;
      if (token != null && JwtUtil.validateToken(token)) {
        Map<String, Object> data = JwtUtil.parseToken(token) ;
        SecurityContext.set(data) ;
      }
      filterChain.doFilter(request, resp) ;
    } finally {
      SecurityContext.clear() ;
    }
  }
}

AOP切面實(shí)現(xiàn)

// 自定義注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PermissionCheck {


  String[] value() default {} ;
}
// 切面定義
@Aspect
@Component
public class PermissionAspect {
  @SuppressWarnings("unchecked")
  @Around("@annotation(permissionCheck)")
  public Object checkPermission(ProceedingJoinPoint joinPoint, PermissionCheck permissionCheck) throws Throwable {
    try {
      Map<String, Object> data = SecurityContext.get() ;
      if (data == null) {
        throw new PermissionException("無(wú)權(quán)限訪問(wèn)", 403) ;
      }
      // 獲取所需角色
      String[] requiredRoles = permissionCheck.value() ;
      // 用戶所擁有的角色
      List<String> assignedRoles = (List<String>) data.get("roles") ; 
      // 判斷2個(gè)集合如果沒(méi)有共同元素則返回true
      if (Collections.disjoint(List.of(requiredRoles), assignedRoles)) {
        throw new PermissionException("無(wú)權(quán)限訪問(wèn)", 403) ;
      }
      // 繼續(xù)執(zhí)行方法
      return joinPoint.proceed();
    } catch (Exception e) {
      e.printStackTrace() ; 
      throw new PermissionException("Token無(wú)效或過(guò)期", 401) ;
    }
  }
}

修改Controller接口

@GetMapping("/api/query")
@PermissionCheck({"api:query"})
public ResponseEntity<?> query() {
  return ResponseEntity.ok("query...") ;
}

2.4 使用Spring Security

Spring Security 是 Spring 生態(tài)中的安全框架,提供了豐富的權(quán)限控制功能,包括身份認(rèn)證、授權(quán)、密碼加密等。通過(guò)配置安全規(guī)則和過(guò)濾器鏈,可以輕松實(shí)現(xiàn)細(xì)粒度的權(quán)限控制。

代碼實(shí)現(xiàn):

首先,引入依賴

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

最后,安全配置

@Configuration
public class SecurityConfig {
  @Bean
  SecurityFilterChain apiSecurity(HttpSecurity http) throws Throwable {
    http.csrf(csrf -> csrf.disable()) ;
    http.securityMatcher("/api/**", "/login") ;
    http.formLogin(Customizer.withDefaults()) ;
    http.authorizeHttpRequests(registry -> {
      registry.anyRequest().authenticated() ;
    }) ;
    return http.build() ;
  }
  // 實(shí)際我們應(yīng)該從數(shù)據(jù)庫(kù)中查詢,這里為了簡(jiǎn)單直接固定一個(gè)內(nèi)存用戶
  @Bean
  UserDetailsService userDetailsService() {
    UserDetails user = User.withUsername("pack")
      .password("{noop}123123")
      .roles("ADMIN")
      .build() ;
    return new InMemoryUserDetailsManager(user) ;
  }
}

在上面的SecurityFilterChain配置中,我們將只會(huì)對(duì)/api/*,/login接口進(jìn)行攔截。如果沒(méi)有權(quán)限將會(huì)自動(dòng)定向到登錄頁(yè)面。

當(dāng)訪問(wèn)/api/query接口時(shí),自動(dòng)跳轉(zhuǎn)到登錄頁(yè)面:

圖片圖片

輸入正確的用戶名密碼后,自動(dòng)跳回之前的接口地址

圖片圖片

責(zé)任編輯:武曉燕 來(lái)源: Springboot全家桶實(shí)戰(zhàn)案例源碼
相關(guān)推薦

2025-02-12 08:47:07

SpringAPI接口

2025-02-13 07:45:26

APISpringHTTP

2024-08-29 09:01:39

2021-09-18 10:06:06

數(shù)據(jù)安全隱私計(jì)算大數(shù)據(jù)

2025-06-30 01:45:00

2025-03-31 08:39:55

2023-10-16 11:12:29

2025-04-30 08:39:33

SpringMVC接口

2022-07-04 07:41:53

接口數(shù)據(jù)安全

2024-03-14 12:00:52

2023-05-17 13:46:14

2025-05-14 04:00:00

2025-06-09 01:22:00

2024-09-26 08:03:37

2024-09-29 09:31:08

Spring前綴URL

2025-03-12 02:00:55

API接口優(yōu)化

2011-05-18 14:10:18

敏感數(shù)據(jù)安全數(shù)據(jù)泄漏

2022-06-30 05:35:33

API網(wǎng)絡(luò)安全

2010-09-26 10:41:31

2024-09-03 13:59:37

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)