基于Keycloak 22与Spring Boot 3.1,如何用OAuth2AuthorizationRequestRedirectFilter拦截请求?
要在请求跳转到Keycloak之前拦截授权URL,你可以通过自定义OAuth2AuthorizationRequestRedirectFilter子类实现,这个过滤器是Spring Security OAuth2中负责将用户重定向到授权服务器(Keycloak)的核心组件。以下是完整实现示例:
1. 自定义拦截过滤器
继承OAuth2AuthorizationRequestRedirectFilter,重写sendRedirect方法——这是触发跳转前的最后拦截点,你可以在这里添加自定义逻辑:
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; public class CustomKeycloakRedirectFilter extends OAuth2AuthorizationRequestRedirectFilter { public CustomKeycloakRedirectFilter(OAuth2AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository) { super(authorizationRequestRepository); } @Override protected void sendRedirect(HttpServletRequest request, HttpServletResponse response, String redirectUri) throws IOException { // 拦截逻辑示例1:打印即将跳转的Keycloak授权URL System.out.println("即将跳转至Keycloak授权端点: " + redirectUri); // 拦截逻辑示例2:修改授权URL参数(比如添加自定义参数) // String modifiedUri = redirectUri + (redirectUri.contains("?") ? "&" : "?") + "custom_param=my_value"; // 拦截逻辑示例3:自定义校验,不满足则阻止跳转 // if (!validateRequest(request)) { // response.sendError(HttpServletResponse.SC_FORBIDDEN, "无权访问Keycloak授权"); // return; // } // 执行默认跳转逻辑(如果修改了URL,就传入modifiedUri) super.sendRedirect(request, response, redirectUri); } // 可选:自定义请求校验方法 private boolean validateRequest(HttpServletRequest request) { // 这里可以添加你的校验逻辑,比如检查请求来源、用户状态等 return true; } }
2. 配置Spring Security替换默认过滤器
在Spring Security配置类中,将自定义过滤器注册到OAuth2登录流程的授权端点,替换默认的过滤器:
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.oauth2.client.web.AuthorizationRequestRepository; import org.springframework.security.oauth2.client.web.HttpSessionOAuth2AuthorizationRequestRepository; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; @Configuration @EnableWebSecurity public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .anyRequest().authenticated() ) .oauth2Login(oauth2 -> oauth2 .authorizationEndpoint(authEndpoint -> authEndpoint // 指定授权请求的存储仓库 .authorizationRequestRepository(authorizationRequestRepository()) // 替换为自定义的跳转过滤器 .authorizationRequestRedirectFilter(customKeycloakRedirectFilter()) ) ) .exceptionHandling(ex -> ex .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/oauth2/authorization/keycloak")) ); return http.build(); } @Bean public AuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository() { // 使用HttpSession存储授权请求 return new HttpSessionOAuth2AuthorizationRequestRepository(); } @Bean public CustomKeycloakRedirectFilter customKeycloakRedirectFilter() { return new CustomKeycloakRedirectFilter(authorizationRequestRepository()); } }
关键说明
sendRedirect方法是拦截跳转的核心时机:在调用父类的sendRedirect前,你可以完全控制是否跳转、修改跳转URL、添加业务校验等。- 版本适配:Spring Boot 3.1搭配的Spring Security 6.1使用Jakarta Servlet API(取代了旧的javax),所以代码中导入的是
jakarta.servlet.http.*包。 - 如果需要更深度定制授权请求(比如修改scope、clientId等),可以重写
buildAuthorizationRequest方法,直接操作OAuth2AuthorizationRequest对象。
内容的提问来源于stack exchange,提问作者user3648235
相关产品推荐
相关产品推荐

