通过OAuth 2.0和Okta使用安全的服务器到服务器通信构建Spring Boot应用
“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证。
大多数OAuth 2.0指南都围绕用户的上下文,即使用Google,Github,Okta等登录到应用程序,然后代表该用户执行某些操作。 尽管有用,但这些指南会忽略没有用户且只有一项服务连接到另一项服务的服务器到服务器的通信。 值得庆幸的是,Okta也在此方面为应用程序安全领域提供了帮助。
OAuth 2.0客户端凭据授予类型专门用于不存在用户(CRON作业,计划任务,其他数据工作负载等)的情况。 由于没有最终用户或浏览器需要处理,因此与其他OAuth流相比,此流的显示效果不那么出色,但与以用户为中心的更为复杂的OAuth 2.0授予类型相比,该流更易于理解。 在本教程中,我们将介绍OAuth 2.0客户端凭据授予类型,以及如何在Spring Boot中部署它以实现安全的服务器间通信。
OAuth 2.0客户端凭据授予
客户端凭据授予的目标是允许两台计算机安全地通信。 在这种授予类型中,您有一个客户端(将其视为您的应用程序)向另一个服务(这是您的资源服务器)发出API请求。
为了帮助说明为什么此流程很重要,让我们退后一步,谈谈在OAuth 2.0之前所做的工作。
注意 :如果您是OAuth专业人士,则可以跳到下面的代码示例,或在GitHub上查看示例。
在OAuth 2.0之前,开发人员处理服务器到服务器身份验证的方式是使用HTTP Basic Auth。 从本质上讲,这归结为开发人员将在每次请求时通过服务器的唯一用户名和密码(通常称为ID和机密)发送。 然后,API服务将通过连接到用户存储(数据库,LDAP等)来验证每个用户名和密码,以验证凭据。
这种方法有一些缺点和暴露点:
- 上图中的每个应用程序都处理用户名和密码
- 可能需要第二个用户名和密码才能连接到用户存储
- 每个请求使用相同的用户名和密码
有多种方法可以帮助减轻这些风险,但这超出了本文的范围。
OAuth 2.0客户端凭据授予被创建来帮助解决HTTP Basic Auth所遇到的问题。 尽管客户端仍使用用户名和密码(称为client_id
和client_secret
),但不是将它们根据每个请求直接发送到API服务,而是通过授权服务器将其交换为令牌。
授权服务器返回一个临时访问令牌(使用该令牌直到到期)。 然后,客户端在与资源服务器进行通信时使用此访问令牌,这意味着每个有效期仅在网络上共享一次客户端最敏感的数据(标识和机密),从而大大降低了遭受破坏的可能性。 一旦资源服务器收到带有访问令牌的传入请求,它将通过与授权服务器进行对话来验证令牌。
在本文的结尾,我将讨论几种进一步减少网络呼叫数量的方法,但首先举一个例子!
让我们构建一个OAuth 2.0客户端凭据应用程序!
聊够了,让我们做点什么! 我将向您展示如何使用两个应用程序( client
和server
通过Spring实现客户端凭据授予类型。 服务器将具有单个端点,该端点将返回“每日消息”。 客户端将是一个简单的命令行应用程序; 您可以轻松地将其替换为后端Web应用程序,CRON作业或任何其他后端脚本。
设置您的授权服务器
为简单起见,您将使用Okta创建OAuth 2.0授权服务器。 这将处理上面提到的所有客户端凭据授予内容。 您需要使用Okta吗? 一点也不! 您可以使用任何需要的OAuth 2.0兼容服务器-但由于我们的服务是免费且易于使用的,因此可以加快此过程。
如果您还没有免费的开发者帐户,请转到developer.okta.com ,然后单击注册。 完成后,您将获得两条信息,您的Okta基本URL如下所示: dev-123456.oktapreview.com
,以及一封有关如何激活帐户的说明的电子邮件。
激活帐户后,仍然在Okta开发者控制台中,然后需要创建一个应用程序和一个自定义OAuth范围。 该应用程序将为您提供客户端ID和密码,而自定义范围将您的访问令牌限制为该示例。
单击应用程序菜单项,然后单击添加应用程序 ,然后单击服务 -> 下一步 。 将名称更改为您想要的名称(我将使用“我的MOD应用”),然后单击完成 。
下一步需要客户端ID和客户端机密值。
接下来,为您的应用程序创建一个自定义范围 。
从菜单栏中选择API- > Authorization Servers 。 记住发行者的URI值; 您将在下一步中使用它。 通过单击编辑铅笔来编辑授权服务器,然后单击范围 -> 添加范围 。 用custom_mod
填写名称字段,然后按Create 。
有趣的东西!
创建资源服务器
该资源服务器(又称API服务)将过于简单,由一个/mod
端点组成。 在命令行上使用Spring Initializer创建一个新项目:
curl https://start.spring.io/starter.tgz \-d artifactId=creds-example-server \-d dependencies=security,web \-d language=java \-d type=maven-project \-d baseDir=creds-example-server \
| tar -xzvf -# change into the new directory
cd creds-example-server
您还需要手动将另外一个依赖项添加到pom.xml
:
<dependency><groupId>org.springframework.security.oauth.boot</groupId><artifactId>spring-security-oauth2-autoconfigure</artifactId><version>2.0.0.RELEASE</version>
</dependency>
注意 :我还将DemoApplication
重命名为ServerApplication
因为我们将很快创建另一个应用程序。
更新ServerApplication
以包含@EnableResourceServer
批注并添加一个简单的REST控制器:
@EnableResourceServer
@SpringBootApplication
public class ServerApplication {public static void main(String[] args) {SpringApplication.run(ServerApplication.class, args);}/*** Allows for @PreAuthorize annotation processing.*/@EnableGlobalMethodSecurity(prePostEnabled = true)protected static class GlobalSecurityConfiguration extends GlobalMethodSecurityConfiguration {@Overrideprotected MethodSecurityExpressionHandler createExpressionHandler() {return new OAuth2MethodSecurityExpressionHandler();}}@RestControllerpublic class MessageOfTheDayController {@GetMapping("/mod")@PreAuthorize("#oauth2.hasScope('custom_mod')")public String getMessageOfTheDay(Principal principal) {return "The message of the day is boring for user: " + principal.getName();}}
}
现在是时候配置应用程序了! 我将application.properties
文件重命名为application.yml
并将其更新为包括:
security:oauth2:client:clientId: {client-id-from-above}clientSecret: {client-secret-from-above}resource:tokenInfoUri: {issuer-uri-from-above}/v1/introspect
就是这样:几行代码和几行配置! Spring Boot将自动处理访问令牌的验证,您只需要担心代码。
启动它并使其运行:
./mvn spring-boot:run
如果需要,您可以尝试访问http://localhost:8080/mod
,它将以HTTP 401 UNAUTHORIZED
响应。
创建OAuth 2.0客户端
接下来,您将创建一个简单的命令行客户端(您可以在任何类型的应用程序中轻松复制此逻辑)。
打开一个新的终端窗口,并使用Spring Initializer创建第二个应用程序:
curl https://start.spring.io/starter.tgz \-d artifactId=creds-example-client \-d dependencies=security \-d language=java \-d type=maven-project \-d baseDir=creds-example-client \
| tar -xzvf -# change into the new directory
cd creds-example-client
与之前相同,在您的pom.xml
添加Spring OAuth 2.0库作为依赖项:
<dependency><groupId>org.springframework.security.oauth.boot</groupId><artifactId>spring-security-oauth2-autoconfigure</artifactId><version>2.0.0.RELEASE</version>
</dependency>
这次,我将从定义配置开始(再次将application.properties
重命名为application.yml
):
example:baseUrl: http://localhost:8080oauth2:client:grantType: client_credentialsclientId: {client-id-from-above}clientSecret: {client-secret-from-above}accessTokenUri: {issuer-uri-from-above}/v1/tokenscope: custom_mod
我已在example
下为配置命名空间,因为您可以连接到多个服务器。
我配置了一些属性:
baseUrl
是示例服务器的基本URLgrantType
定义连接的授予类型clientId
和clientSecret
与上述相同accessTokenUri
定义用于获取访问令牌的URIscope
是我们在上面创建的自定义范围
最后是我们的ClientApplication
(从DemoApplication
重命名):
@SpringBootApplication
public class ClientApplication implements CommandLineRunner {private final Logger logger = LoggerFactory.getLogger(ClientApplication.class);@Value("#{ @environment['example.baseUrl'] }")private String serverBaseUrl;public static void main(String[] args) {SpringApplication.run(ClientApplication.class, args);}@Bean@ConfigurationProperties("example.oauth2.client")protected ClientCredentialsResourceDetails oAuthDetails() {return new ClientCredentialsResourceDetails();}@Beanprotected RestTemplate restTemplate() {return new OAuth2RestTemplate(oAuthDetails());}@Overridepublic void run(String... args) {logger.info("MOD: {}", restTemplate().getForObject(serverBaseUrl + "/mod", String.class));}
}
我想谈谈几件事:
CommandLineRunner
界面添加了一个run
方法,该方法在初始化后自动被调用,应用程序在退出该方法后退出- 我创建了一个
ClientCredentialsResourceDetails
bean,该bean绑定到我的配置属性:example.oauth2.client
- 我使用
OAuth2RestTemplate
代替标准的RestTemplate
它自动管理所有OAuth 2.0访问令牌交换并设置Authentication: Bearer
标头值。 基本上,它可以处理所有OAuth详细信息,因此您无需担心其中任何一个!
使用./mvnw spring-boot:run
运行该应用程序,您应该看到类似于以下内容的控制台输出:
2018-03-20 12:56:10.058 INFO 15833 --- [main] c.e.c.ClientApplication: MOD: The message of the day is boring for user: 0oabcd12yz2EpHuis75s3
客户端已成功与服务器通信! 还不错吧? 在短短的几行代码中,您就可以设置OAuth 2.0授权服务器并进行配置,还可以创建两个Spring应用程序(一个客户端和一个服务器),现在可以使用OAuth 2.0客户端凭据授予类型安全地进行通信!
注意:如果您看到401
或500
异常,请再次检查您的application.yml
配置文件是否包含正确的信息。
额外的功劳:减少对授权服务器的呼叫次数
上面的第二个序列图似乎比第一个更复杂,即使考虑到访问令牌的重用也是如此。 访问令牌是不透明的,它们后面没有任何规范,格式由授权服务器实现。
在Okta,我们使用签名的JWT,这意味着您可以在本地对其进行验证,而不是根据每个请求从API服务向授权服务器提出额外的请求。
我们有几种不同语言的帮助程序库和一个Spring Boot入门程序 ,它将为您处理本地验证。
注意:在撰写本文时, okta-spring-boot
仅适用于Spring Boot 1.5.x,请参见GitHub上的示例
进一步了解OAuth 2.0和Okta
在这篇文章中,我已经解释了OAuth 2.0客户端凭据授予类型,并创建了用于执行此流程的小型演示应用程序(使用Spring Boot,只需很少的代码!)。 如果您有任何疑问,请将其留在下面或在Twitter上ping我( @briandemers )或@OktaDev 。
有关OAuth 2.0和Okta的更多信息,请查看以下资源:
- OAuth到底是什么?
- OAuth.com
- 使用Spring Boot和OAuth保护您的SPA
使用Spring Boot和OAuth 2.0进行安全的服务器到服务器通信最初于2018年4月2日发布在Okta开发者博客上。
“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证。
翻译自: https://www.javacodegeeks.com/2018/06/spring-boot-server-to-server-communication-okta.html
通过OAuth 2.0和Okta使用安全的服务器到服务器通信构建Spring Boot应用相关推荐
- 通过OAuth 2.0和Okta构建具有安全的服务器到服务器通信的Spring Boot应用
"我喜欢编写身份验证和授权代码." 〜从来没有Java开发人员. 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证. 大多数O ...
- Openshift:使用Java 8在Wildfly 8.2.0上构建Spring Boot应用程序
OpenShift DIY墨盒是在OpenShift上测试不受支持的语言的好方法. 但是它不具有可伸缩性(您可以在此处为可伸缩DIY墨盒投票),这使得它很难与生产级Spring Boot应用程序一起使 ...
- OAuth 2.0实现分布式认证授权-jwt的认证服务器和资源服务器配置(5)
一 jwt 1.1 jwt? JSON Web Token ( JWT )是一个开放的行业标准( RFC 7519 ),它定义了一种简介的.自包含的协议格式,用于 在通信双方传递json对象 , 传递 ...
- TIMO 后台管理系统 v2.0.1 发布,加入 jwt 身份验证组件,基于 Spring Boot
TIMO后台管理系统v2.0.1版本已发布(基于SpringBoot),更新日志: 新增:加入JWT TOKEN鉴权机制,实现多端的权限验证! 更新:模块化全局统一异常处理机制及项目配置,降低模块间的 ...
- oauth2_带有Spring Security的OAuth 2.0快速指南
oauth2 "我喜欢编写身份验证和授权代码." 〜从来没有Java开发人员. 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验 ...
- 带有Spring Security的OAuth 2.0快速指南
"我喜欢编写身份验证和授权代码." 〜从来没有Java开发人员. 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证. 在构建W ...
- 使用Spring Security和OAuth 2.0保护Spring微服务架构
"我喜欢编写身份验证和授权代码." 〜从来没有Java开发人员. 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证. 每个开发 ...
- OAuth 2.0 学习
写在前面: 在此感谢 阮一峰 老师,以下内容是看了阮一峰老师 OAuth 2.0 的笔记.自己理解记录下来,以便自己后续学习或帮助到一些人. OAuth 2.0 是目前最流行的授权机制,用来授权第三方 ...
- Spring Boot 2.0 都更新了什么
Spring Boot 2.0 都更新了什么 2018 年 3 月 1 号 Spring Boot 2.0.0.RELEASE 正式发布,这是 Spring Boot 1.0 发布 4 年之后第一次重 ...
最新文章
- Asp.net(asp,jsp)+JavaScript动态实现添加数据行
- 关于win10更新后谷歌浏览器打开卡慢或者无法上网的问题解决
- 划船训练常见错误:含胸驼背肩胛骨活动不足
- An unspecified error occurred!
- 正确的理解MySQL的MVCC及实现原理
- 背景图(css sprite)尺寸设置,DIPS,设备像素比,Retina,,border 1px问题
- BD和ts是什么意思
- wordpress企业主题
- java 克隆对象_Java中克隆(Clone)一个对象
- 如何一次性下载全国谷歌卫星影像地图数据
- 目标检测第5步-使用keras版YOLOv3训练
- 设计模式-鸭子类型1
- ui设计需要美术功底吗,没有美术功底如何快速提高
- C语言编译执行的全过程
- #笔记-面向对象基础知识
- ATAT 报错Impossible to natch point correlations
- matlab一维数组截取,Matlab创建一维数组的具体操作讲解
- EC20 不常用AT 命令 整理
- 通过装饰器模式为 RoundedBitmapDrawable 加边框
- 道是有情却无情 [转]
热门文章
- P3911 最小公倍数之和
- FFT/NTT卷积神级副本
- NOMURA Programming Contest 2021(AtCoder Regular Contest 121)
- 数论练习二之BSGS算法——随机数生成器,Matrix,Lunar New Year and a Recursive Sequence,Fermat‘s Last Theorem
- P7600-[APIO2021]封闭道路【堆,dp】
- CF757F-Team Rocket Rises Again【最短路,DAG支配树】
- P6046-纯粹容器【数学期望,组合数】
- P3952-时间复杂度【模拟】
- ssl1746-商务旅行【tarjan,LCA】
- 【结论】游戏(jzoj 1984)