通过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_idclient_secret ),但它们不会通过每个请求将它们直接发送到API服务,而是通过授权服务器来交换令牌。

服务器到服务器的通信

授权服务器返回一个临时访问令牌(使用该令牌直到到期)。 然后,客户端在与资源服务器进行通信时使用此访问令牌,这意味着每个有效期仅在网络上共享一次客户端最敏感的数据(标识和机密),从而大大降低了遭受破坏的可能性。 一旦资源服务器收到带有访问令牌的传入请求,资源服务器将通过与授权服务器对话来验证令牌。

在本文的结尾,我将讨论几种进一步减少网络呼叫数量的方法,但首先,举一个例子!

让我们构建一个OAuth 2.0客户端凭据应用程序!

聊够了,让我们做点什么! 我将向您展示如何使用两个应用程序( clientserver通过Spring实现客户端凭据授予类型。 服务器将具有单个端点,该端点将返回“每日消息”。 客户端将是一个简单的命令行应用程序; 您可以轻松地将其替换为后端Web应用程序,CRON作业或任何其他后端脚本。

设置您的授权服务器

为简单起见,您将使用Okta创建OAuth 2.0授权服务器。 这将处理上面提到的所有客户端凭据授予内容。 您需要使用Okta吗? 一点也不! 您可以使用任何需要的OAuth 2.0兼容服务器-但由于我们的服务是免费且易于使用的,因此可以加快此过程。

如果您还没有免费的开发者帐户,请访问developer.okta.com ,然后单击注册。 完成后,您将获得两条信息,您的Okta基本URL如下所示: dev-123456.oktapreview.com ,以及一封有关如何激活帐户的说明的电子邮件。

激活帐户后,仍然在Okta开发者控制台中,然后需要创建一个应用程序和一个自定义OAuth范围。 该应用程序将为您提供客户端ID和密码,而自定义范围将您的访问令牌限制为该示例。

单击应用程序菜单项,然后单击添加应用程序 ,然后单击服务 -> 下一步 。 将名称更改为您想要的名称(我将使用“ My MOD App”),然后单击“完成”

下一步需要客户端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是示例服务器的基本URL
  • grantType定义连接的授予类型
  • clientIdclientSecret与上述相同
  • accessTokenUri定义用于获取访问令牌的URI
  • scope是我们在上面创建的自定义范围

最后是我们的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客户端凭据授予类型安全地进行通信!

注意:如果您看到401500异常,请再次检查您的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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/346549.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot java获取版本号_深入实践Spring Boot 实战篇,大佬整理出的PDF文档

如何使用Spring Boot 本文章将会详细介绍如何使用Spring Boot。它覆盖了构建系统&#xff0c;自动配置和运行/部署选项等主题。我们也覆盖了一些Spring Boot最佳实践。尽管Spring Boot没有什么特别的(只是一个你能消费的库)&#xff0c;但仍有一些建议&#xff0c;如果你遵循的…

6 redis 编译失败_Centos7.8环境搭建Redis主从复制和哨兵模式

本节我们搭建Redis主从复制和哨兵模式集群&#xff0c;集群的好处是把数据分散不不同的服务器上&#xff0c;解决网站中的很多高并发&#xff0c;高负载等问题&#xff0c;很好的提高网站的性能&#xff0c;也能解决mysql的数据读写问题&#xff0c;所以我们搭建集群非常有必要…

springboot异步注解_Spring Boot 2 :Spring Boot 中的响应式编程和 WebFlux 入门

【小宅按】Spring 5.0 中发布了重量级组件 Webflux&#xff0c;拉起了响应式编程的规模使用序幕。WebFlux 使用的场景是异步非阻塞的&#xff0c;使用 Webflux 作为系统解决方案&#xff0c;在大多数场景下可以提高系统吞吐量。Spring Boot 2.0 是基于 Spring5 构建而成&#x…

结尾的单词_22个以“ez”结尾的西语单词,你掌握了吗?

22 palabras que terminan en -ez22个以“-ez”结尾的西语单词ntido → nitidez 清澈&#xff0c;透明lcido → lucidez 光亮&#xff1b;清楚plido → palidez 苍白&#xff1b;暗淡rpido → rapidez 迅速cido → acidez 酸性estrecho → estrechez 狭窄esbelto → esb…

python xlwt xlrd模块详解_python操作excel之xlrd、xlwt模块详解

python操作excel主要用到xlrd和xlwt这两个库&#xff0c;即xlrd是读excel&#xff0c;xlwt是写excel的库。 可从这里下载https://pypi.python.org/pypi。下面分别记录python读和写excel. python读excel——xlrd 这个过程有几个比较麻烦的问题&#xff0c;比如读取日期、读合并单…

python应届生找工作在深圳_应届毕业程序员找工作,企业最看重你们这些地方

这篇文章来谈一下应届生找工作的问题&#xff0c;最近有很多在校大学生跟我咨询很多企业很多工作要求有工作经验&#xff0c;那这样没工作经验的人都去哪学经验&#xff0c;要求工作经验真的有必要吗&#xff1f;应届生毕业找工作&#xff0c;一直有一个困惑是什么&#xff0c;…

PHP密码问题陈婷代码_PHP实现登录注册

一、首先实现一个PHP的简单登录注册的话 我们要简单的与后端定义一下接口和传输数据的方式 并且我们要有一个phpStudy服务器。第一步&#xff1a;当我们点击注册按钮的时候数据库要接收到客户端请求的数据 第二步&#xff1a;接收到数据以后服务器要处理数据&#xff1a;1.确定…

在Spring Boot中使用Vaadin的简介

介绍 Vaadin的工作方式依赖于服务器端渲染&#xff0c;因此可以自然地集成到诸如Spring之类的框架中。 Vaadin的Spring集成已经存在了一段时间&#xff0c;并且提供了用于在Spring容器中配置和管理Vaadin的工具&#xff0c;如果您希望将Vaadin与Spring Boot结合使用&#xff0c…

excel转las文件_这3种Word、Excel格式不变的互转方法,实在太好用了

日常工作中用Word写总结、写报告&#xff0c;写分析&#xff0c;一定离不开数据支持。但在制作的过程中你一定碰到过这些问题&#xff1a;Excel里做的表格、图表&#xff0c;一复制到word就变的乱七八糟&#xff01;那么&#xff0c;有没有什么好的方法&#xff0c;即省时&…

stm32编码器正反转计数程序_光电编码器接线图分析

编码器(encoder)是将信号(如比特流)或数据进行编制、转换为可用以通讯、传输和存储的信号形式的设备。光电编码器如果按信号原理来分类的话&#xff0c;可以分为增量型编码器和绝对型编码器。旋转编码器是一种光电式旋转测量装置&#xff0c;它将被测的角位移直接转换成数字信号…

jieba库词频统计_如何用python对《三国演义》、《红楼梦》等名著开展词云分析及字频统计、出场统计等工作。...

以下以《红楼梦》为例进行设计。在制作词云图及统计之前&#xff0c;需要下载python的几个库&#xff0c;wordcloud、jieba以及imageio等&#xff0c;我的操作系统为Windows10&#xff0c;IDE环境为idle&#xff0c;下载方式就直接搜索cmd&#xff0c;打开命令提示符窗口&#…

数学史思维导图_【学科活动】思维导图展风采,数学文化提素养——庆云县第四中学(北校区)四年级数学组活动小记...

思维无限 导我所想思维的火花跨越时空&#xff0c;照亮昨天、今天和明天。人类从茹毛饮血、采集狩猎到今天足不出户购遍全球&#xff0c;人工智能、大数据信息处理融入每个人的生活。这其中&#xff0c;最大的改变就是思维方式的改变。——题记思维导图又叫心智导图&#xff0c…

k2677场效应管参数引脚_共射极放大电路,场效应管放大电路,运算放大电路

电子技术、无线电维修及SMT电子制造工艺技术绝不是一门容易学好、短时间内就能够掌握的学科。这门学科所涉及的方方面面很多&#xff0c;各方面又相互联系&#xff0c;作为初学者&#xff0c;首先要在整体上了解、初步掌握它。无论是无线电爱好者还是维修技术人员&#xff0c;你…

加载类_JVM类加载详解

类的加载器概述类加载器是JVM执行类加载机制的前提。ClassLoader的作用&#xff1a;ClassLoader是Java的核心组件&#xff0c;所有的Class都是由ClassLoader进行加载的&#xff0c;ClassLoader负责通过各种方式将Class信息的二进制数据流读入JVM内部&#xff0c;转换为一个与目…

group by用法多个字段_select的用法

select的用法 --每个员工的所有信息 select * from emp; --每个人的部门编号&#xff0c;姓名&#xff0c;薪水 select empno, ename, sal from emp; --每个人的年薪 select ename, sal*12 from emp; --计算2*3的值 select 2*3 from emp; --计算2*3的值(dual) select 2*3 from …

计算机考试打字小作文,打字练习作文(通用5篇)

打字练习作文(通用5篇)导语&#xff1a;随着计算机在人们的生活中普及&#xff0c;敲键盘打字的速度就变成了人们努力的方向。下面是小编为大家整理的打字练习作文(通用5篇)&#xff0c;欢迎阅读&#xff0c;希望大家能够喜欢。打字练习作文 篇1今天过得有些无聊&#xff0c;爸…

eclipse创建pojo_使用Eclipse Hibernate插件逐步为POJO域Java类和hbm自动生成代码

eclipse创建pojo概述&#xff1a; 在本教程中&#xff0c;我们将使用Eclipse Hibernate工具自动生成域对象和相应的hbm xml文件。 如果您正在处理大型或中型项目&#xff0c;并且开始时有超过5个以上的表&#xff0c;那么您可能会发现此插件是自动生成映射域对象java文件和相应…

c语言中x的n次方怎么表示_线性代数的本质及其在AI中的应用

线性代数是 AI 专家必须掌握的知识&#xff0c;这已不再是个秘密。如果不掌握应用数学这个领域&#xff0c;你永远就只能是「门外汉」。当然&#xff0c;学习线性代数道阻且长。数学&#xff0c;尤其是线性代数常与枯燥、复杂和毫无意义的事物联系起来。不过你还可以另辟蹊径。…

解码base64_linux C++ Base64编解码

Base64的由来目前Base64已经成为网络上常见的传输8Bit字节代码的编码方式之一。在做支付系统时&#xff0c;系统之间的报文交互都需要使用Base64对明文进行转码&#xff0c;然后再进行签名或加密&#xff0c;之后再进行&#xff08;或再次Base64&#xff09;传输。那么&#xf…

java的for循环取出数据只是拿到最后一个_新兴大数据分析榆中百合

新兴大数据分析榆中百合大数据流程从流程角度上看&#xff0c;整个大数据处理可分成4个主要步骤。处理流程图分为三层(数据采集层&#xff0c;数据存储与计算处理层&#xff0c;数据可视化)&#xff1a;表2-1 系统环境系统版本Windows 10专业版(建议)LinuxCentOS 6.8 or CentO…