如何进行多服务的分布式授权认证

多行不义必自毙。

————————《左传 · 郑伯克段于鄢》

问题起源

最近工作中需要和数个第三方进行服务对接,都涉及到同一个问题,如何进行服务安全认证,并进一步考虑到当前流行的多服务模式下,如何在多个服务间,即分布式服务间进行分布式的服务安全认证,或身份认证与操作授权。

第三方常用的身份认证与授权方式

就目前所对接的第三方来说,大多数的身份认证为access_token认证,即通过约定的key+secret以及指定的加密方式,通过指定接口获取一个特定的token以及token的有效期或者有效截止时间,后续业务接口访问时,每次均需要带上该token即可。

这种方式目前的专业术语叫OAuth 2.0。

推荐阅读阮一峰大佬的博客:OAuth 2.0 的四种方式OAuth 的核心就是向第三方应用颁发令牌。在文章里面提到了4中身份认证方式,分别是授权码,隐藏式,密码式,客户端凭证。

例如,我们上文提到的与第三方交互的token方式就对应阮一峰博客中的凭证式的访问方式。

如下图是我绘制的一个简单的认证请求方式,以便于读者理解。

image-20220314161456380

多服务模式下的身份认证与授权

在目前的情况下,多服务通常指的是微服务,而微服务又以SpringCloud为代表,其使用广泛,组件全面。

SpringCloud中,负责身份认证与授权的有Spring Cloud Security,Netflix Zuul等。

我们今天来看一下SpringCloud Security的基础使用。

首先按照创建springboot的流程,创建SpringCloud Security项目。创建完成后,需要在pom文件中引入以下内容,以便服务启动。

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

然后修改application.properties配置文件,设置端口号:

1
server.port=8083

并创建一个测试的接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.springcloud.security.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

@GetMapping("test")
public String sayHello() {
return "test hello world";
}
}

然后,我们启动项目:

image-20220314171013328

在浏览器中输入地址:

1
localhost:8083/test

发现,浏览器自动跳转到地址localhost:8083/login,其页面如下:

image-20220314171123503

我们接着配置项目。在配置文件中输入以下内容:

1
2
3
# Security
spring.security.user.name=admin
spring.security.user.password=123456

在浏览器输入框中输入对应内容,重试,点击”Sign in”按钮,页面自动跳转到了地址:localhost:8083/test,如下图所示:

image-20220314171640322