以下是一个使用 golang.org/x/oauth2 包实现 Azure AD 授权码授权流程的完整示例。该示例将引导用户完成登录流程,获取访问令牌,并使用该令牌调用 Microsoft Graph API 获取用户信息。
首先,确保在 Azure 门户中注册应用并配置重定向 URI(例如 http://localhost:8080/auth/callback),并授予 User.Read 权限(委托权限)。
1. 安装依赖
go get golang.org/x/oauth2
2. 主要代码实现
package main
import (
"context"
"fmt"
"log"
"net/http"
"golang.org/x/oauth2"
"golang.org/x/oauth2/microsoft"
)
// 配置 OAuth2
var (
oauthConfig = &oauth2.Config{
ClientID: "YOUR_CLIENT_ID", // 替换为你的客户端 ID
ClientSecret: "YOUR_CLIENT_SECRET", // 替换为你的客户端密钥
RedirectURL: "http://localhost:8080/auth/callback",
Scopes: []string{"User.Read"},
Endpoint: microsoft.AzureADEndpoint("YOUR_TENANT_ID"), // 替换为你的租户 ID
}
state = "random-state-string" // 用于防止 CSRF 攻击
)
func main() {
http.HandleFunc("/", handleHome)
http.HandleFunc("/login", handleLogin)
http.HandleFunc("/auth/callback", handleCallback)
fmt.Println("服务器运行在 http://localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
// 主页
func handleHome(w http.ResponseWriter, r *http.Request) {
html := `<html><body><a href="/login">使用 Azure AD 登录</a></body></html>`
w.Write([]byte(html))
}
// 跳转到 Azure AD 登录页面
func handleLogin(w http.ResponseWriter, r *http.Request) {
url := oauthConfig.AuthCodeURL(state, oauth2.AccessTypeOffline)
http.Redirect(w, r, url, http.StatusTemporaryRedirect)
}
// 处理回调,获取访问令牌
func handleCallback(w http.ResponseWriter, r *http.Request) {
if r.URL.Query().Get("state") != state {
http.Error(w, "状态不匹配", http.StatusBadRequest)
return
}
code := r.URL.Query().Get("code")
token, err := oauthConfig.Exchange(context.Background(), code)
if err != nil {
http.Error(w, "无法交换令牌: "+err.Error(), http.StatusInternalServerError)
return
}
// 使用访问令牌调用 Microsoft Graph API
client := oauthConfig.Client(context.Background(), token)
resp, err := client.Get("https://graph.microsoft.com/v1.0/me")
if err != nil {
http.Error(w, "请求 Graph API 失败: "+err.Error(), http.StatusInternalServerError)
return
}
defer resp.Body.Close()
// 读取响应(此处简化处理,实际应解析 JSON)
w.Write([]byte("成功获取用户信息!访问令牌: " + token.AccessToken))
}
3. 使用访问令牌进行 REST 调用
获取访问令牌后,可以将其用于任何 Azure REST API 调用。以下示例演示如何将访问令牌添加到请求头中:
func callAzureResource(token *oauth2.Token, resourceURL string) {
req, _ := http.NewRequest("GET", resourceURL, nil)
req.Header.Set("Authorization", "Bearer "+token.AccessToken)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// 处理响应...
}
4. 配置说明
- 将
YOUR_CLIENT_ID、YOUR_CLIENT_SECRET 和 YOUR_TENANT_ID 替换为你的 Azure 应用注册信息。
- 确保重定向 URI 与 Azure 门户中配置的完全一致。
- 根据需要调整
Scopes(例如 https://management.azure.com/user_impersonation 用于 Azure 资源管理)。
注意事项
- 此示例使用内存存储,生产环境应使用安全存储(如数据库)管理令牌和状态。
- 客户端密钥需保密,避免硬编码在代码中(可使用环境变量)。
运行程序后,访问 http://localhost:8080 并点击登录链接,将跳转到 Azure AD 登录页面。登录成功后,回调页面将显示访问令牌和用户信息。