安全是一个需要深入理解的复杂主题。此外,使用 OAuth 2.0 和 OpenID Connect 规范为基于微服务的复杂系统实现认证和授权更加困难。像 Spring Security 这样的框架和库有助于降低复杂性,但要正确实现 Security 仍然需要经历陡峭的学习曲线。
在本 Spring Security OAuth2 系列教程中,我将与大家分享如何使用 Spring Security OAuth2 为基于微服务的应用实现认证和授权。
有许多身份提供商(Identity Provider)解决方案,如 Keycloak、Okta、Auth0 等。在本系列中,我们将使用开源身份和访问管理解决方案 Keycloak。
我不是安全、OAuth2 和 Keycloak 方面的专家。我只是根据自己对这些概念的理解与大家分享我的学习心得。如果你认为其中有任何概念或解释不正确,请指正。
我们不会直接进入 Spring Security OAuth2 的实现,而是先从概念开始学习,循序渐进。
学习 OAuth 2.0 和 OpenID Connect 的第一步是了解一些核心概念,如 OAuth2 中的各种角色(Role)是什么、各种授权方式(Grant Type)是什么以及何时使用哪种方式。
简而言之,在 OAuth2 系统中,有各种不同的组件扮演着不同的角色,也有不同的方法来验证用户身份。
- 资源所有者(Resource Owner): 资源所有者通常是终端终用户,他授权应用(客户端)访问他/她的账户。
- 资源服务器(Resource Server): 托管受保护资源的服务器。这是你要访问的 API。
- 客户端(Client): 代表资源所有者请求访问受保护资源的应用(资源所有者正在使用的应用)。
- 授权服务器(Authorization Server): 对资源所有者进行身份验证并在成功授权后发放访问令牌(Access Token)的服务器。
- 授权码模式
- PKCE 授权码模式
- 客户端凭证模式
- 隐式/简化模式(不推荐)
- 资源所有者密码模式(不推荐)
OAuth 2.0 只涉及授权(Authorization),而不涉及身份认证(Authentication)。OpenID Connect 规范是为解决身份认证问题而制定的,它是 OAuth 2.0 的基础层。
在本系列的后续部分中,我们将进一步了解在何时使用哪种授权方式。
如前所述,我们将使用 Keycloak 来实现基于 OAuth2.0/OpenID Connect 的 Security。
首先使用 docker compose 安装 Keycloak。
启动 Keycloak 容器,如下:
我们以开发模式启动了 keycloak 容器,并使用环境变量配置了 用户凭证。容器的 端口映射到主机的 端口。
现在你可以通过 访问 Keycloak 管理控制台。
摘自 Keycloak 的文档:
一个 Realm 管理一组用户、凭证、角色和组。用户属于并登录到一个 Realm。Realm 之间相互隔离,只能管理和验证其控制的用户。
你可以创建一个新的 Realm,将一组客户端、用户、角色等与其他客户端、用户、角色等隔离开来。
使用 登录管理控制台后,左上角有一个下拉菜单,其中提供了创建新 Realm 的选项。
输入 Realm 名称:,设置 为 ,然后点击 。
创建成功后,应自动选择新 Realm。如果没有,请从下拉菜单中选择 Realm。
要创建新客户端,请点击左侧导航菜单上的 ,然后点击 按钮。
- General Settings:
- Client type:OpenID Connect
- Client ID:messages-webapp
- Capability config:
- Client authentication:On
- Authorization:Off
- Authentication flow:选中 ,取消选中其余复选框
- Login settings:
- Root URL:
- Home URL:
- Valid redirect URIs:
- Valid post logout redirect URIs:
- Web origins:
使用上述配置创建客户端后,你将进入新创建的客户端 “Settings” 页面。单击 “Credentials” 选项卡并复制 “Client secret” 值。
在本例中,“Client secret” 是:qVcg0foCUNyYbgF0Sg52zeIhLYyOwXpQ.
Keycloak Client AccessType
如果你使用过 Keycloak 的早期版本,你可能会知道有一个名为 的选项,其可能的值为 、、。在新版本中,没有明确的 字段。
- 如果 Client authentication 是 Off,则是公共(public)客户端。
- 如果 Client authentication 是 On,则是保密(confidential)客户端。
- 如果 Client authentication 是 On,但是未启用任何 Authentication flow 选项,那么是 Bearer-only 客户端。
现在你可能会问,什么是公开客户端、保密客户端和 Bearer-only 客户端?
- 公共客户端是面向用户的应用,没有服务器后台,如单页应用。它们不能安全地存储任何敏感数据,如 Client secret。
- 保密客户端是在后端服务器上运行的 Web 应用,如 Spring MVC 应用。它们可以安全地存储 Client secret 等敏感数据。
- Bearer-only 客户端通常是仅后台应用(API),它需要调用者提供 。如果调用者没有提供有效的 ,它就会简单地返回 (未授权)响应,而不会启动身份认证流程。
现在,让我们创建一个用户。点击左侧导航菜单上的 “Users”,然后点击 “Add user” 按钮。
创建一个具有以下详细信息的用户:
- Username:siva
- Email:
- Email verified:Yes
- First name:Siva
- Last name:Katamreddy
创建用户后,转到 “Credentials” 选项卡,将 “Password” 设置为 ,“Temporary” 选项设置为 “Off”。
现在你就可以使用 用户的凭证登录到 Realm 了。
访问 并使用 登录。
好了,现在我们已经完成了初始设置,可以开始探索 OAuth 2.0 和 OpenID Connect 了。
在下一篇 Spring Security OAuth 2 教程 - 2:授权码模式 文章中,我们将了解如何通过 “授权码模式”(Authorization Code Flow)获取访问令牌(Access Token)。
参考:
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/1455.html