构建微服务使用OAuth2.0保护API接口Rickie

在本文中,我们将使用OAuth2.0,创建一个的安全API,可供外部访问Part1和Part2完成的微服务。

我们将创建一个新的微服务,命名为product-api,作为一个外部API(OAuth术语为资源服务器-ResourceServer),并通过之前介绍过的EdgeServer暴露为微服务,作为TokenRelay,也就是转发Client端的OAuth访问令牌到资源服务器(ResourceServer)。另外添加OAuthAuthorizationServer和一个OAuthClient,也就是服务消费方。

继续完善Part2的系统全貌图,添加新的OAuth组件(标识为红色框):

备注:

1/保护外部API并不是微服务的特殊需求,因此本文适用于任何使用OAuth2.0保护外部API的架构;

3/为了降低复杂度,我们特意采用了HTTP协议。在实际的应用中,OAuth通信需要使用TLS,如HTTPS保护通信数据。

和在Part2中一样,我们使用JavaSE8、Git和Gradle访问源代码,并进行编译:

cdblog-microservices

gitcheckout-bB3M3.1

./build-all.sh

如果运行在Windows平台,则执行相应的bat文件-build-all.bat。

在Part2的基础中,新增了2个组件源码,分别为OAuthAuthorizationServer,项目名为auth-server;另一个为OAuthResourceServer,项目名为product-api-service。

编译输出10条log消息:

BUILDSUCCESSFUL

查看2个新组件是如何实现的,以及EdgeServer是如何更新并支持传递OAuth访问令牌的。我们也会修改API的URL,以便于使用。

2.1Gradle依赖

为了使用OAuth2.0,我们将引入开源项目:spring-cloud-security和spring-security-oauth2,添加如下依赖。

auth-server项目:

compile("org.springframework.boot:spring-boot-starter-security")

compile("org.springframework.security.oauth:spring-security-oauth2:2.0.6.RELEASE")

完整代码,可查看auth-server/build.gradle文件。

product-api-service项目:

compile("org.springframework.cloud:spring-cloud-starter-security:1.0.0.RELEASE")

完整代码,可以查看product-api-service/build.gradle文件。

2.2AUTH-SERVER

@EnableAuthorizationServer

