电子书 – Spring Cloud 指南 – NPI EA (分类=Spring Cloud)
announcement - icon

让我们开始使用 Spring Cloud 的微服务架构

>> 加入 Pro 并下载电子书

电子书 – Mockito – NPI EA (标签 = Mockito)
announcement - icon

模拟是单元测试的重要组成部分,Mockito 库使编写 清晰直观的单元测试 变得容易,用于您的 Java 代码。

通过我们的 Mockito 指南 开始模拟,并改进您的应用程序测试

下载电子书

电子书 – Java 并发 – NPI EA (分类=Java 并发)
announcement - icon

在应用程序中处理并发可能是一个棘手的过程,其中包含许多 潜在的陷阱。 扎实的掌握基本知识将有助于最大程度地减少这些问题。

通过我们的 Java 并发 指南开始了解多线程应用程序

>> 下载电子书

电子书 – 响应式 – NPI EA (分类=响应式)
announcement - icon

Spring 5 增加了对使用 Spring WebFlux 模块进行响应式编程的支持,此支持自那时起不断改进。 开始使用 Reactor 项目基础知识和 Spring Boot 中的响应式编程

>> 加入 Pro 并下载电子书

电子书 – Java Streams – NPI EA (分类=Java Streams)
announcement - icon

自从 Java 8 引入以来,Stream API 已成为 Java 开发的基础。 基本操作,例如迭代、过滤、映射元素序列,使用起来看似很简单。

但这些也可能被过度使用并陷入一些常见陷阱。

更好地了解 Stream 的工作方式 以及如何将其与其他语言功能结合使用,请查看我们关于 Java Streams 的指南

>> 加入 Pro 并下载电子书

电子书 – Jackson – NPI EA (分类=Jackson)
announcement - icon

用 Jackson 正确处理 JSON

下载电子书

电子书 – HTTP 客户端 – NPI EA (分类=Http 客户端)
announcement - icon

充分利用 Apache HTTP 客户端

下载电子书

电子书 – Maven – NPI EA (分类 = Maven)
announcement - icon

开始使用 Apache Maven

下载电子书

电子书 – 持久化 – NPI EA (分类=持久化)
announcement - icon

您在努力实现正确的持久化层 Spring 吗?

探索电子书

电子书 – RwS – NPI EA (分类=Spring MVC)
announcement - icon

使用 Spring 构建 REST API 吗?

下载电子书

课程 – LS – NPI EA (分类=Jackson)
announcement - icon

通过 Learn Spring 课程开始学习 Spring 和 Spring Boot

>> 学习 SPRING
课程 – RWSB – NPI EA (分类=REST)
announcement - icon

通过构建一个完整的 REST API,深入了解 Spring Boot 3 和 Spring 6,使用该框架

>> 全新的“REST With Spring Boot”

课程 – LSS – NPI EA (分类=Spring Security)
announcement - icon

是的,Spring Security 可能很复杂,从核心内的更高级功能到框架中深入的 OAuth 支持。

我将安全材料构建为 两个完整的课程 - 核心和 OAuth,以针对这些更复杂的场景进行实践。 我们探索何时以及如何使用每个功能,并 在后台项目中对其进行编码

您可以在这里探索该课程

>> 学习 Spring Security

课程 – LSD – NPI EA (标签=Spring Data JPA)
announcement - icon

Spring Data JPA 是处理 JPA 复杂性的绝佳方式,它具有 Spring Boot 的强大简洁性

通过引导式参考课程开始使用 Spring Data JPA

>> 查看课程

合作伙伴 – Moderne – NPI EA (类别=Spring Boot)
announcement - icon

使用 OpenRewrite 安全且自动地重构 Java 代码。

手动重构大型代码库既缓慢、有风险,又容易拖延。OpenRewrite 应运而生。这个用于大规模、自动化代码转换的开源框架可以帮助团队安全、一致地进行现代化改造。

每个月,OpenRewrite 的创建者和维护者 Moderne 都会举办现场、实践培训课程——一个面向初学者,一个面向经验丰富的用户。您将了解配方的运作方式、如何将其应用于项目,以及如何自信地进行代码现代化改造。

参加下一次课程,带来您的问题,并学习如何自动化通常会占用您 sprint 时间的工作。

合作伙伴 – LambdaTest – NPI EA (类别=测试)
announcement - icon

回归测试是发布流程中的重要步骤,以确保新代码不会破坏现有功能。随着代码库的不断发展,我们希望频繁运行这些测试,以便尽早发现任何问题。

