OAUTH2 的微服务安全
前言
公开由许多微服务组成的公共访问 API 时要考虑的最重要方面之一是安全性。Spring 有一些有趣的特性和框架,使我的微服务安全配置更容易。在本文中,我将向您展示如何使用 Spring Cloud 和 Oauth2 在 API 网关后面提供令牌访问安全性。
理论
OAuth2 标准目前被所有允许您通过共享 API 访问其资源的主要网站使用。它是一种开放的授权标准,允许用户将存储在一个页面中的私有资源共享到另一个页面,而无需进入其凭据服务。这些是与 oauth2 相关的基本术语。
- 资源所有者- 处置对资源的访问
- 资源服务器——存储所有者资源的服务器,可以使用特殊令牌共享
- 授权服务器——管理密钥、令牌和其他临时资源访问代码的分配。它还必须确保授予相关人员访问权限
- 访问令牌——允许访问资源的密钥
- 授权授予——授予访问权限。确认访问的方式有多种:授权码、隐式、资源所有者密码凭据和客户端凭据
该协议的流程包括三个主要步骤。一开始,我将授权请求发送给资源所有者。在资源所有者响应后,我向授权服务器发送授权授予请求并接收访问令牌。最后,我将此访问令牌发送到资源服务器,如果有效,则 API 将资源提供给应用程序。
我的解决方案
下图显示了我示例的架构。我有 API 网关 (Zuul),它将我的请求代理到授权服务器和两个帐户微服务实例。授权服务器是一种提供outh2安全机制的基础设施服务。我还有发现服务(Eureka),我所有的微服务都在其中注册。
网关
对于我的示例,我不会在 API 网关上提供任何安全性。它只需要将来自客户端的请求代理到授权服务器和帐户微服务。在下面可见的 Zuul 网关配置中,我将sensitiveHeaders属性设置为空值以启用授权HTTP 标头转发。默认情况下,Zuul 在将我的请求转发到目标 API 时会剪切该标头,这是不正确的,因为网关背后的服务要求基本授权。
代码语言:javascript代码运行次数:0运行复制zuul:
routes:
uaa:
path: /uaa/**
sensitiveHeaders:
serviceId: auth-server
account:
path: /account/**
sensitiveHeaders:
serviceId: account-service
网关源代码中的主类非常简单。它只需要启用 Zuul 代理功能和发现客户端即可从 Eureka 注册中心收集服务。
代码语言:javascript代码运行次数:0运行复制@SpringBootApplication
@EnableZuulProxy
@EnableDiscoveryClient
public class GatewayServer {
public static void main(String[] args) {
SpringApplication.run(GatewayServer.class, args);
}
}
授权服务器
授权服务器尽可能简单。它基于默认的 Spring 安全配置。客户端授权详细信息存储在内存存储库中。当然在生产模式下,您希望使用其他实现而不是像本例一样将令牌存储这样的内存存储库。您可以在Spring Security Reference 和 Spring Boot Security 中阅读有关 Spring 授权机制的更多信息 。这是application.yml 中的配置片段。我为/token 端点提供了用户基本身份验证数据和基本安全凭证: 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 发现。服务配置很简单 。
代码语言:javascript代码运行次数:0运行复制@SpringBootApplication
@EnableDiscoveryClient
@EnableResourceServer
public class AccountService {
public static void main(String[] args) {
SpringApplication.run(AccountService.class, args);
}
}
代码语言:javascript代码运行次数:0运行复制security:
user:
name: root
password: password
oauth2:
resource:
loadBalanced: true
userInfoUri: http://localhost:9999/user
测试
我只需要 Web 浏览器和 REST 客户端(例如 Chrome Advanced REST 客户端)来测试我的解决方案。让我从向资源所有者发送授权请求开始。我可以在 Web 浏览器中通过 Zuul 网关调用 oauth2 授权端点。
http://localhost:8765/uaa/oauth/authorize?response_type=token&client_id=acme&redirect_uri=;scope=openid&state=48532
发送此请求后,我应该看到下面的页面。选择Approve并单击 Authorize 以请求来自授权服务器的访问令牌。如果应用程序身份已通过身份验证并且授权许可有效,则应在 HTTP 响应中返回应用程序的访问令牌。
= b1acaa35-1ebd-4995-987d-56ee1c0619e5 &token_type=bearer&state=48532&expires_in=43199
最后一步是使用访问令牌调用帐户端点。我必须将它作为不记名令牌放入 Authorization 标头中。在示例应用程序中,安全操作的日志级别设置为 TRACE,因此您可以轻松地找出出现问题时发生的情况。
结论
老实说,我对应用程序中的安全问题不是很熟悉。所以对我来说一件非常重要的事情是我决定使用的安全解决方案的简单性。在 Spring Security 中,我几乎拥有所有需要的开箱即用的机制。它还提供了可以轻松扩展以满足更高级要求的组件。您应该将本文视为使用 Spring Cloud 和 Spring Security 项目的更高级解决方案的简要介绍。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2016-03-23,如有侵权请联系 cloudcommunity@tencent 删除安全微服务cloud服务器spring
发布评论