protectedstaticclassOAuth2ConfigextendsAuthorizationServerConfigurerAdapter{

@Override

publicvoidconfigure(ClientDetailsServiceConfigurerclients)throwsException{

clients.inMemory()

.withClient("acme")

.secret("acmesecret")

.authorizedGrantTypes("authorization_code","refresh_token","implicit","password","client_credentials")

.scopes("webshop");

}

显然这一方法仅适用于开发和测试场景模拟Client端应用的注册流程,实际应用中采用OAuthAuthorizationServer,如LinkedIn或GitHub。

完整的代码,可以查看AuthserverApplication.java。

模拟真实环境中IdentityProvider的用户注册(OAuth术语称为ResourceOwner),通过在文件application.properties中,为每一个用户添加一行文本,如:

security.user.password=password

完整代码,可以查看application.properties文件。

实现代码也提供了2个简单的web用户界面,用于用户认证和用户准许,详细可以查看源代码:

2.3PRODUCT-API-SERVICE

为了让API代码实现OAuthResourceServer的功能,我们只需要在main方法上添加@EnableOAuth2Resource标注:

@EnableOAuth2Resource

publicclassProductApiServiceApplication{

完整代码,可以查看ProductApiServiceApplication.java。

API服务代码的实现和Part2中的组合服务代码的实现很相似。为了验证OAuth工作正常,我们添加了user-id和accesstoken的日志输出:

@RequestMapping("/{productId}")

@HystrixCommand(fallbackMethod="defaultProductComposite")

publicResponseEntitygetProductComposite(

@PathVariableintproductId,

@RequestHeader(value="Authorization")StringauthorizationHeader,

PrincipalcurrentUser){

LOG.info("ProductApi:User={},Auth={},calledwithproductId={}",

currentUser.getName(),authorizationHeader,productId);

...

1/SpringMVC将自动填充额外的参数,如currentuser和authorizationheader。

2/为了URL更简洁,我们从@RequestMapping中移除了/product。当使用EdgeServer时,它会自动添加一个/product前缀,并将请求路由到正确的服务。

3/在实际的应用中,不建议在log中输出访问令牌(accesstoken)。

2.4更新EdgeServer

最后,我们需要让EdgeServer转发OAuth访问令牌到API服务。非常幸运的是,这是默认的行为,我们不必做任何事情。

为了让URL更简洁,我们修改了Part2中的路由配置:

zuul:

ignoredServices:"*"

prefix:/api

routes:

productapi:/product/**

我们也替换了到composite-service的路由为到api-service的路由。

完整的代码,可以查看application.yml文件。

首先启动RabbitMQ:

$~/Applications/rabbitmq_server-3.4.3/sbin/rabbitmq-server

如在Windows平台,需要确认RabbitMQ服务已经启动。

接着启动基础设施微服务:

$cdsupport/auth-server;./gradlewbootRun

$cdsupport/discovery-server;./gradlewbootRun

$cdsupport/edge-server;./gradlewbootRun

$cdsupport/monitor-dashboard;./gradlewbootRun

$cdsupport/turbine;./gradlewbootRun

最后,启动业务微服务:

$cdcore/product-service;./gradlewbootRun

$cdcore/recommendation-service;./gradlewbootRun

$cdcore/review-service;./gradlewbootRun

$cdcomposite/product-composite-service;./gradlewbootRun

$cdapi/product-api-service;./gradlewbootRun

如在Windows平台,可以执行相应的bat文件-start-all.bat。

一旦微服务启动完成,并注册到服务发现服务器(ServiceDiscoveryServer),会输出如下日志:

DiscoveryClient...-registrationstatus:204

现在已经准备好尝试获取访问令牌,并使用它安全地调用API接口。

OAuth2.0规范定义了4种授予方式,获取访问令牌:

备注:AuthorizationCode和Implicit是最常用的2种方式。如前面2种方式不使用,其他2种适用于一个特殊场景。

接下来看看每一个授予流程是如何获取访问令牌的。

首先,我们通过浏览器获取一个代码许可:

code=IyJh4Y&

state=97536

备注:在请求中state参数设置为一个随机值,在响应中进行检查,避免cross-siterequestforgery攻击。

从重定向的URL中获取code参数,并保存在环境变量中:

CODE=IyJh4Y

现在作为一个安全的web服务器,使用codegrant获取访问令牌:

curlacme:acmesecret@localhost:9999/uaa/oauth/token\

-dgrant_type=authorization_code\

-dclient_id=acme\

-dcode=$CODE-s|jq.

{

"access_token":"eba6a974-3c33-48fb-9c2e-5978217ae727",

"token_type":"bearer",

"refresh_token":"0eebc878-145d-4df5-a1bc-69a7ef5a0bc3",

"expires_in":43105,

"scope":"webshop"

在环境变量中保存访问令牌,为随后访问API时使用:

TOKEN=eba6a974-3c33-48fb-9c2e-5978217ae727

再次尝试使用相同的代码获取访问令牌,应该会失败。因为code实际上是一次性密码的工作方式。

"error":"invalid_grant",

"error_description":"Invalidauthorizationcode:IyJh4Y"

4.2隐式许可(ImplicitGrant)

通过ImplicitGrant,可以跳过前面的CodeGrant。可通过浏览器直接请求访问令牌。在浏览器中使用如下URL地址:

access_token=00d182dc-9f41-41cd-b37e-59de8f882703&

token_type=bearer&

state=48532&

expires_in=42704

备注:在请求中state参数应该设置为一个随机,以便在响应中检查,避免cross-siterequestforgery攻击。

在环境变量中保存访问令牌,以便随后访问API时使用:

TOKEN=00d182dc-9f41-41cd-b37e-59de8f882703

4.3资源所有者密码凭证许可(ResourceOwnerPasswordCredentialsGrant)

在这一场景下,用户不必访问web浏览器,用户在Client端应用中输入凭证,通过该凭证获取访问令牌(从安全角度而言,如果你不信任Client端应用,这不是一个好的办法):

curl-sacme:acmesecret@localhost:9999/uaa/oauth/token\

-dgrant_type=password\

-dscope=webshop\

-dusername=user\

-dpassword=password|jq.

"access_token":"62ca1eb0-b2a1-4f66-bcf4-2c0171bbb593",

"refresh_token":"920fd8e6-1407-41cd-87ad-e7a07bd6337a",

"expires_in":43173,

在环境变量中保存访问令牌,以便在随后访问API时使用:

TOKEN=62ca1eb0-b2a1-4f66-bcf4-2c0171bbb593

4.4Client端凭证许可(ClientCredentialsGrant)

-dgrant_type=client_credentials\

-dscope=webshop|jq.

"access_token":"8265eee1-1309-4481-a734-24a2a4f19299",

"expires_in":43189,

TOKEN=8265eee1-1309-4481-a734-24a2a4f19299

现在,我们已经获取到了访问令牌,可以开始访问实际的API了。

首先在没有获取到访问令牌时,尝试访问API,将会失败:

"error":"unauthorized",

"error_description":"Fullauthenticationisrequiredtoaccessthisresource"

OK,这符合我们的预期。

接着,我们尝试使用一个无效的访问令牌,仍然会失败:

-H"Authorization:Bearerinvalid-access-token"-s|jq.

"error":"access_denied",

"error_description":"Unabletoobtainanewaccesstokenforresource'null'.Theprovidermanagerisnotconfiguredtosupportit."

再一次如期地拒绝了访问请求。

现在,我们尝试使用许可流程返回的访问令牌,执行正确的请求:

-H"Authorization:Bearer$TOKEN"-s|jq.

"productId":123,

"name":"name",

"weight":123,

"recommendations":[...],

"reviews":[...]

OK,这次工作正常了!

可以查看一下api-service(product-api-service)输出的日志记录。

2015-04-2318:39:59.030INFO79321---[ctApiService-10]s.c.m.a.p.service.ProductApiService:ProductApi:User=user,Auth=Bearera0f91d9e-00a6-4b61-a59f-9a084936e474,calledwithproductId=123

我们看到API联系AuthorizationServer,获取用户信息,并在log中打印出用户名和访问令牌。

最后,我们尝试使访问令牌失效,模拟它过期了。可以通过重启auth-server(仅在内存中存储了该信息)来进行模拟,接着再次执行前面的请求:

如我们的预期一样,之前可以接受的访问令牌现在被拒绝了。

多谢开源项目spring-cloud-security和spring-security-auth,我们可以基于OAuth2.0轻松设置安全API。然后,请记住我们使用的AuthorizationServer仅适用于开发和测试环境。

THE END
1.authorizationn.批准;授权(书); clearancen.清除,清理;(官方)许可;间距; carte blanchen.全权委托,署名空白纸(任人填写条件等); 知识拓展 同根词汇 permit v.允许 重要短语 without permission 未经许可 with one's permission 如果…允许的话 written permission 书面许可证;签单 ask for permission 征求许可;https://dict.ruihongw.com/permission
2.licenses是什么意思licenses怎么读中文意思用法n. 授权;许可(license的复数) licenses 词性变化 原型:license 词组短语 1、sub-licenses(sub-license 的第三人称 -s形式) 分许可 2、driver'slicenses驾照 3、commerciallicenses商业授权商业许可证商业执照 4、marriagelicenses结婚证 5、private pilotlicenses私人飞行员执照 https://danci.gjcha.com/licenses.html
3.二零二四年度版权许可协议:电子书出版与销售3篇.docx20XX专业合同封面COUNTRACTCOVER20XX专业合同封面COUNTRACTCOVER甲方:XXX乙方:XXXPERSONALRESUMERESUME二零二四年度版权许可协议:电子书出版与销售本合同目录一览1.定义与解释1.1合同术语1.2术语定义2.许可授权2.1许可范围2.2许可期限3.许可费用3.1费用金额3.2付款方式3.3付款时间4.许可内容4.1电子书内容4.2电子书版本4.3电子书https://www.renrendoc.com/paper/369179256.html
4.出海文件中的“principal”该如何翻译?Principal在法律文件中做名词讲时通常有以下几层含义: 1.本金 如: 利息收入将按照未偿还本金及适用的实际利率,按时间比例基础计提。 Interest income is accrued on a time basis, by reference to the principal outstanding and at the applicable effective interest rate. https://m.thepaper.cn/newsDetail_forward_29681549
5.Codesoft许可管理明确许可需求:首先,您需要明确企业对Codesoft软件的具体需求,包括所需的许可证数量、类型和期限。这将有助于您更好地规划和管理许可资源。 分配许可证:根据需求,为您的员工或部门分配相应的Codesoft许可证。确保每个用户都拥有合适的许可证,并遵循授权规则。 https://www.jianshu.com/p/07654db06b1d
6.授权许可的英文授权许可翻译授权许可英语怎么说海词词典,最权威的学习词典,专业出版授权许可的英文,授权许可翻译,授权许可英语怎么说等详细讲解。海词词典:学习变容易,记忆很深刻。http://m.dict.cn/msearch.php?q=%E6%8E%88%E6%9D%83%E8%AE%B8%E5%8F%AF
7.商标许可授权合同(中英文).docx一、授权许可 Grant of License 二、付款方式 Terms of Payment 三、专用权 Exclusivity 四、 信誉Good 可 Grant of License 产品Articles 根据以下规定的条款,许可方授与被许可方,被许可方接受单独使用这一商标的许可 权力,且只在制造和出售、分销以下产品的使用。(加入产品描述) http://taodocs.com/p-701406609.html
8.股权购买协议中英文公司在此类特许、许可和类似授权的重要方面均不存在违约。 21、公司文件(Corporate Documents) 重述章程和公司规章均以提供给购买者的格式作出。提供给购买者的公司会议纪要副本记录了自公司设立以来的所有董事会和股东会会议纪要和所有未召开董事会会议或股东会议而以书面许可采取的行为,在所有重要方面准确反映了董事(和https://www.66law.cn/contractmodel/688606.aspx
9.中译英费用标准授权翻译合同范本(共13篇) (经典版) 编制人:___ 审核人:___ 审批人:___ 编制单位:___ 编制时间:___年___月___日 序言 下载提示:该文档是本店铺精心编制而成的,希望大家下载后,能够帮助大家解决实际问题。文档下载后可定制修改,请根据实际需要进行调整和使用,谢谢! 并且,本店铺为大家提供各种类型的https://www.360docs.net/doc/0b19462749.html
10.官宣!JetBrainsIDE支持远程开发了!OSCHINA支持的 IDE 和授权许可 远程开发包含在现有付费订阅中。 它内置到支持 JetBrains IDE 的 IntelliJ 平台中。JetBrains Gateway 与 IntelliJ IDEA Ultimate、PyCharm Professional、GoLand、PhpStorm 和 RubyMine 捆绑在一起。 您也可以通过带有 CLion 和 WebStorm 的独立 JetBrains Gateway 应用使用远程开发。 我们计划在https://my.oschina.net/u/5494143/blog/5332935
11.CALIBRI免费字体下载在字体家网站不需要通过任何付费即可下载到的字体文件,该类字体文件是本站收集于网络,本站不享有任何版权,仅提供给本站网友进行字体爱好交流,如您想通过免费下载的字体进行商业用途使用,本站强烈提醒您联系对应厂商或原作者进行版权授权购买,如因为使用了免费下载的字体引起了版权诉讼纠纷,本站不承担任何责任;当然,您如https://www.zitijia.com/i/258783464260652089.html
12.最新2021win10专业版激活秘钥序列号推荐附激活工具windows10云盟win10系统激活工具(kms永久数字许可证) v2.5.0.0 最新免费版 类型:系统其它 大小:2.95MB 语言:简体中文 时间:2020-03-11 查看详情 win10/win11/office2022激活工具 KMS_VL_ALL_AIO v52 中/英文免费绿色版 类型:系统其它 大小:125KB 语言:简体中文 https://www.jb51.net/os/win10/759015.html
13.AMTEmu(Adobe授权工具)V0.9.2英文绿色版白手创业网AMTEmu是非常好用的Adobe授权解除工具,通过Amtemu实现应用程序激活和解锁功能所有必要的类函数,让用户可以免费的使用到Adobe软件的全部功能,有需要的朋友可以来下载试试。 AMTEmu软件由来 AmtemuV0.9.2是俄罗斯技术论坛Ru-Board大神PainteR的最新作品,替代其 Adobe Universal Patcher。它是Adobe产品的软件保护模拟器。 该工https://www.heishou.org/d/332069
14.授权,许可,Authorization,音标,读音,翻译,英文例句,英语词典为解决越来越多的用户使用数字版权管理(DRM)系统购买电子产品而导致的系统中证书服务器在颁发证书时出现的系统瓶颈问题,基于代理签名技术的原理,设计了一个由多个签名服务器组成的DRM系统,并在此系统上设计了一个许可授权协议。4) licensed utilization 授权许可使用5) certificate of authorization 授权证书(许可证)http://www.dictall.com/indu52/50/52503365E46.htm
15.云桌面基础技术一:GPU原理及在云桌面中的应用citrixgpu切分7、在许可证服务器上打开英文浏览器访问http://localhost:8080/licserver ,点击Upload上传许可证文件 参考链接:Virtual GPU License Server User Guide 虚拟机内安装NVIDIA驱动并连接许可服务器: 1、虚拟机内安装对应版本的NVIDIA vGPU驱动软件 2、在虚拟机里NVIDIA控制面板中连接搭建好的NVIDIA许可服务器,给vGPU授权。https://blog.csdn.net/qq_44906445/article/details/105632845
16.专利授权制度,PatentGrantingSystem英语短句,例句大全1.This paper tests the causal relationship between the enterprise s patent authorization amount and the GNP of Chongqing City from 1990 to 2005 by using the regressive analysis, and makes analysis on the results.采用回归分析方法对重庆市1990—2005年的企业专利授权量与重庆市国民生产总值进行因果关系检http://xjishu.com/en/038/y272016.html
17.授权书英文翻译14篇(全文)【授权委托书】英文版授权委托书样本 授权书(或授权委托书)在英文中有两种形式,即Letter of Authorization(LOA)和 Power of Attorney(POA),而且英文授权书在使用上是有一些区别的。一般来说,Letter of Authorization比较通用,几乎可以用于各种形式和各种需求时的授权;而Power of Attorney的使用比较严格,被授权人应为https://www.99xueshu.com/w/file8y2qunmq.html
18.服务框架合同模板(通用10篇)9、乙方应保守甲方的工作秘密,未经授权或许可,不得对外提供其存储的电子数据。 三、协议期限 本协议所指技术服务期限为___年,从双方签订之日开始计算,具体时间为从___年___月___日起到___年___月___日止。 四、协议的解除和终止 协议到期后,如甲方继续需要乙方https://www.oh100.com/a/202204/4479211.html
19.美国人事管理中的信息安全审查制度及其启示国内研究方面,王鸿杰提出中国应当建立接触国家秘密许可的可信任度审查制度,但未对可操作的建议进行具体阐述。?韩慧云从科学划分审查等级、完善分级审查标准、严格确定禁止条件三个方面完善涉密人员资格审查标准体系,从明确审查主体、规范审查程序、建立审查档案三个方面健全涉密人员资格审查工作机制,对如何严格把控“入口”https://www.xsyk021.com/article/app/id/457f9754-07ae-4bd7-9a04-f270e3be24df
20.苹果Shake4.1Linux平台(5用户授权英文版)(AppleShake4.1关于苹果 苹果 苹果公司(Apple Inc.)是美国的一家高科技公司,2007年由苹果电脑公司(Apple Computer, Inc.)更名而来,核心业务为电子科技 [苹果Shake4.1 Linux平台(5用户授权英文版)维修信息] 客服电话:400-666-8800,400-627-2273 官方网站:点此进入https://product.yesky.com/product/519/519134/