1. 简介
本文将演示如何轻松地在Spring Boot应用中使用AzureAD作为身份认证提供者。我们将展示完整的集成步骤,包括配置、客户端注册和权限映射等关键环节。
2. 概述
AzureAD是微软推出的综合性身份管理产品,被全球众多组织广泛采用。它支持多种登录机制和控制策略,能为组织内的应用组合提供单点登录体验。
特别值得注意的是,AzureAD与现有Active Directory安装深度集成——这正是许多组织在企业网络中用于身份和访问管理的基础设施。管理员可以使用熟悉的工具为现有用户分配应用权限,统一管理访问控制。
3. 集成AzureAD
从Spring Boot应用的角度看,AzureAD表现为一个符合OIDC标准的身份提供者。这意味着我们只需配置必要的属性和依赖,就能与Spring Security无缝集成。
我们将实现一个保密客户端,其中授权码与访问令牌的交换在服务端完成。这种流程永远不会将访问令牌暴露给用户浏览器,因此比公共客户端方案更安全。
4. Maven依赖
首先添加基于Spring Security的WebMVC应用所需依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
<version>3.1.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.1.5</version>
</dependency>
最新版本可在Maven中央仓库获取:
5. 配置属性
接下来添加配置Spring Security所需的属性。最佳实践是将这些属性放在独立的Spring Profile中,便于应用扩展时维护。我们创建名为azuread
的profile,在application-azuread.yml
中配置:
spring:
security:
oauth2:
client:
provider:
azure:
issuer-uri: https://login.microsoftonline.com/your-tenant-id-comes-here/v2.0
registration:
azure-dev:
provider: azure
#client-id: 外部提供
#client-secret: 外部提供
scope:
- openid
- email
- profile
在provider部分定义azure
提供者:AzureAD支持OIDC标准端点发现机制,因此只需配置issuer-uri
属性。
该属性有双重作用:
- 作为基础URI,客户端追加发现资源名后获取实际下载URL
- 用于验证JSON Web Token (JWT)的真实性(JWT的
iss
声明必须与此值匹配)
AzureAD的issuer-uri
格式固定为:https://login.microsoftonline.com/my-tenant-id/v2.0
,其中my-tenant-id
是你的租户ID。
在registration部分定义使用前述提供者的azure-dev
客户端。必须通过client-id
和client-secret
提供客户端凭据(稍后注册应用时获取)。
scope属性定义授权请求中包含的权限范围。这里请求profile
权限,允许客户端访问标准的userinfo端点,该端点返回AzureAD用户目录中的可配置信息集(如用户偏好语言、区域设置等)。
6. 客户端注册
我们需要在AzureAD中注册客户端应用,以获取client-id
和client-secret
的实际值。假设已有Azure账户,步骤如下:
在Overview部分获取
issuer-uri
配置所需的租户标识符点击App Registrations → New Registration,填写注册表单:
- 应用名称
- 支持的账户类型
- 重定向URI
6.1. 应用名称
此值将在认证过程中展示给最终用户,应选择对目标用户有意义的名称。这里使用示例名称"Baeldung Test App":
AzureAD允许随时修改名称而不影响已注册应用。虽然名称不必唯一,但多个应用使用相同显示名称并非明智之举。
6.2. 支持的账户类型
根据目标受众选择:组织内部应用通常选择第一项("仅限此组织目录中的账户")。这意味着即使应用可从互联网访问,也只有组织内用户可以登录:
其他选项允许接受其他AzureAD目录(如使用Office 365的学校/组织)以及个人账户(Skype/Xbox)。虽然不常见,但此设置后续可修改,不过文档警告修改后用户可能遇到错误。
6.3. 重定向URI
需提供一个或多个授权流程可接受的重定向URI。需选择与URI关联的"平台"类型:
- Web:授权码与访问令牌交换在后端进行
- SPA:交换在前端进行
- Public Client:用于桌面/移动应用
我们选择Web平台。URI值设为http://localhost:8080/login/oauth2/code/azure-dev
,该路径来自Spring Security的OAuth回调控制器默认路径/login/oauth2/code/{registration-name}
,其中{registration-name}
需匹配配置中的注册名称(此处为azure-dev
)。
重要提示:AzureAD要求这些URI使用HTTPS,但对localhost有例外,便于本地开发无需证书。部署到生产环境(如Kubernetes集群)时可添加其他URI。
6.4. 添加客户端密钥
左侧Essentials部分的应用程序ID对应配置文件中的client-id
。生成客户端密钥步骤:
⚠️ 当前客户端密钥最长有效期2年,必须建立密钥轮换机制(建议使用Terraform等自动化工具)。企业环境中应用长期运行很常见,两年看似很长实则不然。
必须立即复制密钥值到安全位置,离开页面后将不再显示。我们将值直接复制到应用的client-secret
属性中。
⚠️ 这是敏感值!生产环境通常通过动态机制(如Kubernetes密钥)提供。
7. 应用代码
测试应用包含一个控制器,处理根路径请求,记录认证信息并转发到Thymeleaf视图,渲染用户信息页面:
@Controller
@RequestMapping("/")
public class IndexController {
@GetMapping
public String index(Model model, Authentication user) {
model.addAttribute("user", user);
return "index";
}
}
视图代码使用user
模型属性创建认证对象和所有可用声明的信息表格。
8. 运行测试应用
由于使用了AzureAD专用profile,需激活该profile。通过Spring Boot Maven插件运行时,使用spring-boot.run.profiles
属性:
mvn -Dspring-boot.run.profiles=azuread spring-boot:run
访问http://localhost:8080
,Spring Security检测到未认证请求,重定向到AzureAD通用登录页:
具体登录流程因组织设置而异,通常包含用户名/邮箱和密码输入,可能要求二次认证。若已在同一浏览器的同一AzureAD租户登录其他应用,将跳过登录流程——这正是单点登录的体现。
✅ AzureAD支持自定义登录UI(包括本地化定制),也可完全跳过授权表单(适用于内部应用授权)。
已获取用户基本信息(姓名、邮箱、头像URL等),但用户名显示不友好。接下来优化此问题。
9. 用户名映射
Spring Security使用Authentication
接口表示已认证主体,其getName()
方法返回的值常作为用户唯一标识。使用JWT认证时,Spring Security默认使用标准sub
声明值作为主体名称,但AzureAD在此字段填充内部标识符,不适合显示。
解决方案:在提供者配置中指定user-name-attribute
属性,选择可用属性:
spring:
security:
oauth2:
client:
provider:
azure:
issuer-uri: https://login.microsoftonline.com/xxxxxxxxxxxxx/v2.0
user-name-attribute: name
... 其他属性省略
这里选择name
声明(用户全名),也可选email
属性(若应用需用于数据库查询)。重启应用后效果:
用户体验显著改善!
10. 获取组成员信息
检查可用声明发现缺少用户组成员信息。Authentication
中仅包含与请求范围关联的GrantedAuthority
值。
若仅需限制组织成员访问,这已足够。但通常需要基于用户角色授予不同访问级别,将角色映射到AzureAD组可复用现有流程(如用户入职/调岗)。
需配置AzureAD在授权流程返回的idToken
中包含组成员信息:
11. 将组映射为Spring权限
groups声明包含用户所属组的对象ID列表,但Spring不会自动将其映射为GrantedAuthority
实例。需自定义OidcUserService
(参考Spring Security文档)。
我们的实现使用外部映射表为标准OidcUser
添加权限。通过@ConfigurationProperties
类配置:
- 获取组列表的声明名称("groups")
- 权限前缀
- 对象ID到
GrantedAuthority
的映射表
组到权限的映射策略允许复用现有组,保持应用角色集与组分配策略解耦。典型配置示例:
baeldung:
jwt:
authorization:
group-to-authorities:
"ceef656a-fca9-49b6-821b-xxxxxxxxxxxx": BAELDUNG_RW
"eaaecb69-ccbc-4143-b111-xxxxxxxxxxxx": BAELDUNG_RO,BAELDUNG_ADMIN
现在包含三个对应映射组的新权限。
12. 总结
本文展示了在Spring Security中使用AzureAD进行用户认证的完整流程,包括演示应用的配置步骤。关键点包括:
- ✅ 通过OIDC标准实现无缝集成
- ✅ 保密客户端模式保障令牌安全
- ✅ 灵活的用户名和权限映射机制
- ⚠️ 注意客户端密钥的定期轮换
完整代码可在GitHub获取。