确保这些测试以自动化的方式频繁运行的最佳方法当然是将其包含在 CI/CD 管道中。 这样,每次向仓库提交代码时,回归测试将自动执行。

在本教程中,我们将学习如何使用 Selenium 创建回归测试,然后使用 GitHub Actions 将它们包含在我们的管道中,在 LambdaTest 云网格上运行

>> 如何使用 GitHub Actions 运行 Selenium 回归测试

课程 – LJB – NPI EA (类别 = Core Java)
announcement - icon

通过编码方式构建 Java 的坚实、实用的基础

>> 学习 Java 基础

课程 – LSS – NPI (类别=Spring Security)
announcement - icon

如果您正在使用 Spring Security (特别是 OAuth) 进行实现,请务必查看《学习 Spring Security》课程

>> 学习 SPRING SECURITY
电子书 – Spring Cloud 指南 – NPI (cat=Cloud/Spring Cloud)
announcement - icon

让我们开始使用 Spring Cloud 的微服务架构

>> 加入 Pro 并下载电子书

1. 简介

在本教程中,我们将展示如何轻松地将 AzureAD 用作 Spring Boot 应用程序的身份提供程序。

2. 概述

微软的 AzureAD 是一种全面的身份管理产品,被全球许多组织使用。它支持多种登录机制和控制,为组织的应用组合中的用户提供单点登录体验。

此外,正如微软的起源一样,AzureAD 与现有的 Active Directory 安装集成良好,许多组织已经将其用于企业网络的身份和访问管理 这允许管理员授予现有用户访问应用程序的权限,并使用他们已经习惯的相同工具管理他们的权限。

3. 集成 AzureAD

从基于 Spring Boot 的应用程序的角度来看,AzureAD 表现为符合 OIDC 标准的身份提供程序。 这意味着我们可以通过仅配置所需的属性和依赖项来与 Spring Security 一起使用它。

为了说明 AzureAD 集成,我们将实现一个 保密客户端,其中访问代码交换授权码发生在服务器端。 此流程不会将访问令牌暴露给用户的浏览器,因此被认为比公共客户端替代方案更安全。

4. Maven 依赖

我们首先为基于 Spring Security 的 WebMVC 应用程序添加所需的 maven 依赖项

<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 Central 上找到

5. 配置属性

接下来,我们将添加用于配置客户端所需的 Spring Security 属性。 一个好的做法是将这些属性放在一个专门的 Spring profile 中,这使得应用程序增长时更容易维护。 我们将此 profile 命名为 azuread,使其用途清晰。 因此,我们将相关属性添加到 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: externally provided
            #client-secret: externally provided         
            scope:
            - openid
            - email
            - profile

在 provider 部分,我们定义了一个 azure provider。 AzureAD 支持 OIDC 标准的端点发现机制,因此我们只需要配置 issuer-uri 属性。

此属性具有双重目的:首先,它是客户端追加发现资源名称以获取下载实际 URL 的基本 URI。 其次,它还用于检查 JSON Web Token (JWT) 的真实性。 例如,由身份提供程序创建的 JWT 的 iss 断言必须与 issuer-uri 值相同。

对于 AzureAD,issuer-uri 始终采用 https://login.microsoftonline.com/my-tenant-id/v2.0 的形式,其中 my-tenant-id 是您的租户的标识符。

registration 部分,我们定义了 azure-dev 客户端,它使用先前定义的 provider。 我们还必须通过 client-id 和 client-secret 属性提供客户端凭据。 我们将在本文稍后介绍如何在 Azure 中注册此应用程序时再回来讨论这些属性。

最后,scope 属性定义了此客户端将在授权请求中包含的一组范围。 在这里,我们请求 profile 范围,该范围允许此客户端应用程序请求标准的 userinfo 端点。 此端点返回存储在 AzureAD 用户目录中的可配置信息集。 这些可能包括用户的首选语言和区域设置数据等。

6. 客户端注册

如前所述,**我们需要在 AzureAD 中注册客户端应用程序,以获取所需属性client-idclient-secret 的实际值**。假设我们已经拥有 Azure 帐户,第一步是登录到 Web 控制台,并使用左上角菜单选择 *Azure Active Directory* 服务页面

AD Home

