Java调用Graph API如何获取AuthorizationCodeCredential授权码
问题参考
免责声明:本问题为此前提问「how-to-set-scope-when-call-microsoft-graph-api」的续篇。
我正在学习在Java项目中调用Microsoft Graph API,当前需要实现向Teams频道发送消息的功能,目前编写的代码如下:
ClientSecretCredential _credential = new ClientSecretCredentialBuilder().clientId(clientId).clientSecret(secretValue).tenantId(tenantId).build(); TokenCredentialAuthProvider authProvider = new TokenCredentialAuthProvider(graphUserScopes, _credential); GraphServiceClient<Request>_client = GraphServiceClient.builder().authenticationProvider(authProvider).buildClient(); ChatMessage chatMessage = new ChatMessage(); ItemBody body = new ItemBody(); body.content = message; chatMessage.body = body; _client.teams(teamId).channels(channelId).messages().buildRequest().post(chatMessage);我了解到ClientSecretCredential仅支持Application类型权限操作,而发送频道消息的接口要求使用Delegated类型权限。我尝试改用AuthorizationCodeCredential类完成认证,但不清楚如何获取该类所需的authorizationCode参数,参考了官方授权码提供程序相关文档,希望能得到获取authorizationCode的可运行参考代码。
解答
首先补充关键信息:当前向Teams频道发送消息的Graph接口已经支持Application类权限,权限项为ChannelMessage.Send。如果你做的是无用户交互的后台服务场景,完全不需要走委托权限的授权码流:给Azure AD应用添加该应用权限、完成租户管理员授权后,把原有代码里的scope替换为https://graph.microsoft.com/.default即可正常调用,实现成本低很多。
如果你确实需要使用Delegated权限走授权码流,要明确:authorizationCode是用户完成微软账号登录、同意授权后,Azure AD重定向回你预先配置的回调地址时携带的一次性临时代码,完整获取流程和可运行参考代码如下:
- 前置配置:进入Azure AD应用注册页面,给你的应用添加需要的委托权限(比如
ChannelMessage.Send、offline_access),同时添加重定向URI,本地调试可填http://localhost:8080/ms-callback。 - 代码实现(以Spring Boot Web项目为例):
// 1. 登录引导接口,浏览器访问该接口会自动跳转到微软官方登录授权页 @GetMapping("/ms-login") public void redirectToMicrosoftLogin(HttpServletResponse response) throws IOException { String encodedRedirectUri = URLEncoder.encode("http://localhost:8080/ms-callback", StandardCharsets.UTF_8); String authUrl = String.format( "https://login.microsoftonline.com/%s/oauth2/v2.0/authorize?" + "client_id=%s" + "&response_type=code" + "&redirect_uri=%s" + "&response_mode=query" + "&scope=https://graph.microsoft.com/ChannelMessage.Send offline_access" + "&state=%s", tenantId, clientId, encodedRedirectUri, UUID.randomUUID().toString() // state参数用于校验请求来源防CSRF,生产环境需持久化后校验 ); response.sendRedirect(authUrl); } // 2. 回调接口,和Azure AD中配置的重定向URI完全一致,授权码会通过code参数传入 @GetMapping("/ms-callback") public String handleCallbackAndSendMsg(@RequestParam("code") String authorizationCode, @RequestParam("state") String state) { // 校验state合法性,校验通过后再使用authorizationCode初始化凭证 AuthorizationCodeCredential credential = new AuthorizationCodeCredentialBuilder() .clientId(clientId) .clientSecret(clientSecret) .authorizationCode(authorizationCode) .redirectUrl("http://localhost:8080/ms-callback") .tenantId(tenantId) .build(); // 初始化Graph服务客户端 TokenCredentialAuthProvider authProvider = new TokenCredentialAuthProvider( Arrays.asList("https://graph.microsoft.com/ChannelMessage.Send"), credential ); GraphServiceClient<Request> graphClient = GraphServiceClient.builder() .authenticationProvider(authProvider) .buildClient(); // 执行频道消息发送逻辑 ChatMessage chatMessage = new ChatMessage(); ItemBody body = new ItemBody(); body.content = "测试频道消息"; chatMessage.body = body; graphClient.teams(teamId).channels(channelId).messages() .buildRequest() .post(chatMessage); return "消息发送成功"; }
- 注意事项:
- authorizationCode为一次性使用凭证,有效期仅数分钟,拿到后需要立刻调用凭证对象兑换access token,不能存储复用
- 授权请求时加上
offline_accessscope可以拿到refresh_token,后续无需用户重复登录即可续期access token,适合需要长期保留用户授权的场景 - 如果你的项目是桌面应用、命令行工具这类没有公网回调地址的场景,可以改用DeviceCodeCredential实现委托权限认证,无需配置重定向URI,流程更简单。
内容的提问来源于stack exchange,提问作者N.D.H.Vu
相关产品推荐
相关产品推荐

