Vaadin、Spring Boot、Microsoft Graph - 如何使用刷新令牌扩展访问令牌

发布于 2025-01-14 06:15:03 字数 4424 浏览 4 评论 0原文

我正在开发一个访问 Microsoft Graph 的应用程序,到目前为止一切正常。但一小时后,访问令牌已过期,我不明白如何刷新令牌。我进行了很多研究,似乎没有什么适合使用 azure spring boot starter 的方法。如果有人提供提示,那就太好了,因为我无法在 Microsoft 文档或其他任何地方找到有用的东西。

据我了解,我必须使用刷新令牌发送新的 Post 请求才能获取新的访问令牌。但在这种情况下我该如何做到这一点呢?

我正在使用 Vaadin 14.7,以下是其他库:

<dependency> 
  <groupId>org.springframework.boot</groupId>  
  <artifactId>spring-boot-starter-oauth2-client</artifactId>  
  <version>2.5.5</version> 
</dependency>  

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

<dependency> 
  <groupId>com.azure.spring</groupId>  
  <artifactId>azure-spring-boot-starter-active-directory</artifactId>  
  <version>3.9.0</version> 
</dependency>  

<dependency> 
  <groupId>org.springframework.security</groupId>  
  <artifactId>spring-security-oauth2-core</artifactId>  
  <version>5.5.2</version> 
</dependency>

<dependency> 
  <groupId>com.microsoft.graph</groupId>  
  <artifactId>microsoft-graph</artifactId>  
  <version>5.4.0</version> 
</dependency>  

这是我的代码,用于让 GraphServiceClient 向 Graph API 发出请求

public GraphServiceClient<Request> getGraphService() throws OAuthTokenException {
    OAuth2AuthenticationToken token;
    try {
        token = (OAuth2AuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
    } catch (ClassCastException e) {
        throw new OAuthTokenException("Token cannot be cast");
    }

    if (token == null)
        throw new OAuthTokenException("No valid OAuth Token");

    OAuth2AuthorizedClient authorizedClient = this.oAuth2AuthorizedClientRepository.loadAuthorizedClient(
            token.getAuthorizedClientRegistrationId(),
            SecurityContextHolder.getContext().getAuthentication(),
            (HttpServletRequest) VaadinService.getCurrentRequest());

    return GraphServiceClient.builder().authenticationProvider(new GraphAuthenticationProvider(authorizedClient))
            .buildClient();
}

身份验证提供程序:

public class GraphAuthenticationProvider extends BaseAuthenticationProvider {
private final OAuth2AuthorizedClient graphAuthorizedClient;

/**
 * Set up the GraphAuthenticationProvider. Allows accessToken to be
 * used by GraphServiceClient through the interface IAuthenticationProvider
 *
 * @param graphAuthorizedClient OAuth2AuthorizedClient created by AAD Boot starter. Used to surface the access token.
 */
public GraphAuthenticationProvider(OAuth2AuthorizedClient graphAuthorizedClient) throws OAuthTokenException {
    if (graphAuthorizedClient == null)
        throw new OAuthTokenException("No valid client!");

    this.graphAuthorizedClient = graphAuthorizedClient;
}

/**
 * This implementation of the IAuthenticationProvider helps injects the Graph access
 * token into the headers of the request that GraphServiceClient makes.
 *
 * @param requestUrl the outgoing request URL
 * @return a future with the token
 */
@Override
public CompletableFuture<String> getAuthorizationTokenAsync(final URL requestUrl){
    return CompletableFuture.completedFuture(graphAuthorizedClient.getAccessToken().getTokenValue());
}

}

我的配置:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Lazy
@Autowired
private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .csrf().disable()
            .headers().frameOptions().disable().and()
            .authorizeRequests()
            .requestMatchers(SecurityUtils::isFrameworkInternalRequest).permitAll()
            .antMatchers("/login**", "/error**", "/api/**").permitAll()
            .anyRequest().authenticated()
            .and().logout().logoutUrl("/logout").logoutSuccessUrl("/login")
            .and()
            .oauth2Login()
            .userInfoEndpoint()
            .oidcUserService(oidcUserService);
}

...

@Bean
public OAuth2AuthorizedClientRepository authorizedClientRepository() {
    return new HttpSessionOAuth2AuthorizedClientRepository();
}

}

I am developing an application that accesses Microsoft Graph and everything works fine so far. But after an hour the access token has expired and I do not understand how I can refresh the token. I researched a lot and nothing seems to fit to the approach with azure spring boot starter. It would be really nice if someone has a tip because I was not able to find something helpful in the Microsoft documentation or anywhere else.

As far as I am understanding this, I have to send a new Post request with the refresh_token to get a new access token. But how can I do this in this scenario?

