如何在 Go 应用中集成 Azure AD 实现单点登录(SSO)

11次阅读

如何在 Go 应用中集成 Azure AD 实现单点登录(SSO)

本文介绍如何使用 go 语言构建基于 openid connect 协议的单点登录框架,对接 azure active Directory(azure ad),实现安全、标准、可扩展的用户身份认证。

go 生态中实现 Azure AD 单点登录(SSO),推荐采用 OpenID Connect(OIDC) ——这是 OAuth 2.0 的身份层扩展,也是 Azure AD 官方首选且最简明的现代认证方案。相比已逐步弃用的 WS-Fed 或 SAML-P,OIDC 基于 jsON 和 httpS,天然适配 Go 的轻量级 Web 服务架构,且拥有成熟的标准库支持。

✅ 核心步骤概览

  1. 在 Azure Portal 注册应用:获取 Client ID、Client Secret 和 Tenant ID;配置重定向 URI(如 http://localhost:8080/callback);启用 ID Token 发放(需在「Token configuration」中添加 ID token)。
  2. 选择 OIDC 客户端库:推荐使用 coreos/go-oidc(社区维护良好,支持 PKCE 可选)或更轻量的 oauth2 + 手动验证 ID Token。
  3. 实现认证流程
    • 重定向用户至 Azure AD 授权端点;
    • 处理回调,交换 authorization code 获取 id_token 和 access_token;
    • 验证 ID Token 签名、有效期、受众(aud)、颁发者(iss)等关键声明;
    • 解析用户身份(如 email、name、oid)并建立会话。

? 示例代码(基于 go-oidc)

package main  import (     "context"     "fmt"     "log"     "net/http"     "time"      "github.com/coreos/go-oidc"     "golang.org/x/oauth2" )  var (     provider *oidc.Provider     oauth2Config *oauth2.Config )  func init() {     ctx := context.Background()     var err error     // 初始化 OIDC Provider(注意替换为你的 tenant ID)     provider, err = oidc.NewProvider(ctx, "https://login.microsoftonline.com/YOUR_TENANT_ID/v2.0")     if err != nil {         log.Fatal(err)     }      // 配置 OAuth2 客户端(从 Azure app Registration 获取)     oauth2Config = &oauth2.Config{         ClientID:     "YOUR_CLIENT_ID",         ClientSecret: "YOUR_CLIENT_SECRET",         RedirectURL:  "http://localhost:8080/callback",         Endpoint:     provider.Endpoint(),         Scopes:       []string{oidc.ScopeOpenID, "profile", "email"},     } }  func loginHandler(w http.ResponseWriter, r *http.Request) {     http.Redirect(w, r, oauth2Config.AuthCodeURL("state", oauth2.accessTypeOnline), http.StatusFound) }  func callbackHandler(w http.ResponseWriter, r *http.Request) {     ctx := r.Context()     code := r.URL.Query().Get("code")     if code == "" {         http.Error(w, "missing code", http.StatusbadRequest)         return     }      // 交换 code 获取 token     oauth2Token, err := oauth2Config.Exchange(ctx, code)     if err != nil {         http.Error(w, "failed to exchange code", http.StatusInternalServerError)         return     }      // 解析并验证 ID Token     rawIDToken, ok := oauth2Token.Extra("id_token").(string)     if !ok {         http.Error(w, "no id_token in response", http.StatusInternalServerError)         return     }      idToken, err := provider.Verifier(&oidc.Config{ClientID: oauth2Config.ClientID}).Verify(ctx, rawIDToken)     if err != nil {         http.Error(w, "failed to verify id_token", http.StatusInternalServerError)         return     }      // 提取用户信息     var claims struct {         Email string `json:"email"`         Name  string `json:"name"`     }     if err := idToken.Claims(&claims); err != nil {         http.Error(w, "failed to parse claims", http.StatusInternalServerError)         return     }      fmt.Fprintf(w, "✅ Logged in as %s (%s)", claims.Name, claims.Email) }  func main() {     http.HandleFunc("/login", loginHandler)     http.HandleFunc("/callback", callbackHandler)     log.Println("Server starting on :8080")     log.Fatal(http.ListenAndServe(":8080", nil)) }

⚠️ 关键注意事项

  • 安全性:务必启用 PKCE(推荐 S256 code challenge)以防范授权码劫持,尤其在公共客户端场景;生产环境必须使用 HTTPS 并校验 issuer(应为 https://login.microsoftonline.com/{tenant-id}/v2.0)。
  • 租户配置:开发阶段可用 common(多租户)端点,但生产建议锁定 tenant-id 以提升安全与性能。
  • Token 刷新:若需长期访问 Graph API,请保存 refresh_token 并妥善加密存储;ID Token 不可刷新,需重新登录获取新身份上下文。
  • 错误处理:Azure AD 返回的错误(如 login_required, interaction_required)需前端友好提示,并引导用户重新鉴权。

通过以上方式,你即可构建一个符合企业级标准、易于维护、与 Azure AD 深度集成的 Go SSO 框架——无需自研协议解析,专注业务逻辑,安全交由标准与云平台保障。

text=ZqhQzanResources