前言
公开由许多微服务组成的公共访问API时要考虑的最重要方面之一是安全性。Spring具有一些有趣的功能和框架,使我们的微服务安全性配置更加容易。在本文中,我将向您展示如何使用Spring Cloud和Oauth2在API网关后面提供令牌访问安全性。
理论
目前,所有主要网站都使用OAuth2标准,允许您通过共享API访问其资源。它是一种开放授权标准,允许用户将存储在一个页面中的私有资源共享到另一页面,而不必使用其凭据服务。这些是与oauth2相关的基本术语。
· 资源所有者 –处理对资源的访问
· 资源服务器 –存储所有者资源的服务器,可以使用特殊令牌共享这些资源
· 授权服务器 –管理密钥,令牌和其他临时资源访问代码的分配。它还必须确保授予相关人员访问权限
· 访问令牌 –允许访问资源的密钥
· 授权授予 –授予访问权限。有多种确认访问的方法:授权码,隐式,资源所有者密码凭证和客户端凭证
该协议的流程包括三个主要步骤。首先,我们将授权请求发送到资源所有者。在资源所有者的响应之后,我们将授权授予请求发送到授权服务器并接收访问令牌。最后,我们将此访问令牌发送到Resource Server,如果有效,则API将资源提供给应用程序。
我们的解决方案
下图显示了示例的体系结构。我们有API网关(Zuul),用于将我们的请求代理到授权服务器和两个帐户微服务实例。授权服务器是提供outh2安全机制的某种基础结构服务。我们还拥有发现服务(Eureka),在其中注册了我们所有的微服务。
网关
对于我们的示例,我们不会在API网关上提供任何安全性。它只需要代理从客户端到授权服务器和autService的请求。在下面可见的Zuul网关配置中,我们将emptyHeader属性设置为空值以启用Authorization HTTP标头转发。默认情况下,Zuul在将我们的请求转发到目标API时会剪切该标头,其实这是不正确的,因为网关后面我们的服务需要基本授权。
zuul:
routes:
uaa:
path: /uaa/**
sensitiveHeaders:
serviceId: auth-server
account:
path: /account/**
sensitiveHeaders:
serviceId: account-service
网关内部的主类源代码非常简单。它只需要启用Zuul代理功能和发现客户端即可从Eureka注册表收集服务。
@SpringBootApplication
@EnableZuulProxy
@EnableDiscoveryClient
public class GatewayServer {
public static void main(String[] args) {
SpringApplication.run(GatewayServer.class, args);
}
}
授权服务器
我们的授权服务器尽可能简单。它基于默认的Spring安全配置。客户端授权详细信息存储在内存中的存储库中。当然,在生产模式下,您想使用其他实现而不是诸如JDBC数据源和令牌存储之类的内存中存储库。这是来自application.yml的配置片段。 client-id和 client-secret 提供了用户基本的身份验证数据和基本的安全凭证。用户凭证通常是Spring Security用户详细信息。
security:
user:
name: root
password: password
oauth2:
client:
client-id: acme
client-secret: secret
@EnableAuthorizationServer是带有的认证服务器的主要类 。我们还公开了一个REST端点,其中包含用于帐户服务的用户身份验证详细信息,并为客户端启用了Eureka注册和发现。
@SpringBootApplication
@EnableAuthorizationServer
@EnableDiscoveryClient
@EnableResourceServer
@RestController
public class AuthServer {
public static void main(String[] args) {
SpringApplication.run(AuthServer.class, args);
}
@RequestMapping("/user")
public Principal user(Principal user) {
return user;
}
}
应用程序–帐户微服务
我们的示例微服务仅对@GET请求提供一个端点,该端点始终返回同一帐户。在主类中,启用了资源服务器和Eureka发现。服务配置很简单。
测试中
我们只需要Web浏览器和REST客户端(例如Chrome Advanced REST客户端)即可测试我们的解决方案。让我们从向资源所有者发送授权请求开始。我们可以通过Web浏览器中的Zuul网关调用oauth2授权端点。
发送此请求后,我们应该看到下面的页面。选择批准,然后单击授权以从授权服务器请求访问令牌。如果应用程序身份经过验证且授权授予有效,则应在HTTP响应中返回对该应用程序的访问令牌。
b1acaa35-1ebd-4995-987d-56ee1c0619e5&token_type = bearer&state = 48532&expires_in = 43199
最后一步是使用访问令牌联系帐户端点。我们必须将其作为承载令牌放入Authorization标头中。在示例应用程序中,安全操作的日志记录级别设置为TRACE,因此您可以轻松找出发生问题的情况。
结论
老实说,我对应用程序中的安全性问题不是很熟悉。在Spring Security中,我们几乎提供了所有需要的机制。它还提供了可以轻松扩展以满足更高级要求的组件。