如何在Sping Boot 客户端中从oauth2流中提取access_token

rqmkfv5c  于 2023-10-15  发布在  其他
关注(0)|答案(1)|浏览(111)

我需要了解如何从Sping Boot 客户端应用程序访问和提取access_token。所以我创建了一个spring Boot 应用程序,它对github oauth2提供程序执行oauth2流,它可以授权和认证我的spring Boot 应用程序,没有问题。但是,我还需要让我的应用程序能够提取access_token。这就是我遇到的麻烦.我不明白在Spring Boot 应用程序中重定向是什么样子的。我试着从这个帖子OAuth2: Extract access_token fragment from implicit flow中得到一个想法.但不确定这将如何在Spring Boot 应用程序中翻译。
这里是我到目前为止尝试过的客户端代码和spring Boot 客户端代码下面的github配置:
application.yml:

spring:
  security:
    oauth2:
      client:
        registration:
          github:
            client-id: ea54290955115164855a
            client-secret: d4987ca45405bb75adc78175f9aa5c11ab9e2b2a
            scope: user:email
            authorization-grant-type: authorization_code
            redirect-uri: '{baseUrl}/login/oauth2/code/github'
        provider:
          github:
            authorization-uri: https://github.com/login/oauth/authorize
            token-uri: https://github.com/login/oauth/access_token

SecurityConfig.java:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        return httpSecurity
                .authorizeHttpRequests(auth -> {
                    auth.requestMatchers("/").permitAll();
                    auth.requestMatchers("/favicon.ico").permitAll();
                    auth.anyRequest().authenticated();
                })
                .oauth2Login(withDefaults())
                .formLogin(withDefaults())
                .build();

    }
}

AuthController.java:

@RestController
public class AuthController {

    @GetMapping("/login/github")
    public String redirectToGitHub() {
        // This will automatically redirect the user to the GitHub authorization URL
        return "redirect:https://github.com/login/oauth/authorize";
    }

    @GetMapping("/login/oauth2/code/github")
    public String handleGitHubCallback(@AuthenticationPrincipal OAuth2User principal) {
        // Handle the callback and extract the access token
        String accessToken = principal.getAttribute("access_token");

        // Use the access token for GitHub API requests or store it as needed
        // Redirect or display user information as required

        return "redirect:/profile"; // Redirect to a profile page, for example
    }
}

/login/oauth2/code/github端点是我认为浏览器会重定向到的地方,但它没有...为什么?
这是我在github上注册客户端的方式:

liwlm1x9

liwlm1x91#

授权码不是访问令牌。OAuth2客户端只能使用一次代码来获取令牌。因此,当调用/login/oauth2/code/github时,客户端还没有令牌。
一旦客户端成功获得了给定客户端注册的授权(在代码交换为令牌之后),您就可以从OAuth2AuthorizedClientRepository获取该注册的OAuth2AuthorizedClient示例。OAuth2AuthorizedClient包含您正在查找的访问令牌。

@RestController
@RequiredArgsConstructor
static class TokensController {
    private final OAuth2AuthorizedClientRepository authorizedClientRepo;
    
    @GetMapping("/access-token")
    @PreAuthorize("isAuthenticated()")
    public String getAccessToken(HttpServletRequest request, OAuth2AuthenticationToken auth) {
        final var authorizedClient = authorizedClientRepo.loadAuthorizedClient(auth.getAuthorizedClientRegistrationId(), auth, request);
        return Optional.ofNullable(authorizedClient).map(OAuth2AuthorizedClient::getAccessToken).map(OAuth2AccessToken::getTokenValue).orElse(null);
    }
}

请注意,您正在尝试做的事情非常可疑,可能会打开严重的安全漏洞:访问令牌被传递到客户端以代表令牌受众的资源服务器部分上的资源所有者进行操作。如果令牌泄露,恶意程序/用户可以窃取资源所有者身份并向资源服务器授权恶意请求。因此,访问令牌应该只在颁发它的授权服务器、它被传递到的客户端和受众的资源服务器部分之间交换。它不应该被前端访问,因为你可能正在实现,其他客户端,资源服务器不是受众的一部分,等等。你最好在spring-cloud-gateway中使用类似TokenRelay filter的东西,它在将请求从前端转发到资源服务器之前,用包含session中访问令牌的Authorization头替换session cookie。提醒一下,由oauth2Login安全过滤器链处理的请求是通过会话而不是令牌来保护的。
因此,与其将访问令牌暴露给前端,不如像我在this tutorial中所做的那样实现BFF模式。

相关问题