Spring Security OAuth2客户端:如何获取Quickbooks授权返回的realmId?
Spring Boot OAuth2对接Quickbooks获取realmId的解决方案
方法一:自定义授权成功处理器提取realmId
Spring Security的OAuth2登录流程中,授权成功后的回调请求会携带realmId参数,可通过自定义OAuth2AuthorizationSuccessHandler拦截请求并提取参数:
- 实现
OAuth2AuthorizationSuccessHandler接口,在方法中提取realmId并存储:
@Component public class QuickbooksOAuth2SuccessHandler implements OAuth2AuthorizationSuccessHandler { private final OAuth2AuthorizationSuccessHandler defaultHandler; public QuickbooksOAuth2SuccessHandler(OAuth2AuthorizationSuccessHandler defaultHandler) { this.defaultHandler = defaultHandler; } @Override public void onAuthorizationSuccess(OAuth2AuthorizationRequest authorizationRequest, OAuth2AuthorizationResponse authorizationResponse, Authentication authentication, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String realmId = request.getParameter("realmId"); if (StringUtils.hasText(realmId)) { // 可存入会话、数据库,或与用户信息关联存储 request.getSession().setAttribute("quickbooks_realm_id", realmId); } // 调用默认处理器完成后续流程 defaultHandler.onAuthorizationSuccess(authorizationRequest, authorizationResponse, authentication, request, response); } }
- 在Security配置中绑定自定义处理器:
@Configuration @EnableWebSecurity public class SecurityConfig { @Autowired private QuickbooksOAuth2SuccessHandler quickbooksOAuth2SuccessHandler; @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) .oauth2Login(oauth2 -> oauth2 .successHandler(quickbooksOAuth2SuccessHandler) ); return http.build(); } }
方法二:自定义授权请求解析器捕获参数
扩展OAuth2AuthorizationRequestResolver,在解析授权响应时提取realmId:
- 实现自定义解析器:
@Component public class QuickbooksAuthorizationRequestResolver implements OAuth2AuthorizationRequestResolver { private final OAuth2AuthorizationRequestResolver defaultResolver; public QuickbooksAuthorizationRequestResolver(OAuth2AuthorizationRequestResolver defaultResolver) { this.defaultResolver = defaultResolver; } @Override public OAuth2AuthorizationRequest resolve(HttpServletRequest request) { OAuth2AuthorizationRequest authorizationRequest = defaultResolver.resolve(request); if (authorizationRequest != null && request.getParameter("realmId") != null) { String realmId = request.getParameter("realmId"); request.setAttribute("quickbooks_realm_id", realmId); } return authorizationRequest; } @Override public OAuth2AuthorizationRequest resolve(HttpServletRequest request, String clientRegistrationId) { OAuth2AuthorizationRequest authorizationRequest = defaultResolver.resolve(request, clientRegistrationId); if (authorizationRequest != null && request.getParameter("realmId") != null) { String realmId = request.getParameter("realmId"); request.setAttribute("quickbooks_realm_id", realmId); } return authorizationRequest; } }
- 在Security配置中替换默认解析器:
@Configuration @EnableWebSecurity public class SecurityConfig { @Autowired private QuickbooksAuthorizationRequestResolver quickbooksAuthorizationRequestResolver; @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) .oauth2Login(oauth2 -> oauth2 .authorizationEndpoint(authEndpoint -> authEndpoint .authorizationRequestResolver(quickbooksAuthorizationRequestResolver) ) ); return http.build(); } }
方法三:自定义回调Controller直接提取
配置自定义回调路径,在Controller中直接获取realmId:
- 编写回调Controller:
@Controller public class OAuth2CallbackController { @GetMapping("/oauth2/callback/quickbooks") public String callback(@RequestParam String code, @RequestParam String state, @RequestParam String realmId, HttpServletRequest request) { request.getSession().setAttribute("quickbooks_realm_id", realmId); // 转发到Spring Security默认处理路径完成token交换 return "forward:/login/oauth2/code/quickbooks"; } }
- 修改配置文件中的回调地址:
spring: security: oauth2: client: registration: quickbooks: redirect-uri: "{baseUrl}/oauth2/callback/quickbooks"
后续使用realmId
提取到realmId后,可在业务逻辑中取出使用:
@Service public class QuickbooksService { public void callQuickbooksApi(OAuth2AuthorizedClient client, HttpServletRequest request) { String realmId = (String) request.getSession().getAttribute("quickbooks_realm_id"); String apiUrl = "https://quickbooks.api.intuit.com/v3/company/" + realmId + "/query"; // 携带accessToken发起API请求 } }
内容的提问来源于stack exchange,提问作者Vyassa
相关产品推荐
相关产品推荐