在 *Overview*(概览)部分,我们可以获取需要在 issuer-uri 配置属性中使用的租户标识符。接下来,我们将点击 *App Registrations*(应用注册),这将我们带到现有应用程序列表,然后点击“New Registration”(新注册),显示客户端注册表单。在这里,我们必须提供三条信息

  • 应用程序名称
  • 支持的帐户类型
  • 重定向 URI

让我们详细介绍这些项目。

6.1. 应用程序名称

我们在此处输入的值将在身份验证过程中显示给最终用户。因此,我们应该选择一个对目标受众有意义的名称。让我们使用一个非常缺乏想象力的名称:“Baeldung Test App”(Baeldung 测试应用)

New App Name

我们不必太担心正确命名。**AzureAD 允许我们随时更改它,而不会影响已注册的应用程序。** 重要的是要注意,虽然此名称不必唯一,但让多个应用程序使用相同的显示名称不是一个明智的做法。

6.2. 支持的帐户类型

在这里,我们有一些选项可供根据应用程序的目标受众选择。**对于旨在供组织内部使用的应用程序,第一个选项(“仅此组织目录中的帐户”)通常是我们想要的。**这意味着即使应用程序可以从互联网访问,只有组织内的用户才能登录

New App Account Type

其他可用选项增加了接受来自其他 AzureAD 支持的目录(如使用 Office 365 的任何学校或组织)以及在 Skype 和/或 Xbox 上使用的个人帐户的功能。

虽然不太常见,我们也可以稍后更改此设置,但如文档中所述,用户在更改后可能会收到错误消息。

6.3. 重定向 URI

最后,我们需要提供一个或多个可接受的授权流程目标的重定向 URI。 我们必须选择与 URI 关联的“平台”,这转化为我们正在注册的应用程序类型

  • Web(Web):授权码与访问令牌交换发生在后端
  • SPA(单页应用程序):授权码与访问令牌交换发生在前端
  • Public Client(公共客户端):用于桌面和移动应用程序。

在我们的例子中,我们将选择第一个选项,因为这是我们用于用户身份验证的选项。

至于 URI,我们将使用值 https://:8080/login/oauth2/code/azure-dev。 该值来自 Spring Security 的 OAuth 回调控制器的路径,默认情况下,它期望在 /login/oauth2/code/{registration-name} 处接收响应代码。在这里,{registration-name} 必须与配置的 registration 部分中的一个键匹配,在我们的例子中是 azure-dev

同样重要,AzureAD 强制使用 HTTPS 作为这些 URI,但localhost 除外。 这可以在不需要设置证书的情况下启用本地开发。 稍后,当我们迁移到目标部署环境(例如 Kubernetes 集群)时,我们可以添加其他 URI。

请注意,该键的值与 AzureAD 的注册名称没有直接关系,尽管使用与使用位置相关的名称是合理的。

6.4. 添加客户端密钥

一旦我们在初始注册表单上按下注册按钮,我们将看到客户端信息页面

App Overview

Essentials 部分在左侧显示了应用程序 ID,对应于我们的属性文件中的 client-id 属性。要生成新的客户端密钥,现在我们将点击 Add a certificate or secret,这将带我们进入 Certificates & Secrets 页面。接下来,我们将选择 Client Secrets 选项卡并点击 New client secret  以打开密钥创建表单。

App Add Secret

在这里,我们将为该密钥提供一个描述性名称并定义其过期日期。我们可以选择预配置的其中一种时长,或选择自定义选项,后者允许我们定义开始和结束日期。

截至本文撰写之时,客户端密钥最多有效期为两年。这意味着我们必须建立一个密钥轮换流程,最好使用自动化工具,例如 Terraform。 两年可能看似很长,但在企业环境中,运行多年才被替换或更新的应用程序很常见。

点击 Add 后,新创建的密钥将出现在客户端凭据列表中。

App Credentials List

我们必须立即将密钥值复制到安全的位置,因为一旦离开此页面将不再显示它。 在我们的例子中,我们将该值直接复制到应用程序的属性文件中,在 client-secret 属性下。

无论如何,我们必须记住这是一个敏感值!在将应用程序部署到生产环境时,通常会通过一些动态机制(例如 Kubernetes secret)提供此值。

7. 应用程序代码

我们的测试应用程序有一个控制器,用于处理对根路径的请求,记录有关传入身份验证的信息,并将请求转发到 Thymeleaf 视图。在那里,它将渲染一个包含当前用户信息的页面。

实际控制器的代码非常简单。

@Controller
@RequestMapping("/")
public class IndexController {

