Vaadin、Spring Boot、Microsoft Graph - 如何使用刷新令牌扩展访问令牌
我正在开发一个访问 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用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 .

正如我们在您的代码中看到的,图形版本已旧,因此请尝试先将版本更新到 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

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

and then try to acquire the token - refer docs ,