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

Spring Boot前后端分离架构下存储请求URL解决授权重定向问题

解决方案:存储原请求URL并实现自定义重定向

核心思路

由于授权服务器固定重定向到前端仪表盘,我们需要在用户触发认证跳转前拦截请求,保存原请求URL;待授权服务器回调至仪表盘时,读取保存的URL完成二次跳转,同时确保令牌能正常用于后端通信。

具体实现步骤

1. 拦截未认证请求,存储原URL

通过Spring Security的AuthenticationEntryPoint自定义认证入口,在跳转授权服务器前将原请求URL存入会话:

@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        // 排除授权回调端点,避免误存回调URL
        if (!request.getRequestURI().equals("/oauth2/callback")) {
            // 拼接完整请求URL(含参数)并存入session
            String fullUrl = request.getRequestURL().append("?").append(request.getQueryString()).toString();
            request.getSession().setAttribute("ORIGINAL_REQUEST_URL", fullUrl);
        }
        // 重定向到授权服务器认证端点
        response.sendRedirect("/oauth2/authorization/your-provider-id");
    }
}

在Spring Security配置中注册该入口:

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    private final CustomAuthenticationEntryPoint customAuthenticationEntryPoint;

    public SecurityConfig(CustomAuthenticationEntryPoint customAuthenticationEntryPoint) {
        this.customAuthenticationEntryPoint = customAuthenticationEntryPoint;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
            .oauth2Login(oauth2 -> oauth2.defaultSuccessUrl("/dashboard")) // 授权服务器固定回调至仪表盘
            .exceptionHandling(ex -> ex.authenticationEntryPoint(customAuthenticationEntryPoint));
        return http.build();
    }
}

2. 在仪表盘端点处理二次重定向

授权回调至/dashboard时,读取会话中存储的原URL,存在则跳转至该URL,否则停留仪表盘:

@Controller
public class DashboardController {
    @GetMapping("/dashboard")
    public String dashboard(HttpServletRequest request) {
        String originalUrl = (String) request.getSession().getAttribute("ORIGINAL_REQUEST_URL");
        if (originalUrl != null) {
            // 清除session中的存储,避免重复跳转
            request.getSession().removeAttribute("ORIGINAL_REQUEST_URL");
            return "redirect:" + originalUrl;
        }
        return "dashboard";
    }
}

3. 令牌用于后端通信的处理

Spring Security OAuth2客户端会自动管理令牌的获取与存储,调用后端接口时可通过注解直接注入授权客户端,携带令牌发起请求:

@RestController
public class BackendApiClient {
    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/fetch-backend-data")
    public ResponseEntity<String> fetchData(@RegisteredOAuth2AuthorizedClient("your-provider-id") OAuth2AuthorizedClient client) {
        String token = client.getAccessToken().getTokenValue();
        HttpHeaders headers = new HttpHeaders();
        headers.setBearerAuth(token);
        HttpEntity<String> entity = new HttpEntity<>(headers);
        return restTemplate.exchange("http://backend-service/api/data", HttpMethod.GET, entity, String.class);
    }
}

注意事项

  • 集群部署时需使用Redis等分布式会话存储,避免原URL丢失。
  • 若原请求URL包含敏感参数,需过滤敏感字段后再存储,或加密存储。
  • 需确保授权回调端点被正确排除,防止误存回调URL。

内容的提问来源于stack exchange,提问作者Syed Iftekharuddin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 05:32:20