    @GetMapping
    public String index(Model model, Authentication user) {
        model.addAttribute("user", user);
        return "index";
    }
}

视图代码使用 user 模型属性创建一个包含有关身份验证对象和所有可用声明信息的漂亮表格。

8. 运行测试应用程序

准备好所有组件后,现在我们可以运行该应用程序了。由于我们使用了具有 AzureAD 属性的特定配置文件,我们需要激活它。 使用 Spring Boot 的 maven 插件运行应用程序时,我们可以使用 spring-boot.run.profiles 属性来执行此操作。

mvn -Dspring-boot.run.profiles=azuread spring-boot:run

现在,我们可以打开浏览器并访问 https://:8080。Spring Security 将检测到此请求尚未经过身份验证,并将我们重定向到 AzureAD 的通用登录页面。

Sign in

具体的登录顺序会根据组织的设置而异,但通常包括填写用户名或电子邮件并提供密钥。如果已配置,它还可以请求第二个身份验证因素。但是,如果我们当前已在同一浏览器中登录到同一 AzureAD 租户中的另一个应用程序,它将跳过登录顺序 - 这就是单点登录的意义所在。

第一次访问我们的应用程序时,AzureAD 还会显示应用程序的同意表单。

Sign in to your account

虽然此处未介绍,但 AzureAD 支持自定义登录 UI 的几个方面,包括特定于区域的自定义。此外,可以完全绕过授权表单,这对于授权内部应用程序很有用。

一旦授予权限,我们将看到我们的应用程序的主页,如下所示(部分显示)。

User Info Page

我们可以看到,我们已经可以访问用户的基本信息,包括他的/她的姓名、电子邮件,甚至可以获取他的/她的头像的 URL。 不过,有一个令人恼火的细节:Spring 为用户名选择的值不太友好。

让我们看看如何改进这一点。

9. 用户名映射

Spring Security 使用 Authentication 接口来表示经过身份验证的 Principal。 该接口的具体实现必须提供 getName() 方法,该方法返回一个值,通常用作身份验证域内用户的唯一标识符。

使用基于 JWT 的身份验证时,Spring Security 默认会将标准的 sub claim 值用作 Principal 的名称。 查看 claims,我们看到 AzureAD 将此字段填充为内部标识符,不适合显示目的。

幸运的是,在这种情况下有一个简单的解决方法。 我们所要做的就是选择一个可用的属性,并将其名称放在提供程序的 user-name-attribute 属性上

spring:
  security:
    oauth2:
      client:
        provider:
          azure:
            issuer-uri: https://login.microsoftonline.com/xxxxxxxxxxxxx/v2.0
            user-name-attribute: name
... other properties omitted

在这里,我们选择了 name claim,因为它对应于用户的完整姓名。 另一个合适的候选者是 email 属性,如果我们的应用程序需要在某些数据库查询中使用它的值,那么它可能是一个不错的选择。

现在,我们可以重新启动应用程序,看看此更改的影响

User Info Page

好多了!

10. 获取组成员资格

仔细检查可用的 claims 显示,其中没有关于用户组成员资格的信息Authentication 中可用的唯一 GrantedAuthority 值是与客户端配置中包含的请求范围相关联的值。

如果我们需要做的只是限制对组织成员的访问,这可能就足够了。 但是,通常我们会根据分配给当前用户的角色授予不同的访问级别。 此外,将这些角色映射到 AzureAD 组可以重用可用的流程,例如用户入职和/或重新分配。

为了实现这一点,我们必须指示 AzureAD 在我们将接收到的 idToken 中包含组成员资格,在授权流程期间。

首先,我们必须转到我们的应用程序页面,并在右侧菜单中选择 Token Configuration。 接下来,我们将点击 Add groups claim,这将打开一个对话框,我们将在其中定义此 claim 类型所需的详细信息

Group mapping

我们将使用常规 AzureAD 组,因此我们将选择第一个选项(“安全组”)。 此对话框还具有为每个受支持的令牌类型配置的其他选项。 我们现在将保留默认值。

单击 Save 后,应用程序的 claims 列表将显示组 claims

Group mapping

现在,我们可以返回到我们的应用程序,看看此配置的效果

User Info Page

11. 将组映射到 Spring Authorities

组 claim 包含一个列表,其中包含与用户分配的组相对应的对象标识符。 但是,Spring 并不会自动将这些组映射到 GrantedAuthority 实例。

