微服务和 Kerberos 身份验证

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 63w+ 字,讲解图 2808+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2200+ 小伙伴加入学习 ,欢迎点击围观

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 服务器。因此,不再需要使用绑定用户(具有特殊权限)。主要优点是您可以创建任何登录到您系统的用户的审计跟踪。

相关文章