In this blog post we will create a secure API for external access, using OAuth 2.0, to the microservices we created inPart 1 and Part 2.

For information about OAuth 2.0 either see introductory material Parecki - OAuth 2 Simplified and Jenkov - OAuth 2.0 Tutorial or the specification IETF RFC 6749.

We will add a new microservice, product-api, that will act as the external API (a Resource Server in OAuth terminology) and we will expose its services through the edge server that we introduced in Part 1 acting as a token relay, i.e. forwarding OAuth access tokens from the client to the resource server. We will also add an OAuth Authorization Server and an OAuth client, i.e. service consumer, we will continue to use cURL.

The system landscape from Part 2 will be complemented with the new OAuth components (marked with a red line):

We will demonstrate how a client can use any of the four standard authorization grant flows to get an access token from the authorization server and then use the access token to make a secure request to the resource server, i.e. the API.

NOTES:

  • Protecting external API’s is nothing specific to microservices, so this blog post is applicable to any architecture where there is a need to secure external API’s using OAuth 2.0!

  • We will provide a lightweight OAuth authorization server only useful for development and testing. In a real world usage it needs to be replaced, e.g. by an API platform or by delegating the sign in and authorization process to social networks such as Facebook or Twitter.

  • We are on purpose only using HTTP in this blog post to reduce complexity. In any real world usage of OAuth all traffic should be protected using TLS, i.e. HTTPS!

  • As in the previous posts we emphasize the differences between microservices and monolithic applications by running each service in a separate microservice, i.e. in separate processes.

  1. BUILD FROM SOURCE

As in Part 2 we use Java SE 8, Git and Gradle. So, to access the source code and build it perform:

git clone https://github.com/callistaenterprise/blog-microservices.git
cd blog-microservices
git checkout -b B3 M3.1
./build-all.sh

If you are on Windows you can execute the corresponding bat-file build-all.bat!

Two new source code components have been added since Part 2, an OAuth Authorization Server, auth-server, and the OAuth Resource Server, product-api-service:

The build should result in ten log messages that all says:

BUILD SUCCESSFUL

  1. SOURCE CODE WALKTHROUGH

Let’s look into how the two new components are implemented and how the edge server is updated to be able to relay the OAuth access tokens. We will also change the URL for the API to make it a bit more convenient to use.

2.1 GRADLE DEPENDENCIES

To be able to use OAuth 2.0 we will bring in the open source projects spring-cloud-security and spring-security-oauth2 with the following dependencies.

For the auth-server:

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

For full source code see auth-server/build.gradle.

For the product-api-service:

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

For full source code see product-api-service/build.gradle.

2.2 AUTH-SERVER

The implementation of the authorization server is straight forward. It is brought to life using an annotation, @EnableAuthorizationServer. Then we use a configuration class to register (in-memory only) the approved client applications, specifying client-id, client-secret, allowed grant flows and scopes:

  @EnableAuthorizationServer
protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter { @Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("acme")
.secret("acmesecret")
.authorizedGrantTypes("authorization_code", "refresh_token", "implicit", "password", "client_credentials")
.scopes("webshop");
}
}

This approach obviously only works for development and test to simulate a client application registration process provided by real world OAuth Authorization Servers, e.g. LinkedIn or GitHub.

For full source code see AuthserverApplication.java.

Registration of users (Resource Owner in OAuth terminology), simulating a real world Identity Provider (IdP), is done by adding one line per user in the file application.properties, e.g.:

security.user.password=password

For full source code see application.properties.

The implementation also comes with two simple web based user interfaces for user authentication and user consent, see the source code for details.

2.3 PRODUCT-API-SERVICE

To make our API-implementation act as a OAuth Resource Server we only need to annotate the main-method with the @EnableOAuth2Resource-annotation:

