微服务和 Kerberos 身份验证
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2800+ 小伙伴加入学习 ,欢迎点击围观
kerberos 身份验证 用于保护各种大数据产品,如 apache hadoop 和最近的 apache kafka (>0.9)。在 hadoop 的情况下,它用于对每个用户和服务进行身份验证,以便使用 hadoop 生态系统。许多现代 nosql 数据库也提供对 kerberos 的支持,例如 apache cassandra 和 mongodb。 kerberos 身份验证在微服务架构中也很有用。它可用于实现单点登录功能。一个鲜为人知的属性是将代币委托给子服务的可能性。
在微服务架构中,您可能有一个 api 网关 ,它是本机移动应用程序或 html5 应用程序的单一入口点。网关可以将请求转发到多个微服务并将结果聚合到一个响应中。
来源:http://microservices.io/patterns/apigateway.html
这里的挑战是知道哪个用户登录了后备休息服务。在 kerberos 的情况下,可以将用户凭据委托给这些其余服务。这些微服务可以再次验证凭据。
这在 Java 中如何工作?
由于 java 是企业就绪的,因此 gss-api 从早期(jdk 1.4)开始就支持 kerberos。但是,这个 api 使用起来很尴尬。幸运的是,有一个用于 spring security 的 kerberos 插件 ,但是这个插件没有开箱即用的凭证委托支持。所以我写了一些代码来创建委托服务票:(注意这张票也是可转发的)
import org.ietf.jgss.*;
import org.springframework.security.core.context.securitycontextholder;
import org.springframework.security.kerberos.authentication.kerberosservicerequesttoken;
import javax.security.auth.subject;
import java.security.privilegedexceptionaction;
public static byte[] createservicetoken(string servicename) throws exception {
kerberosservicerequesttoken authentication = (kerberosservicerequesttoken)
securitycontextholder.getcontext().getauthentication();
subject subject = authentication.getticketvalidation().subject();
return subject.doas(subject, (privilegedexceptionaction<byte[]>) () -> {
gssmanager manager = gssmanager.getinstance();
gssname name = manager.createname("http@" + servicename, gssname.nt_hostbased_service);
gsscontext context = manager.createcontext(name,
null,
authentication.getticketvalidation().getgsscontext().getdelegcred(),
gsscontext.indefinite_lifetime);
context.requestcreddeleg(true);
byte[] servicetoken = context.initseccontext(authentication.gettoken(), 0, authentication.gettoken().length);
context.dispose();
return servicetoken;
});
}
一些解释:
第 9,10 行从 spring 安全上下文中检索 keberosservicetoken
第 12 行获取当前登录的主题
第 14 行运行 lambda 表达式作为这个主题
第 15 行获取 gssmanager
第 16 行为其余端点创建一个 gssname
第 17-20 行为此 rest 端点创建一个新的 gsscontext
第 21 行请求可转发的 kerberos 令牌,因此新服务票证也是可转发的
第 22 行使用当前的 kerberos 令牌启动安全上下文以获取新的服务票证
第 23 行关闭上下文并
第 24 行返回新票
我的一位同事还创建了 spring security kerberos 插件的扩展,以将用户凭据委托给 ldap 服务器。因此,不再需要使用绑定用户(具有特殊权限)。主要优点是您可以创建任何登录到您系统的用户的审计跟踪。