4、Azure AD集成:Azure AD基础、应用注册、服务主体、托管身份
好,咱们进入第四章节。前面聊了统一身份认证的顶层设计,也看了AWS和阿里云那边的玩法。这一章,咱们把目光转向微软的Azure AD。
说实话,在多云数据湖的实战里,Azure AD是个绕不开的角色。很多企业用Office 365,Azure AD天然就是他们的身份源。我见过不少团队,明明Azure AD里躺着几千个用户,却还在手工维护另一套LDAP,你说这多浪费?
这一章,咱们就把它讲透。从基础概念,到应用注册,再到服务主体和托管身份,一步步来。
4.1 Azure AD基础:不只是目录
很多人以为Azure AD就是个“云上的Active Directory”。嗯,这个理解对了一半。
Azure AD本质上是一个多租户的云身份和访问管理服务。它跟咱们本地那个AD DS(Active Directory Domain Services)有本质区别。本地AD是“目录+认证+授权”,而Azure AD是“身份+认证+授权+应用代理+条件访问+……”。
我习惯把Azure AD理解成一个“身份中枢”。它不存你的文件,不跑你的代码,但它决定了谁能进你的数据湖,谁能读你的Parquet文件。
核心概念速览:
- 租户(Tenant): 一个Azure AD实例。每个Azure订阅必须关联一个租户。你可以理解成“一个公司的身份空间”。
- 用户(User): 就是人。可以是云原生用户,也可以是从本地AD同步过来的。
- 组(Group): 用户的集合。支持安全组和Microsoft 365组。
- 域(Domain): 每个租户有一个初始域(xxx.onmicrosoft.com),你也可以绑定自己的域名。
为什么说它重要?因为你的数据湖(比如Azure Data Lake Storage Gen2)的访问控制,底层就是靠Azure AD的OAuth 2.0令牌来做的。没有Azure AD,你的Spark作业连文件都读不了。
4.2 应用注册:给“程序”一个身份证
好,现在问题来了。你的数据湖里有一堆数据,你的Python脚本、你的Databricks作业、你的Power BI报表,它们都需要访问这些数据。但它们是程序,不是人。程序怎么登录?
答案就是应用注册(App Registration)。
说白了,应用注册就是在Azure AD里给一个“程序”创建了一个身份。这个身份有两个关键属性:
- 应用程序(客户端)ID: 全局唯一,相当于程序的“用户名”。
- 客户端凭据: 可以是密码(Client Secret),也可以是证书(Certificate)。相当于程序的“密码”。
我在项目中遇到过一件事。有个团队把Client Secret直接写死在代码里,结果不小心提交到了GitHub。不到两小时,他们的数据湖就被爬了一遍。嗯,从那以后,我要求所有Client Secret必须存在Key Vault里,并且定期轮换。
我的建议: 能用证书就别用Secret。证书的轮换和吊销比Secret安全得多。而且,证书可以绑定有效期,到期自动失效,省心。
注册一个应用很简单,在Azure门户里搜“App registrations”,点“New registration”。填个名字,选一下支持的账户类型。我一般选“Accounts in this organizational directory only”,除非你有跨租户的需求。
# 注册完成后,你会得到类似这样的信息
Application (client) ID: 12345678-1234-1234-1234-123456789abc
Directory (tenant) ID: 87654321-4321-4321-4321-cba987654321
Client Secret (Value): 这个只在创建时显示一次,记得复制!
4.3 服务主体:身份的“实体化”
应用注册创建了一个“身份定义”,但它还不能直接干活。要让这个身份真正能访问资源(比如你的存储账户),你需要把它“实体化”。这个实体化的产物,就是服务主体(Service Principal)。
你可以这么理解:
- 应用注册 = 一个人的“身份证信息”(姓名、身份证号)。
- 服务主体 = 这个人的“实体存在”(他能去银行开户、能去公司上班)。
当你创建一个应用注册时,Azure AD会自动在同一个租户里创建一个对应的服务主体。但如果你需要跨租户访问,或者需要给这个应用分配特定的Azure RBAC角色,你就得手动管理这个服务主体。
举个例子。你的Databricks工作区需要读取ADLS Gen2里的数据。你需要在ADLS Gen2的“访问控制(IAM)”里,给这个服务主体分配“Storage Blob Data Contributor”角色。这样,Databricks才能用这个身份去读文件。
注意: 服务主体默认没有任何权限。你给它什么角色,它才能干什么事。最小权限原则,永远不要给“Contributor”或“Owner”这种大权限。给个“Storage Blob Data Reader”就够了,除非它需要写数据。
我曾经见过一个案例,运维人员给一个CI/CD的服务主体分配了“Contributor”角色。结果CI/CD脚本里有个bug,误删了整个资源组。嗯,从那以后,我要求所有服务主体的权限必须经过安全组审核。
4.4 托管身份:Azure的“免密”方案
好,前面讲了服务主体。但服务主体有个麻烦:你得管理它的凭据。Secret会过期,证书要轮换。有没有更省心的办法?
有。托管身份(Managed Identity) 就是干这个的。
托管身份是Azure自动管理的一个服务主体。你不需要创建任何凭据,Azure帮你搞定一切。你的虚拟机、你的App Service、你的Functions,只要开启了托管身份,就能自动获得一个身份,去访问其他Azure资源。
我特别喜欢这个功能。它解决了两个核心痛点:
- 凭据泄露风险: 没有Secret,没有证书,想泄露都没东西可泄。
- 运维负担: 不用轮换,不用过期提醒,Azure全自动。
托管身份分两种:
| 类型 | 生命周期 | 使用场景 |
|---|---|---|
| 系统分配(System-assigned) | 与资源绑定。资源删除,身份也删除。 | 单个资源需要唯一身份。比如一台VM只跑一个应用。 |
| 用户分配(User-assigned) | 独立于资源。可以分配给多个资源。 | 多个资源需要共享同一个身份。比如一组VM都访问同一个存储账户。 |
我个人习惯,能用系统分配就用系统分配。因为它更安全——身份跟资源绑定,资源销毁了,身份也没了,不会留下“僵尸身份”。
举个例子。你的Azure Data Factory需要把数据从SQL Server复制到ADLS Gen2。你给Data Factory开启系统分配托管身份,然后在ADLS Gen2的IAM里给这个身份分配“Storage Blob Data Contributor”角色。完事。不需要任何连接字符串,不需要任何Secret。
# 在Azure CLI中为VM启用系统分配托管身份
az vm identity assign -g MyResourceGroup -n MyVm
# 然后,在VM内部,你可以通过Azure Instance Metadata Service获取令牌
# 不需要任何凭据!
curl 'http://169.254.169.254/metadata/identity/oauth2/?api-version=2018-02-01&resource=https://storage.azure.com/' -H Metadata:true
4.5 三者关系与实战选择
讲到这里,你可能有点晕。应用注册、服务主体、托管身份,到底什么关系?
我画了一张图,帮你理清思路。
现在,咱们总结一下实战中的选择逻辑:
- 你的代码跑在Azure服务上(VM、App Service、Functions、Data Factory等)? 首选托管身份。零凭据,零运维。
- 你的代码跑在本地或非Azure环境? 只能用服务主体。记得把Secret存在Key Vault里,或者用证书+受控存储。
- 需要跨租户访问? 应用注册+服务主体。在目标租户里创建服务主体,并授予权限。
避坑指南: 我曾经遇到一个场景,一个应用注册被删除了,但对应的服务主体还在。结果那个服务主体变成了“孤儿”,无法被管理,也无法被删除。最后只能通过PowerShell强制清理。所以,删除应用注册前,一定先检查它有没有被其他资源引用。
好了,这一章的内容就到这里。Azure AD的集成,说白了就是搞清楚“谁(身份)能做什么(权限)”。应用注册、服务主体、托管身份,这三者构成了Azure身份体系的基石。你想想看,你的数据湖每天被成千上万的作业访问,如果身份管理没做好,那简直就是把钥匙挂在门上。