Azure AD授权码流Core Java实现及无浏览器令牌获取咨询
背景
- 已实现Azure AD的Client Credential授权类型(代码如下)
- 需求:基于Core Java实现Authorization Code授权类型的令牌获取逻辑,要求不依赖Spring Boot,无需浏览器交互,通过代码传递凭证获取Access Token
- 已知参数:
- 授权URL:
https://login.microsoftonline.com/{tenantID}/oauth2/v2.0/authorize - 令牌URL:
https://login.microsoftonline.com/{tenantID}/oauth2/v2.0/token - Client ID:
{ClientID} - Client Secret:
{Client_Secret} - Scope:
{ClientID}/.default - 回调URL:
http://redirectURL
- 授权URL:
- 已在Postman中完成令牌生成测试,咨询方案可行性及具体实现
已掌握的Client Credential实现代码
import java.net.URI; import java.net.URLEncoder; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; public class AzureAdClientCredentialFlow { public static void main(String[] args) { String tenantId = "{tenantID}"; String clientId = "CLIENT_ID"; String clientSecret = "CLIENT_SECRET"; String scope = clientId + "/.default"; String url = String.format("https://login.microsoftonline.com/%s/oauth/v2.0/token", tenantId); Map<String, String> parameters = new HashMap<>(); parameters.put("grant_type", "client_credentials"); parameters.put("client_id", clientId); parameters.put("client_secret", clientSecret); parameters.put("scope", scope); String form = parameters.keySet().stream() .map(key -> key + "=" + URLEncoder.encode(parameters.get(key), StandardCharsets.UTF_8)) .collect(Collectors.joining("&")); HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)) .headers("Content-Type", "application/x-www-form-urlencoded") .POST(HttpRequest.BodyPublishers.ofString(form)) .build(); HttpResponse<?> response = null; try { response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body()); } catch (Exception e) { e.printStackTrace(); } } }
可行性说明
授权码流的核心是需要用户通过浏览器完成身份认证并授权,从而获取一次性的授权码(code)。要实现无浏览器交互,有两种可行路径:
- 预获取授权码:手动通过浏览器或Postman获取有效期内的code,再用代码调用令牌URL兑换token(code仅能使用一次)
- 无头浏览器模拟:使用Selenium等无头浏览器工具自动化完成登录授权流程获取code,但这需要额外依赖,不属于纯Core Java实现
如果你的场景是服务端非交互式访问,且不需要用户参与,更推荐使用Client Credential流;若必须使用授权码流,只能通过上述两种方式规避浏览器交互。
具体实现代码(Core Java)
以下是用预获取的授权码兑换Access Token的纯Core Java实现:
import java.net.URI; import java.net.URLEncoder; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; public class AzureAdAuthorizationCodeFlow { public static void main(String[] args) { // 替换为实际参数 String tenantId = "{tenantID}"; String clientId = "{ClientID}"; String clientSecret = "{Client_Secret}"; String redirectUri = "http://redirectURL"; String scope = clientId + "/.default"; // 替换为预先获取的有效授权码 String authorizationCode = "{YOUR_AUTHORIZATION_CODE}"; String tokenUrl = String.format("https://login.microsoftonline.com/%s/oauth2/v2.0/token", tenantId); // 构建请求参数 Map<String, String> parameters = new HashMap<>(); parameters.put("grant_type", "authorization_code"); parameters.put("client_id", clientId); parameters.put("client_secret", clientSecret); parameters.put("code", authorizationCode); parameters.put("redirect_uri", redirectUri); parameters.put("scope", scope); // 转换为x-www-form-urlencoded格式 String formData = parameters.keySet().stream() .map(key -> key + "=" + URLEncoder.encode(parameters.get(key), StandardCharsets.UTF_8)) .collect(Collectors.joining("&")); // 创建HttpClient并发送请求 HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(tokenUrl)) .header("Content-Type", "application/x-www-form-urlencoded") .POST(HttpRequest.BodyPublishers.ofString(formData)) .build(); try { HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println("响应状态码: " + response.statusCode()); System.out.println("响应内容: " + response.body()); } catch (Exception e) { e.printStackTrace(); } } }
注意事项
- 授权码(code)仅能使用一次,使用后立即失效,需重新获取
- 授权码有效期通常为10分钟,需在有效期内完成兑换
- 回调URL(
redirect_uri)必须与Azure AD应用注册中配置的完全一致,否则会返回错误 - 如果需要完全自动化获取code,需引入Selenium等无头浏览器依赖,实现登录授权的自动化流程
内容的提问来源于stack exchange,提问作者Mahajan
相关产品推荐
相关产品推荐

