我一直在c/c ++应用程序中使用GSSAPI.显然我不得不谷歌和研究很多.我发现的最有趣的文档之一是在Sun的旧网站上.在Oracle接管Sun之后,旧的网站已经消失,但不知何故,这些信息仍然存在. http://docs.oracle.com/cd/E19253-01/816-4863/index.html 令人震惊的是,我在Oracle的文档中找不到上述URL的任何链接.内容还包括几个PDF文件,我幸运地保存在我的笔记本电脑上.
上面的URL也提供了使用SASL和c/c ++的出色指南.
内容引用了一些包含示例源代码的tar文件.根据当前网站内容,该文件应该可以在以下网址获得:http: //www.sun.com/download/products.xml?id = 41912db5 但遗憾的是我现在无法在网站上找到它们.
内容是ac/c ++程序员在GSSAPI/Kerberos/PAM/SASL上重新开始的一个很好的起点
看看Oracle现在的网站,我坚信内容目前"意外"落后,很快就会消失.
现在,这是我访问stackoverflow的奇妙黑客的问题:
我认为这些内容真的非常宝贵,而且我无法想到任何其他网络资源,以获得有关使用GSSAPI和C/C++的非常明确的信息.如果您可以对此做些什么,请立即执行,因为我认为上述网址很快就会消失.
我真诚地感谢你们,我向你们许多人也会感谢你们.
编辑:在Oracle网站上有点狩猎,我发现了其中一个PDF的链接,但是给了一个新名称: Oracle Solaris Security for Developers 如果你开始使用GSSAPI/SASL,那么肯定是一个参考的宝石C++
在过去的几年里,我不得不"偶尔"与Heimdal/MIT Gssapi合作进行kerberos认证.我必须构建一个应用程序,用作在Linux机器上运行的Web服务,并提供运行在Windows和/或Linux桌面和工作站上的浏览器等客户端应用程序.当然不是最容易驯服的野兽.最后,在总结我的工作时,我可以记录由于多方面的挑战而产生的困难.开始使用gssapi编程确实是一个挑战,因为文档很差,并且实际上是不存在的教程.谷歌搜索通常会导致对什么是kerberos进行一些理论上的讨论,或者导致内容写成假设你已经知道除了某些特定的语义问题之外的所有内容.这里有一些非常好的黑客对我有所帮助,因此我认为从开发人员的角度总结这些东西是个好主意,并在这里分享它作为某种维基,给回到这个梦幻般的地方,和其他程序员.
以前没有真正做过像这样的维基,而且我肯定对GSSAPI和Kerberos没有权限,所以请善待,但更重要的是请贡献并纠正我的错误.网站编辑,我指望你做你的魔术;)
成功完成项目需要正确完成3项具体任务:
正如我已经说过的那样,这些项目都是野兽,因为这三个项目都没有放在同一个页面的任何地方.
好的,让我们从头开始吧.
新手 GSSAPI的不可避免的理论帮助客户端应用程序为服务器提供凭据以权威地识别用户.非常有用,因为服务器应用程序可以根据用户调整其服务响应.因此非常自然地 - 客户端和服务器应用程序必须是kerberized,或者有些人会说kerberos知道.
基于kerberos的身份验证要求客户端和服务器应用程序都是Kerberos领域的成员.KDC(Kerberos域控制器)是指定领域的指定权限.Microsoft的AD服务器是KDC中最受欢迎的示例之一,但您当然可以使用基于*NIX的KDC.但肯定没有KDC,根本就没有Kerberos业务.只要所有桌面,服务器和工作站都加入域中,它们就会相互识别.
对于您的初始实验,请在同一领域中设置客户端和服务器应用程序.虽然Kerberos身份验证肯定也可以通过在这些领域的KDC之间创建信任,甚至合并来自不相互信任的不同KDC的密钥记录来跨领域使用.您的代码实际上不需要任何更改来适应这种不同且复杂的场景.
Kerberos身份验证基本上通过"票证(或令牌)"工作.当一个成员加入这个领域时,KDC会向每个成员"授予令牌".这些代币是独一无二的; 时间和FQDN是这些门票的必要因素.
在你想到代码的第一行之前,请确保你有这两个权利:
陷阱#1在设置开发和测试环境时,请确保所有内容都经过测试并以FQDN进行寻址.例如,如果要检查连接,请使用FQDN而不是IP进行ping.因此,不用说,它们必须具有相同的DNS服务配置.
陷阱#2确保所有运行KDC,客户端软件,服务器软件的主机系统都具有相同的时间服务器.时间同步是一种忘记的东西,并且在经过大量的分裂和头撞之后意识到自己很不舒服!
两者,客户端和服务器应用程序都需要kerberos keytabs.因此,如果您的应用程序将在*NIX主机中运行,并且是Microsoft域的一部分,那么在我们开始查看gss编程的剩余准备步骤之前,您必须生成kerberos keytab.
Kerberos 5循序渐进指南(krb5 1.0)互操作性绝对必读.
GSS-API编程指南是一个很好的书签.
根据您的*NIX发行版,您可以安装用于构建代码的标头和库.我的建议是下载源代码并自行构建.是的,你可能不会一气呵成,但它肯定是值得的.
陷阱#3确保您的应用程序在Kerberos感知环境中运行.我真的很努力地学到了这一点,但也许是因为我不那么聪明.在我最初的gssapi编程斗争阶段,我发现kerberos keytabs对于让我的应用程序感知kerberos是绝对必要的.但我根本找不到任何关于如何在我的应用程序中加载这些keytabs.你知道为什么?!!因为没有这样的api !!! 因为:应用程序将在知道keytabs的环境中运行.好吧,让我这么简单:在将环境变量设置KRB5_KTNAME为存储keytabs的路径之后,应该运行应该执行GSSAPI/Kerberos事务的应用程序.所以要么你做的事情如下:
export KRB5_KTNAME=<path/to/your/keytab>
Run Code Online (Sandbox Code Playgroud)
或者在运行使用gssapi的第一行代码之前充分setenv设置KRB5_KTNAME应用程序.
我们现在准备在应用程序的代码中执行必要的操作.
据我所知,应用程序开发人员必须审查其他许多方面,以编写和测试应用程序.我知道一些环境变量,这很重要.
任何人都可以对此有所了解吗?
我正在尝试在 kubernetes 下的 linux docker 容器中使用 windows 身份验证。
我正在关注此设置:https : //docs.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-3.1&tabs=visual-studio#kestrel
应用程序在 .net core3 中,使用 nuget Microsoft.AspNetCore.Authentication.Negotiate 并在 kestrel 中运行
我已经添加了
services.AddAuthentication(Microsoft.AspNetCore.Authentication.Negotiate.NegotiateDefaults.AuthenticationScheme).AddNegotiate();
Run Code Online (Sandbox Code Playgroud)
也
app.UseAuthentication();
Run Code Online (Sandbox Code Playgroud)
并将我的 devbase 映像设置为
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster as final
USER root
RUN whoami
RUN apt update && apt dist-upgrade -y
ADD ca/ca.crt /usr/local/share/ca-certificates/ca.crt
RUN chmod 644 /usr/local/share/ca-certificates/*
RUN update-ca-certificates
RUN DEBIAN_FRONTEND=noninteractive apt install -y krb5-config krb5-user
COPY krb5.conf /etc/krb5.conf
RUN mkdir /app
RUN echo BQIAAA..== | base64 -d > /app/is.k01.HTTP.keytab
WORKDIR /app
#RUN docker version
RUN groupadd …Run Code Online (Sandbox Code Playgroud) 要在Windows上使用Java进行客户端HTTP SPNEGO身份验证,您需要设置Windows注册表项allowtgtsessionkey.这是有据可查的.我不明白的是人们如何解决这个问题?为了单个软件,大多数企业站点永远不会接受在Windows中更改此注册表项.如果需要在组织中的每个工作站上更改它,请考虑一下麻烦.但这只是理论,因为我到目前为止还无法说服我们的任何客户更改此注册表项.
我不怪他们.大多数企业管理员会认为这样可以放松安全性并因此反对它.
我已经读过: 在Java或命令行工具中是否有办法使用本机SSPI API获取服务的Kerberos票证?
但它现在已经很老了.
所以我真的,真的不明白人们如何使Windows + Java客户端+ Kerberos可以在除大学环境,家庭用户等之外的任何地方工作.
我从公司管理员那里得到的问题是"当IE和Firefox等应用程序在没有设置此密钥的情况下执行SPNEGO时没有问题时,我们为什么需要设置此注册表项?".好吧,我知道答案是什么.这是因为(很可能)IE和Firefox等应用程序基于Windows本机GSS API(SSPI),而Sun的Java使用自己的实现.
我假设使用像WAFFLE这样的东西可以解决问题,但我赞成纯Java解决方案.我还假设使用基于Java的解决方案(如Spring安全性或Apache HttpClient)无济于事,因为它们都会遇到这个问题.
任何帮助或指针将不胜感激.
更新1:
我发现Oracle的bug数据库中有一个RFE.还有一个由Oracle员工就此问题提交的补丁以及有关此功能的JDK邮件列表的讨论.除了我能理解的这一点在目前的Java 7中是不可用的,甚至不是实验性的,都不会让我更加明智.对?
更新2:
现在问题在OpenJDK Security Dev邮件列表上再次存在.
我正在使用下面Connect()的SshJava类中的方法,以便使用SSH(JSch)连接到服务器并在服务器中运行命令.
问题是运行Connect()服务器时会提示下一条消息:
Kerberos username [********]:
Kerberos password for ********:
Run Code Online (Sandbox Code Playgroud)
并且为了继续运行,我需要手动按Enter两次键,一个用于用户名,一个用于密码.我试图添加下一个代码:
// Press ENTER
Robot r = new Robot();
r.keyPress(KeyEvent.VK_ENTER);
r.keyRelease(KeyEvent.VK_ENTER);
Run Code Online (Sandbox Code Playgroud)
但是这段代码只适用于用户名,我无法弄清楚当服务器要求输入密码时如何自动按ENTER键.到目前为止,我已经尝试将另一个代码片段作为上面显示的代码片段
session.connect();
Run Code Online (Sandbox Code Playgroud)
线.
package ConnectSSH;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.io.*;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;
public class Ssh{
private static final String user = "********";
private static final String host = "********";
private static final Integer port = 22;
private static final String pass = "********";
public void …Run Code Online (Sandbox Code Playgroud) 在Windows 2012上运行时,我正在努力验证Java Web容器(我已尝试过Tomcat和Jetty).
每次我尝试Negotiate auth方案时都会收到错误: org.ietf.jgss.GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag)
重现步骤
首先设置Windows Server 2012或2016实例并安装Active Directory域服务.
在我的例子中,我创建了:
NETBIOS域名: NICKIS
Dns域名: nickis.life
在Active Directory上创建kerberos主题用户
重要提示:请确保第一个名称,最后名称和完整名称是相同的!
在我的情况下,新用户是:
DN =CN=kerberos500,CN=Users,DC=nickis,DC=life
登录+域名 =kerberos500@nickis.life
NETBIOS\samAccountName =NICKIS\kerberos500
从Windows Active Directory服务器运行setspn命令
setspn -A HTTP/nickis.life@NICKIS.LIFE kerberos500
Run Code Online (Sandbox Code Playgroud)
示例输出:
C:\Users\Administrator>setspn -A HTTP/nickis.life kerberos500
Checking domain DC=nickis,DC=life
Registering ServicePrincipalNames for CN=kerberos500,CN=Users,DC=nickis,DC=life
HTTP/kerberos500.nickis.life
Updated object
Run Code Online (Sandbox Code Playgroud)
从Windows Active Directory服务器运行ktpass命令
ktpass -out c:\Users\Administrator\kerberos500.keytab -princ HTTP/nickis.life@NICKIS.LIFE -mapUser kerberos500 -mapOp set -pass XXXXpasswordforkerberos500userXXXX -crypto DES-CBC-MD5 -pType …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用ldap_sasl_bind_sMicrosoft LDAP C SDK中的方法,使用GSSAPI作为身份验证机制.ldap_sasl_bind_s期望凭证作为BERVAL结构,这是不透明的.
给定用户名(或DN)和密码,如何进入BERVAL我应该传递给的结构ldap_sasl_bind_s?
到目前为止我发现的例子
ldap_sasl_bind_s在需要SIMPLE身份验证时使用- 但我需要使用GSSAPIldap_sasl_interactive_bind_s在需要其他SASL身份验证机制时使用.但是,ldap_sasl_interactive_bind_sMicrosoft SDK中没有.作为旁注,目标是能够通过SASL绑定到各种LDAP服务器; 目前:ActiveDirectory和OpenLDAP.
任何指针将不胜感激.
在我工作的项目上,我们在几个不同的服务器上运行GUI应用程序.由于他们的用户界面相似,我正在研究将他们的OMI组合成一个统一的界面.目前,这些应用程序都可以通过VNC远程查看.我计划通过让主显示器在封面下运行几个VNC查看器并围绕这些VNC会话包装接口以使它们看起来像本机应用程序来利用这一点.
我正在寻找构建单点登录解决方案的指针.我希望消除每个应用程序的个人登录,而只是让用户登录统一显示.当他们这样做时,他们将自动登录到每个单独的应用程序.
我的调查指向了Kerberos和GSSAPI.Kerberos的基于票证的机制似乎非常适合这项任务.
一个棘手的问题是这些应用程序始终在运行.当用户登录时,我需要统一显示以某种方式"告诉"它们.它不像普通的Kerberized程序,它们将在启动时执行Kerberos登录.
如果我使用Kerberos,我不知道如何将票证转移到各种应用程序服务器.有转移它们的标准方法吗?我只是使用"scp"或其他东西吗?或者我是否开发自己的基于套接字的网络协议并让Java程序相互连接并以这种方式传输票证?
不过,我不想让细节陷入困境.我甚至欣赏一般的想法,比如"你考虑过X技术?" 或者"尝试XYZ而不是VNC,它会为你做到这一点."
我会在这里编辑答案和说明......
您是否认为必须进行某些身份验证并且VNC仅将视图导出到正在运行的程序,因此VNC会话无法传输票证?
确实是的.Java + VNC就是我们现在所拥有的.如果有更好的远程查看应用程序的方法,我可以更换VNC.没有重写它们,就是这样.理想的解决方案是将它们分成不同的客户端和服务器部分,并将所有GUI代码放入客户端,但这是5星级的难度,我需要1星或2星.
您是否考虑过两个用户同时登录时的情况?他们会看到相同的应用程序吗?或者这会被禁止吗?
是的,我考虑过了.他们要么看到相同的应用程序,要么将被禁止.就这个特定的系统而言,这两种解决方案都没问题,所以这不是什么大问题.
您是否考虑过在本地主机上使用X Server并导出客户端应用程序窗口?
是的,这会很棒.这可以通过已经运行的应用程序完成吗?我们必须在这些应用程序启动后连接这些应用程序.当有人解雇中央观众时,我无法按需启动它们.
我有一个Java客户端应用程序和一个Java服务器应用程序,我正在尝试通过Kerberos对服务器进行身份验证.客户端基本上使用http组件和SPNEGO进行HTTP GET调用,但我总是得到401 Unauthorized结果.
我无法在下面的Kerberos登录序列中发现错误,也许你们可以:
Debug is true storeKey false useTicketCache false useKeyTab false doNotPrompt f
alse ticketCache is null isInitiator true KeyTab is null refreshKrb5Config is fa
lse principal is null tryFirstPass is false useFirstPass is false storePass is f
alse clearPass is false
Kerberos-Benutzername [GP_Myuser]: GP_Myuser@EESERV.LOCAL
Kerberos-Passwort f³r GP_Myuser@EESERV.LOCAL:
[Krb5LoginModule] user entered username: GP_Myuser@EESERV.
LOCAL
default etypes for default_tkt_enctypes: 23.
Acquire TGT using AS Exchange
default etypes for default_tkt_enctypes: 23.
>>> KrbAsReq calling createMessage
>>> KrbAsReq in …Run Code Online (Sandbox Code Playgroud) 我有以下代码:
public static void main(String args[]){
try {
//String ticket = "Negotiate YIGCBg...==";
//byte[] kerberosTicket = ticket.getBytes();
byte[] kerberosTicket = Base64.decode("YIGCBg...==");
GSSContext context = GSSManager.getInstance().createContext((GSSCredential) null);
context.acceptSecContext(kerberosTicket, 0, kerberosTicket.length);
String user = context.getSrcName().toString();
context.dispose();
} catch (GSSException e) {
e.printStackTrace();
} catch (Base64DecodingException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
当然它失败了.这是例外:
GSSException: Defective token detected (Mechanism level: GSSHeader did not find the right tag)
我不知道我应该做些什么来解决这个问题.老实说,我真的不懂Kerberos.
我通过发送WWW-Authenticate带有"Negotiate" 的适当标题的401 作为值来获得此票.浏览器立即使用authorization包含此票证的标题再次发出相同的请求.
我希望我能验证票证并确定用户是谁.
我需要keytab文件吗?如果是这样,我将在哪个凭据下运行?我正在尝试将Kerberos票证用于网站的身份验证.凭据是否是IIS的凭据?
我错过了什么?
更新1 从Michael-O的回复中,我做了一些谷歌搜索并找到了这篇文章,这引导我阅读这篇文章.
上 …