这样做需要一个自定义 OidcUserService,如 Spring Security 的 文档 中所述。 我们的实现使用外部映射来“丰富”标准的 OidcUser 实现,并添加额外的权限。 我们使用一个 @ConfigurationProperties 类,我们在其中放置了所需的信息

  • 从哪里获取组列表(“groups”)的声明名称
  • 从此提供程序映射的权限的前缀
  • 对象标识符到GrantedAuthority值的映射

使用组到列表的映射策略使我们能够应对希望使用现有组的情况。它还有助于使应用程序的角色集与组分配策略分离。

典型的配置如下所示

baeldung:
  jwt:
    authorization:
      group-to-authorities:
        "ceef656a-fca9-49b6-821b-xxxxxxxxxxxx": BAELDUNG_RW
        "eaaecb69-ccbc-4143-b111-xxxxxxxxxxxx": BAELDUNG_RO,BAELDUNG_ADMIN

对象标识符在Groups页面上可用

Group list

一旦完成所有映射并重新启动应用程序,我们就可以测试应用程序。这是属于这两个组的用户获得的结果

User Info Page

它现在有三个新的权限,对应于映射的组。

12. 结论

在本文中,我们展示了如何使用 AzureAD 与 Spring Security 验证用户,包括用于演示应用程序所需的配置步骤。

支持本文的代码可在 GitHub 上获取。 一旦你Baeldung Pro 会员 身份登录,就开始学习并在项目上进行编码。
Baeldung Pro – NPI EA (类别 = Baeldung)
announcement - icon

Baeldung Pro 具有完全无广告以及最终具有深色模式,提供干净的学习体验

>> 探索干净的 Baeldung

一旦早期采用者的席位全部用完,价格将上涨并保持在每年 33 美元。

电子书 – HTTP 客户端 – NPI EA (类别=HTTP 客户端)
announcement - icon

Apache HTTP Client 是一个非常强大的库,适用于简单和高级用例,在测试 HTTP 端点时尤其适用。 查看我们的指南,涵盖基本请求和响应处理,以及安全性、Cookie、超时等。

>> 下载电子书

电子书 – Java 并发 – NPI EA (分类=Java 并发)
announcement - icon

在应用程序中处理并发可能是一个棘手的过程,其中包含许多 潜在的陷阱。 扎实的掌握基本知识将有助于最大程度地减少这些问题。

通过我们的 Java 并发 指南开始了解多线程应用程序

>> 下载电子书

电子书 – Java Streams – NPI EA (分类=Java Streams)
announcement - icon

自从 Java 8 引入以来,Stream API 已成为 Java 开发的基础。 基本操作,例如迭代、过滤、映射元素序列,使用起来看似很简单。

但这些也可能被过度使用并陷入一些常见陷阱。

更好地了解 Stream 的工作方式 以及如何将其与其他语言功能结合使用,请查看我们关于 Java Streams 的指南

>> 加入 Pro 并下载电子书

电子书 – 持久化 – NPI EA (分类=持久化)
announcement - icon

您在努力实现正确的持久化层 Spring 吗?

探索电子书

课程 – LS – NPI EA (类别=REST)

announcement - icon

从 Spring Boot 开始,通过 Learn Spring 课程了解核心 Spring。

>> 查看课程

合作伙伴 – Moderne – NPI EA (标签=重构)
announcement - icon

现代 Java 团队行动迅速——但代码库并不总是跟上。 框架会发生变化,依赖关系会漂移,技术债务会累积,直到它开始拖慢交付速度。 OpenRewrite 就是为此而构建的:一个开源重构引擎,可在保持开发人员意图不变的同时自动化重复的代码更改。

由 Moderne 的 OpenRewrite 创建者和维护者领导的每月培训系列,将介绍实际的迁移和现代化模式。 无论您是重构配方的新手,还是准备编写自己的配方,您都将学习以安全且可扩展的方式进行重构的实用方法。

如果您曾经希望重构感觉像编写代码一样自然——并且一样快速——这是一个很好的起点

课程 – LSS – NPI (类别=安全/Spring Security)
announcement - icon

我刚刚宣布了新的Learn Spring Security 课程,其中包含完全关注 Spring Security 中新的 OAuth2 堆栈的材料。

>> 查看课程

电子书 Jackson – NPI EA – 3 (类别 = Jackson)
电子书 – 电子书指南 Spring Cloud – NPI (cat=Cloud/Spring Cloud)
2 条评论
最早
最新
内联反馈
查看所有评论
© .