You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring框架中为指定请求添加Authorization Token请求头

Hey there! Great job getting the token generation set up for your social media API—you’re already making solid progress on securing it. To answer your core question: yes, totally feasible to require an Authorization Header for specific endpoints while leaving others (like login/signup) open. Let’s break down how to implement this cleanly in Spring, whether you want to use Spring Security’s built-in tools or your custom validation function.

1. First, Add Spring Security Dependencies

If you haven’t already, include the Spring Security starter in your project. This gives you all the tools to handle authentication rules and filters.

For Maven, add this to your pom.xml:

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

For Gradle, add this to your build.gradle:

implementation 'org.springframework.boot:spring-boot-starter-security'
2. Configure Which Endpoints Need Authentication

Create a security configuration class to define which endpoints are public (no auth needed) and which require a valid token. Here’s how to do it with modern Spring Security (using SecurityFilterChain instead of the old WebSecurityConfigurerAdapter):

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.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            // Disable CSRF since we're building an API (not a web app with form submissions)
            .csrf().disable()
            // Define authorization rules
            .authorizeHttpRequests(auth -> auth
                // Allow everyone to access login/register endpoints
                .antMatchers("/api/auth/login", "/api/auth/register").permitAll()
                // Require authentication for search endpoints
                .antMatchers("/api/search/**").authenticated()
                // Optional: Require auth for all other endpoints (adjust based on your needs)
                .anyRequest().authenticated()
            );
        
        return http.build();
    }
}
3. Implement Your Custom Token Validation Logic

Since you already have token generation working, you’ll need a way to validate those tokens on protected endpoints. The cleanest way is to create a custom filter that runs before Spring Security’s default filters. This filter will check for the Authorization Header, validate the token, and set the user’s authentication status if the token is valid.

Here’s a sample filter:

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;

public class TokenValidationFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // Extract the Authorization header from the request
        String authHeader = request.getHeader("Authorization");
        String requestPath = request.getRequestURI();

        // Skip validation for public endpoints (login/register)
        if (requestPath.startsWith("/api/auth/login") || requestPath.startsWith("/api/auth/register")) {
            filterChain.doFilter(request, response);
            return;
        }

        // Validate the header format (should be "Bearer <token>")
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Missing or invalid Authorization header");
            return;
        }

        // Extract the token from the header
        String token = authHeader.substring(7); // Remove "Bearer " prefix

        // Run your custom token validation logic
        if (!isValidToken(token)) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid or expired token");
            return;
        }

        // If token is valid, set the user's authentication in Spring's security context
        // Replace getUsernameFromToken with your method to extract user info from the token
        String username = getUsernameFromToken(token);
        UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
                username, null, new ArrayList<>() // Add roles/permissions here if you need them
        );
        SecurityContextHolder.getContext().setAuthentication(authToken);

        // Continue processing the request
        filterChain.doFilter(request, response);
    }

    // Your custom token validation method (replace with your actual logic)
    private boolean isValidToken(String token) {
        // Example checks:
        // 1. Verify the token's signature (if using JWT)
        // 2. Check if the token is not expired
        // 3. Confirm the token exists in your database (if you're storing active tokens)
        return true; // Replace with real validation logic
    }

    // Your method to extract the username (or user ID) from the token
    private String getUsernameFromToken(String token) {
        // Example: Parse the token's claims to get the username
        return "user123"; // Replace with real extraction logic
    }
}

Then, add this filter to your SecurityConfig so it runs before Spring’s default authentication filter:

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            // Add your custom token filter before the default username/password filter
            .addFilterBefore(tokenValidationFilter(), UsernamePasswordAuthenticationFilter.class)
            .authorizeHttpRequests(auth -> auth
                .antMatchers("/api/auth/login", "/api/auth/register").permitAll()
                .antMatchers("/api/search/**").authenticated()
                .anyRequest().authenticated()
            );
        
        return http.build();
    }

    @Bean
    public TokenValidationFilter tokenValidationFilter() {
        return new TokenValidationFilter();
    }
}
4. Test Your Setup
  • Public endpoints: Send a POST to /api/auth/login or /api/auth/register without an Authorization Header—this should work and return your token.
  • Protected endpoints: Send a request to /api/search with Authorization: Bearer <your-generated-token> in the headers. If the token is valid, you’ll get a normal response. If not, you’ll get a 401 Unauthorized error.
Quick Tips for Improvement
  • If you’re using JWT tokens, consider using a library like JJWT to simplify token generation and validation (instead of writing all the crypto logic yourself).
  • Store tokens securely: For frontend clients, prefer HttpOnly cookies over localStorage to reduce XSS risks (though Bearer tokens are standard for API-only setups).
  • Add role-based access control later: If you need to restrict certain endpoints to admins, you can add roles to the UsernamePasswordAuthenticationToken and use .hasRole("ADMIN") in your security rules.

内容的提问来源于stack exchange,提问作者K. Janjuha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:43:35