@EnableOAuth2Resource
public class ProductApiServiceApplication { For full source code see ProductApiServiceApplication.java. The implementation of the API-service is very similar to the composite service in Part 2. To be able to verify that OAuth works we have added logging of the user-id and the access token: @RequestMapping("/{productId}")
@HystrixCommand(fallbackMethod = "defaultProductComposite")
public ResponseEntity<String> getProductComposite(
@PathVariable int productId,
@RequestHeader(value="Authorization") String authorizationHeader,
Principal currentUser) { LOG.info("ProductApi: User={}, Auth={}, called with productId={}",
currentUser.getName(), authorizationHeader, productId);
...

NOTES:

  • Spring MVC will fill in the extra parameters for the current user and the authorization header automatically.

  • We have removed the uri /product from the @RequestMapping to be able to get a more compact URL when using the edge server since it will add a /product prefix to the url to be able to route the request to the correct service.

  • Writing access tokens to the log is probably not to recommend from a security perspective in a real world application.

2.4 UPDATES TO THE EDGE SERVER

Finally we need to make the edge server forward the OAuth access tokens down to the API-service. Fortunately this is actually already the default behavior, so we don’t need to do anything in this case

Spring Cloud OAuth的更多相关文章

  1. [转]Spring Cloud在国内中小型公司能用起来吗?

    原文地址:http://www.cnblogs.com/ityouknow/p/7508306.html 原文地址:https://www.zhihu.com/question/61403505 今天 ...

  2. Building microservices with Spring Cloud and Netflix OSS, part 2

    In Part 1 we used core components in Spring Cloud and Netflix OSS, i.e. Eureka, Ribbon and Zuul, to ...

  3. 基于Spring Cloud和Netflix OSS 构建微服务-Part 1

    前一篇文章<微服务操作模型>中,我们定义了微服务使用的操作模型.这篇文章中,我们将开始使用Spring Cloud和Netflix OSS实现这一模型,包含核心部分:服务发现(Servic ...

  4. 基于Spring Cloud和Netflix OSS构建微服务,Part 2

    在上一篇文章中,我们已使用Spring Cloud和Netflix OSS中的核心组件,如Eureka.Ribbon和Zuul,部分实现了操作模型(operations model),允许单独部署的微 ...

  5. spring cloud+dotnet core搭建微服务架构:Api授权认证(六)

    前言 这篇文章拖太久了,因为最近实在太忙了,加上这篇文章也非常长,所以花了不少时间,给大家说句抱歉.好,进入正题.目前的项目基本都是前后端分离了,前端分Web,Ios,Android...,后端也基本 ...

  6. Securing Spring Cloud Microservices With OAuth2

    From Zero to OAuth2 in Spring cloud Today I am presenting hours of research about a (apparently) sim ...

  7. Spring Cloud下微服务权限方案

    背景从传统的单体应用转型Spring Cloud的朋友都在问我,Spring Cloud下的微服务权限怎么管?怎么设计比较合理?从大层面讲叫服务权限,往小处拆分,分别为三块:用户认证.用户权限.服务校 ...

  8. SpringCloud(10)使用Spring Cloud OAuth2和JWT保护微服务

    采用Spring Security AOuth2 和 JWT 的方式,避免每次请求都需要远程调度 Uaa 服务.采用Spring Security OAuth2 和 JWT 的方式,Uaa 服务只验证 ...

  9. SpringCloud(9)使用Spring Cloud OAuth2保护微服务系统

    一.简介 OAth2是一个标准的授权协议. 在认证与授权的过程中,主要包含以下3种角色. 服务提供方 Authorization Server. 资源持有者 Resource Server. 客户端 ...

随机推荐

  1. cocos2dx libjson

    libjson下载 http://sourceforge.net/projects/libjson/ 下载解压后改名成libjson,用到的是根目录下面的JSONOptions.h.libjson.h ...

  2. 关于dispatchTouchEvent, onInterceptTouchEvent, onTouchEvent的分发机制浅析

    虽说这个问题不是很难...动动手就能看出答案...但是似乎不太容易理解...几次尝试把这个问题说明白....但是好像感觉说不明白....(顿时想起了那句话----说不明白就是自己还不明白! 我怎么可能 ...

  3. Redis 客户端连接

      Redis 通过监听一个 TCP 端口或者 Unix socket 的方式来接收来自客户端的连接,当一个连接建立后,Redis 内部会进行以下一些操作: 首先,客户端 socket 会被设置为非阻 ...

  4. Android基本控件之Menus

    在我们的手机中有很多样式的菜单,比如:我们的短信界面,每条短信,我们长按都会出现一个菜单,还有很多的种类.那么现在,我们就来详细的讨论一下安卓中的菜单 Android的控件中就有这么一个,叫做Menu ...

  5. 疑问-hadoop

    hadoop可以设置备份数据个数,那么这些不同节点的数据块对于hadoop来说有区分谁是备份的谁是直接可以用的吗? hadoop有机架策略,给某些操作如像根据带宽选择节点传输数据 那么这种策略的根据是 ...

  6. 美H1B签证额满,硕士以上学位仍可申请

    美国公民与移民服务局6月1日宣布,2007会计年度的工作签证H1B名额已经用完,下年度的申请从明年4月1日开始.但在美国获得硕士以上学位的高学历者仍可申请. 据北美世界日报报道,美国移民律师协会对连续 ...

  7. sql server 2008 com.microsoft.sqlserver.jdbc.SQLServerException: 通过端口 1433 连接到主机

    右击我的电脑,点击管理 右击"TCP/IP"选择"属性"(或双击"TCP/IP"),选择"IP地址"选项卡,最下面有个& ...

  8. Python刷票小脚本——网络人气奖?不好意思,我要了

    零.前言 最近参加微软的kinect大赛,报名之后发现有一个网络投票,票数最多的项目可以得到网络人气奖. 这种事,必然是要搞一搞! 说干就干. 说明:由于本人过于懒惰,所以就不截图了,让大家失望了! ...

  9. 关于php一些数组函数

    array_column($array,"key") 将二维数组中的键名为key的数据生成一个新数组 array_unique($array) 去除重复值

  10. python方式实现scoket通信

    要想明白这个网络通信还真的是离不开实现它实现流程图,看明白了大体很多都知道,觉得这个博主画的不错,地址是 http://www.cnblogs.com/wangcq/p/3520400.html 1. ...