I am using Vaadin 14.7, here are the other libraries:

<dependency> 
  <groupId>org.springframework.boot</groupId>  
  <artifactId>spring-boot-starter-oauth2-client</artifactId>  
  <version>2.5.5</version> 
</dependency>  

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

<dependency> 
  <groupId>com.azure.spring</groupId>  
  <artifactId>azure-spring-boot-starter-active-directory</artifactId>  
  <version>3.9.0</version> 
</dependency>  

<dependency> 
  <groupId>org.springframework.security</groupId>  
  <artifactId>spring-security-oauth2-core</artifactId>  
  <version>5.5.2</version> 
</dependency>

<dependency> 
  <groupId>com.microsoft.graph</groupId>  
  <artifactId>microsoft-graph</artifactId>  
  <version>5.4.0</version> 
</dependency>  

This is my code to get the GraphServiceClient to make requests against the Graph API

public GraphServiceClient<Request> getGraphService() throws OAuthTokenException {
    OAuth2AuthenticationToken token;
    try {
        token = (OAuth2AuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
    } catch (ClassCastException e) {
        throw new OAuthTokenException("Token cannot be cast");
    }

    if (token == null)
        throw new OAuthTokenException("No valid OAuth Token");

    OAuth2AuthorizedClient authorizedClient = this.oAuth2AuthorizedClientRepository.loadAuthorizedClient(
            token.getAuthorizedClientRegistrationId(),
            SecurityContextHolder.getContext().getAuthentication(),
            (HttpServletRequest) VaadinService.getCurrentRequest());

    return GraphServiceClient.builder().authenticationProvider(new GraphAuthenticationProvider(authorizedClient))
            .buildClient();
}

The Authentication Provider:

public class GraphAuthenticationProvider extends BaseAuthenticationProvider {
private final OAuth2AuthorizedClient graphAuthorizedClient;

/**
 * Set up the GraphAuthenticationProvider. Allows accessToken to be
 * used by GraphServiceClient through the interface IAuthenticationProvider
 *
 * @param graphAuthorizedClient OAuth2AuthorizedClient created by AAD Boot starter. Used to surface the access token.
 */
public GraphAuthenticationProvider(OAuth2AuthorizedClient graphAuthorizedClient) throws OAuthTokenException {
    if (graphAuthorizedClient == null)
        throw new OAuthTokenException("No valid client!");

    this.graphAuthorizedClient = graphAuthorizedClient;
}

/**
 * This implementation of the IAuthenticationProvider helps injects the Graph access
 * token into the headers of the request that GraphServiceClient makes.
 *
 * @param requestUrl the outgoing request URL
 * @return a future with the token
 */
@Override
public CompletableFuture<String> getAuthorizationTokenAsync(final URL requestUrl){
    return CompletableFuture.completedFuture(graphAuthorizedClient.getAccessToken().getTokenValue());
}

}

My Configuration:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Lazy
@Autowired
private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .csrf().disable()
            .headers().frameOptions().disable().and()
            .authorizeRequests()
            .requestMatchers(SecurityUtils::isFrameworkInternalRequest).permitAll()
            .antMatchers("/login**", "/error**", "/api/**").permitAll()
            .anyRequest().authenticated()
            .and().logout().logoutUrl("/logout").logoutSuccessUrl("/login")
            .and()
            .oauth2Login()
            .userInfoEndpoint()
            .oidcUserService(oidcUserService);
}

...

@Bean
public OAuth2AuthorizedClientRepository authorizedClientRepository() {
    return new HttpSessionOAuth2AuthorizedClientRepository();
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

攒一口袋星星 2025-01-21 06:15:03

您可以使用refresh_token刷新旧令牌,以下步骤可以帮助获取刷新令牌,请参阅Microsoft 文档
输入图片此处描述

you can use refresh_token to refresh old token , below steps can be help to get the refresh token, please refer the Microsoft documentation .
enter image description here

渔村楼浪 2025-01-21 06:15:03

正如我们在您的代码中看到的,图形版本已旧,因此请尝试先将版本更新到 5.17.0,请遵循文档 - https://github.com/microsoftgraph/msgraph-sdk-java
输入图片此处描述

那么我们建议您使用 MSAL 进行身份验证,文档 https://github.com/AzureAD/microsoft-authentication-library-for-java
输入图片此处描述

,然后尝试获取令牌 - 请参阅文档 , 在此处输入图像描述

As we can see in your code the graph version is old , so try to you update the version to 5.17.0 firs,please follow the docs - https://github.com/microsoftgraph/msgraph-sdk-java
enter image description here

Then we recommend you to use MSAL for authentication , docs https://github.com/AzureAD/microsoft-authentication-library-for-java ,
enter image description here

and then try to acquire the token - refer docs , enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文