services.AddAuthentication(Microsoft.AspNetCore.Authentication.Negotiate.NegotiateDefaults.AuthenticationScheme).AddNegotiate();
以及
app.UseAuthentication();
并设置我的开发基础镜像为
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 --gid 1000 app && useradd --uid 1000 --gid app --shell /bin/bash -d /app app
RUN apt install -y mc sudo syslog-ng realmd gss-ntlmssp
TFS中的构建管道创建基于上述内容的应用程序Docker镜像,并添加以下环境变量,还将构建内容复制到/app目录下。
RUN chmod 0700 run.sh
ENV KRB5_KTNAME=/app/is.k01.HTTP.keytab
ENV KRB5_TRACE=/dev/stdout
ENV ASPNETCORE_URLS=http://*:80;https://+:443
RUN chown app:app /app -R
USER app
该应用程序由run.sh运行
service syslog-ng start
kinit HTTP/is.k01.mydomain.com@MYDOMAIN.COM -k -t /app/is.k01.HTTP.keytab
klist
dotnet dev-certs https
dotnet /app/SampleApi.dll
klist列出分配SPN给机器的主体
在IE和Firefox中,我已将network.negotiate-auth.trusted-uris添加到我的应用程序中
然而,我得到了登录对话框,但无法成功登录
所以问题是:
如何使用Microsoft.AspNetCore.Authentication.Negotiate包启用调试日志?
我的假设是,这个包没有正确地与Kerberos通信,可能缺少某个包,没有运行或其他原因。
还要注意,容器和.NET应用程序已成功连接到域,因为我使用集成安全性连接到数据库,它可以正常工作。
**** 编辑 > 答案第一部分
要启用日志记录,应该在kestrel中启用日志记录:
在appsettings.json中:
"Logging": {
"LogLevel": {
"Default": "Debug",
}
},
在 program.cs 文件中:
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.AddFilter("Microsoft", LogLevel.Debug);
logging.AddFilter("System", LogLevel.Debug);
logging.ClearProviders();
logging.AddConsole();
})
.ConfigureWebHostDefaults(webBuilder =>
{
在 Startup.cs 中,可以跟踪协商事件:
services.AddAuthentication(NegotiateDefaults.AuthenticationScheme).AddNegotiate(
options =>
{
options.PersistKerberosCredentials = true;
options.Events = new NegotiateEvents()
{
OnAuthenticated = challange =>
{
..
},
OnChallenge = challange =>
{
..
},
OnAuthenticationFailed = context =>
{
// context.SkipHandler();
Console.WriteLine($"{DateTimeOffset.Now.ToString(czechCulture)} OnAuthenticationFailed/Scheme: {context.Scheme.Str()}, Request: {context.Request.Str()}");
Console.WriteLine("context?.HttpContext?.Features?.Select(f=>f.Key.Name.ToString())");
var items = context?.HttpContext?.Features?.Select(f => "- " + f.Key?.Name?.ToString());
if (items != null)
{
Console.WriteLine(string.Join("\n", items));
}
Console.WriteLine("context.HttpContext.Features.Get<IConnectionItemsFeature>()?.Items " + context.HttpContext.Features.Get<IConnectionItemsFeature>()?.Items?.Count);
var items2 = context.HttpContext?.Features.Get<IConnectionItemsFeature>()?.Items?.Select(f => "- " + f.Key?.ToString() + "=" + f.Value?.ToString());
if (items2 != null) {
Console.WriteLine(string.Join("\n", items2));
}
return Task.CompletedTask;
}
};
}
);
**** 编辑
与此同时,根据我的目标,在 .net core docker web 应用程序中允许 Windows 认证,我正在查看 .net core、corefx 的源代码,并将 auth 代码截断为以下示例控制台应用程序:
try
{
var token = "MyToken==";
var secAssembly = typeof(AuthenticationException).Assembly;
Console.WriteLine("var ntAuthType = secAssembly.GetType(System.Net.NTAuthentication, throwOnError: true);");
var ntAuthType = secAssembly.GetType("System.Net.NTAuthentication", throwOnError: true);
Console.WriteLine("var _constructor = ntAuthType.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance).First();");
var _constructor = ntAuthType.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance).First();
Console.WriteLine("var credential = CredentialCache.DefaultCredentials;");
var credential = CredentialCache.DefaultCredentials;
Console.WriteLine("var _instance = _constructor.Invoke(new object[] { true, Negotiate, credential, null, 0, null });");
var _instance = _constructor.Invoke(new object[] { true, "Negotiate", credential, null, 0, null });
var negoStreamPalType = secAssembly.GetType("System.Net.Security.NegotiateStreamPal", throwOnError: true);
var _getException = negoStreamPalType.GetMethods(BindingFlags.NonPublic | BindingFlags.Static).Where(info => info.Name.Equals("CreateExceptionFromError")).Single();
Console.WriteLine("var _getOutgoingBlob = ntAuthType.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).Where(info => info.Name.Equals(GetOutgoingBlob) && info.GetParameters().Count() == 3).Single();");
var _getOutgoingBlob = ntAuthType.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).Where(info => info.Name.Equals("GetOutgoingBlob") && info.GetParameters().Count() == 3).Single();
Console.WriteLine("var decodedIncomingBlob = Convert.FromBase64String(token);;");
var decodedIncomingBlob = Convert.FromBase64String(token);
Console.WriteLine("var parameters = new object[] { decodedIncomingBlob, false, null };");
var parameters = new object[] { decodedIncomingBlob, false, null };
Console.WriteLine("var blob = (byte[])_getOutgoingBlob.Invoke(_instance, parameters);");
var blob = (byte[])_getOutgoingBlob.Invoke(_instance, parameters);
if (blob != null)
{
Console.WriteLine("var out1 = Convert.ToBase64String(blob);");
var out1 = Convert.ToBase64String(blob);
Console.WriteLine(out1);
}
else
{
Console.WriteLine("null blob value returned");
var securityStatusType = secAssembly.GetType("System.Net.SecurityStatusPal", throwOnError: true);
var _statusException = securityStatusType.GetField("Exception");
var securityStatus = parameters[2];
var error = (Exception)(_statusException.GetValue(securityStatus) ?? _getException.Invoke(null, new[] { securityStatus }));
Console.WriteLine("Error:");
Console.WriteLine(error);
Console.WriteLine("securityStatus:");
Console.WriteLine(securityStatus.ToString());
}
}
catch(Exception exc)
{
Console.WriteLine(exc.Message);
}
我发现这个库与System.Net.NTAuthentication通信,后者又与System.Net.Security.NegotiateStreamPal通信,最终与unix版本的Interop.NetSecurityNative.InitSecContext交互。
这应该会在操作系统中触发GSSAPI。
在dotnet runtime git中,他们告诉我们需要gss-ntlmssp才能使其正常工作,即使在aspnet core文档中没有提到。
https://github.com/dotnet/runtime/issues?utf8=%E2%9C%93&q=gss-ntlmssp
尽管如此,我已经编译了gss-ntlmssp并发现没有这个库会抛出错误“请求的机制不受支持。”,而使用我的库会抛出“未提供凭据,或凭据不可用或无法访问。”的错误,但从未访问任何gss_*方法。
我通过向文件添加日志条目来测试gss方法的使用情况,但从未出现过..例如:
OM_uint32 gss_init_sec_context(OM_uint32 *minor_status,
gss_cred_id_t claimant_cred_handle,
gss_ctx_id_t *context_handle,
gss_name_t target_name,
gss_OID mech_type,
OM_uint32 req_flags,
OM_uint32 time_req,
gss_channel_bindings_t input_chan_bindings,
gss_buffer_t input_token,
gss_OID *actual_mech_type,
gss_buffer_t output_token,
OM_uint32 *ret_flags,
OM_uint32 *time_rec)
{
FILE *fp;
fp = fopen("/tmp/gss-debug.log", "w+");
fprintf(fp, "gss_init_sec_context\n");
fclose(fp);
return gssntlm_init_sec_context(minor_status,
claimant_cred_handle,
context_handle,
target_name,
mech_type,
req_flags,
time_req,
input_chan_bindings,
input_token,
actual_mech_type,
output_token,
ret_flags,
time_rec);
}
因此,.net 调用 gssapi,而 gssapi 并未调用机制。
我已在 CentOS7 虚拟机、Ubuntu Windows 子系统和 Debian Docker 镜像(自定义的 mcr.microsoft.com/dotnet/core/sdk:3.1-buster)中观察到同样的行为。
现在的问题是,我该如何调试 gssapi?
我假设当前的 gssapi 是由这个库管理的:
readelf -d /usr/lib64/libgssapi_krb5.so
Dynamic section at offset 0x4aa48 contains 34 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libkrb5.so.3]
0x0000000000000001 (NEEDED) Shared library: [libk5crypto.so.3]
0x0000000000000001 (NEEDED) Shared library: [libcom_err.so.2]
0x0000000000000001 (NEEDED) Shared library: [libkrb5support.so.0]
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [libkeyutils.so.1]
0x0000000000000001 (NEEDED) Shared library: [libresolv.so.2]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000e (SONAME) Library soname: [libgssapi_krb5.so.2]
0x000000000000000c (INIT) 0xb1d8
0x000000000000000d (FINI) 0x3ebcc
0x0000000000000019 (INIT_ARRAY) 0x24a120
0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
0x000000000000001a (FINI_ARRAY) 0x24a128
0x000000000000001c (FINI_ARRAYSZ) 16 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x1f0
0x0000000000000005 (STRTAB) 0x3048
0x0000000000000006 (SYMTAB) 0x720
0x000000000000000a (STRSZ) 9167 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000003 (PLTGOT) 0x24b000
0x0000000000000002 (PLTRELSZ) 8088 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x9240
0x0000000000000007 (RELA) 0x58b0
0x0000000000000008 (RELASZ) 14736 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffffc (VERDEF) 0x5788
0x000000006ffffffd (VERDEFNUM) 3
0x000000006ffffffe (VERNEED) 0x57e0
0x000000006fffffff (VERNEEDNUM) 4
0x000000006ffffff0 (VERSYM) 0x5418
0x000000006ffffff9 (RELACOUNT) 504
0x0000000000000000 (NULL) 0x0
到目前为止,我已经从MIT源代码编译了新的最新GSSAPI,并发现它抛出了错误"An unsupported mechanism was requested.",因为GSSAPI需要GSS解释器,而不提供。在CentOS 7中,我遇到了另一个问题,即openssl库使用不兼容的共享kerberos库,因此yum停止工作。
***编辑
我发现gss-ntlmssp有标志GSS_C_MA_NOT_DFLT_MECH,因此它会失败并显示消息"No credentials were supplied, or the credentials were unavailable or inaccessible."。解决方法是构建自定义的gss-ntlmssp,去掉这个属性,因为我想将其用作默认身份验证机制。
我的样本控制台应用程序现在可以检查凭据,我将尝试将其工作放入docker容器中。
***编辑
我成功地在Kubernetes中运行了我的ConsoleApp:
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
RUN mkdir /app
RUN apt install -y mc sudo syslog-ng python3-software-properties software-properties-common packagekit git gssproxy vim
RUN apt install -y autoconf automake libxslt-dev doxygen findutils libgettextpo-dev libtool m4 make libunistring-dev libssl-dev zlib1g-dev gettext xsltproc libxml2-utils libxml2-dev xml-core docbook-xml docbook-xsl bison libkrb5-dev
RUN systemctl enable syslog-ng
RUN mkdir /src
RUN cd /src && wget https://web.mit.edu/kerberos/dist/krb5/1.18/krb5-1.18.tar.gz
RUN cd /src && tar -xf krb5-1.18.tar.gz
RUN cd /src/krb5-1.18/src && ./configure && make && make install
RUN cd /src && git clone https://github.com/scholtz/gss-ntlmssp.git
RUN cd /src/gss-ntlmssp/ && autoreconf -f -i && ./configure && make && make install
RUN cp /src/gss-ntlmssp/examples/mech.ntlmssp.conf /etc/gss/mech.d/mech.ntlmssp.conf
COPY testgss /testgss
RUN cd /testgss && dotnet ConsoleApp3.dll
RUN groupadd --gid 1000 app && useradd --uid 1000 --gid app --shell /bin/bash -d /app app
RUN echo BQIA..AAAB | base64 -d > /app/user.keytab
RUN echo BQIA..oQ== | base64 -d > /etc/krb5.keytab
RUN echo BQIA..oQ== | base64 -d > /app/is.k01.HTTP.keytab
RUN echo BQIA..AAA= | base64 -d > /app/is.k01.kerb.keytab
COPY krb5.conf /etc/krb5.conf
COPY krb5.conf /usr/local/etc/krb5.conf
RUN ln -s /etc/gss /usr/local/etc/gss
RUN cd /app
WORKDIR /app
然而,我现在遇到了这个错误:
System.Exception: An authentication exception occured (0xD0000/0x4E540016).
---> Interop+NetSecurityNative+GssApiException: GSSAPI operation failed with error - Unspecified GSS failure. Minor code may provide more information (Feature not available).
at System.Net.Security.NegotiateStreamPal.GssAcceptSecurityContext(SafeGssContextHandle& context, Byte[] buffer, Byte[]& outputBuffer, UInt32& outFlags)
at System.Net.Security.NegotiateStreamPal.AcceptSecurityContext(SafeFreeCredentials credentialsHandle, SafeDeleteContext& securityContext, ContextFlagsPal requestedContextFlags, Byte[] incomingBlob, ChannelBinding channelBinding, Byte[]& resultBlob, ContextFlagsPal& contextFlags)
***编辑 现在它在这里失败: gssntlm_init_sec_context.. gssntlm_acquire_cred.. gssntlm_acquire_cred_from..
现在它在这里失败:gssntlm_init_sec_context、gssntlm_acquire_cred和gssntlm_acquire_cred_from。 if (cred_store != GSS_C_NO_CRED_STORE) {
retmin = get_creds_from_store(name, cred, cred_store);
} else {
retmin = get_user_file_creds(name, cred);
if (retmin) {
retmin = external_get_creds(name, cred);
}
}
由于我想要从AD中验证用户,而没有设置特定的文件,因此get_user_file_creds()返回错误。
external_get_creds()在这里失败:
wbc_status = wbcCredentialCache(¶ms, &result, NULL);
if(!WBC_ERROR_IS_OK(wbc_status)) goto done;
external_get_creds尝试使用winbind库进行身份验证,显然在凭据缓存中没有用户。
我成功地使用了Samba提供的winbind库进行编译。
现在的问题是:如何设置winbind库与AD通信?
*** 编辑
我尝试使用.net 5,因为在GitHub上有人告诉我NTLM可以在.net 5中工作。但是我得到了与.net 3.1相同的结果。
我尝试过的Docker镜像:
FROM mcr.microsoft.com/dotnet/core-nightly/sdk:5.0-buster as final
USER root
RUN whoami
RUN apt update && apt dist-upgrade -y
RUN DEBIAN_FRONTEND=noninteractive apt install -y krb5-config krb5-user
RUN mkdir /app
RUN apt install -y mc sudo syslog-ng python3-software-properties software-properties-common packagekit git gssproxy vim apt-utils
RUN apt install -y autoconf automake libxslt-dev doxygen findutils libgettextpo-dev libtool m4 make libunistring-dev libssl-dev zlib1g-dev gettext xsltproc libxml2-utils libxml2-dev xml-core docbook-xml docbook-xsl bison libkrb5-dev
RUN systemctl enable syslog-ng
RUN mkdir /src
#RUN cd /src && git clone https://github.com/scholtz/gss-ntlmssp.git
RUN DEBIAN_FRONTEND=noninteractive apt install -y libwbclient-dev samba samba-dev
#RUN cat /usr/include/samba-4.0/wbclient.h
COPY gss-ntlmssp /usr/local/src/gss-ntlmssp
RUN cd /usr/local/src/gss-ntlmssp/ && autoreconf -f -i && ./configure && make && make install
RUN cp /usr/local/src/gss-ntlmssp/examples/mech.ntlmssp.conf /etc/gss/mech.d/mech.ntlmssp.conf
RUN groupadd --gid 1000 app && useradd --uid 1000 --gid app --shell /bin/bash -d /app app
RUN echo BQIAAABMA..ArHdoQ== | base64 -d > /etc/krb5.keytab
COPY krb5.conf /etc/krb5.conf
COPY smb.conf /etc/samba/smb.conf
COPY krb5.conf /usr/local/etc/krb5.conf
RUN DEBIAN_FRONTEND=noninteractive apt install -y winbind
ENV KRB5_TRACE=/dev/stdout
RUN mkdir /src2
WORKDIR /src2
RUN dotnet --list-runtimes
RUN dotnet new webapi --auth Windows
RUN dotnet add package Microsoft.AspNetCore.Authentication.Negotiate
RUN sed -i '/services.AddControllers/i services.AddAuthentication(Microsoft.AspNetCore.Authentication.Negotiate.NegotiateDefaults.AuthenticationScheme).AddNegotiate();' Startup.cs
RUN sed -i '/app.UseAuthorization/i app.UseAuthentication();' Startup.cs
run echo a
RUN cat Startup.cs
RUN dotnet restore
RUN dotnet build
ENV ASPNETCORE_URLS="http://*:5002;https://*:5003"
EXPOSE 5002
EXPOSE 5003
RUN cd /app
WORKDIR /app
docker run -it -p 5003:5003 -it registry.k01.mydomain.com/k01-devbase:latest
在 Docker 容器中:
kinit HTTP/myuser@MYDOMAIN.COM -k -t /etc/krb5.keytab
klist
dotnet run src2.dll
我已经在gssntlmssp库中放置了自己的调试信息,并将其写入文件。
cat /tmp/gss-debug.log
这正是我使用 .net core 3.1 结束的地方。
wbcCredentialCache(samba lib)失败的原因是找不到缓存的凭据。
这是我的 krb5.conf 文件:
[appdefaults]
default_lifetime = 25hrs
krb4_convert = false
krb4_convert_524 = false
ksu = {
forwardable = false
}
pam = {
minimum_uid = 100
forwardable = true
}
pam-afs-session = {
minimum_uid = 100
}
[libdefaults]
default_realm = MYDOMAIN.COM
[realms]
MYDOMAIN.COM = {
kdc = DC01.MYDOMAIN.COM
default_domain = MYDOMAIN.COM
}
[domain_realm]
mydomain.com. = MYDOMAIN.COM
.mydomain.com. = MYDOMAIN.COM
[logging]
default = CONSOLE
default = SYSLOG:INFO
default = FILE:/var/log/krb5-default.log
kdc = CONSOLE
kdc = SYSLOG:INFO:DAEMON
kdc = FILE:/var/log/krb5-kdc.log
admin_server = SYSLOG:INFO
admin_server = DEVICE=/dev/tty04
admin_server = FILE:/var/log/krb5-kadmin.log
并且是Samba文件的一部分:
[global]
security = domain
workgroup = mydomain.com
password server = *
idmap config * : range = 16777216-33554431
template shell = /bin/bash
winbind use default domain = yes
winbind offline logon = false
wins server = 10.0.0.2
在我看来,我更希望使用NTLM而不是Negotiate,因为据我所知,Negotiate在浏览器中并不受支持。例如,在Firefox中,用户必须设置关于:config以进行Negotiate服务器的配置。通配符不受支持,...
尽管如此,似乎我将无法使用NTLM运行.NET Core 5 Web应用程序,因此我现在将尝试使用一些默认的Kerberos机制来设置它,而不使用gssntlmssp库。 我的krb5.conf设置有什么问题吗?
****编辑 因此,我现在正在尝试两种不同的方法:
- NTLM-在我看来,这是首选的方式,因为我已经看到了例如在iis express中,ntlm验证用户时没有对话框,并且不需要在Firefox或通过组策略进行任何特殊配置(如果我错了,请纠正我)
- Negotiate
关于Negotiate,我已经取得了一些进展...
通过这个Docker容器,我能够绕过不支持的机制:
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster as final
USER root
RUN whoami
RUN apt update && apt dist-upgrade -y
RUN DEBIAN_FRONTEND=noninteractive apt install -y krb5-config krb5-user
RUN mkdir /app
RUN apt install -y mc sudo syslog-ng python3-software-properties software-properties-common packagekit git gssproxy vim apt-utils
RUN apt install -y autoconf automake libxslt-dev doxygen findutils libgettextpo-dev libtool m4 make libunistring-dev libssl-dev zlib1g-dev gettext xsltproc libxml2-utils libxml2-dev xml-core docbook-xml docbook-xsl bison libkrb5-dev
RUN systemctl enable syslog-ng
RUN mkdir /src
RUN groupadd --gid 1000 app && useradd --uid 1000 --gid app --shell /bin/bash -d /app app
RUN echo BQIAAAA8..vI | base64 -d > /etc/krb5.keytab
COPY krb5.conf /etc/krb5.conf
COPY krb5.conf /usr/local/etc/krb5.conf
ADD ca/is.k01.mydomain.com.p12 /etc/ssl/certs/is.k01.mydomain.com.pfx
RUN cd /app
WORKDIR /app
现在我有另一个问题:
在keytab中找到HTTP/is.k01.mydomain.com@MYDOMAIN.com kvno 3的请求票据服务器,但未使用rc4-hmac加密类型这对我来说似乎意味着keytab没有使用rc4-hmac加密类型,这是正确的,因为keytab是使用生成的
ktpass -princ HTTP/is.k01.mydomain.com@MYDOMAIN.COM -pass ***** -mapuser MYDOMAIN\is.k01.kerb -pType KRB5_NT_PRINCIPAL -out c:\temp\is.k01.HTTP.keytab -crypto AES256-SHA1
根据 .net 文档所述。
我无法禁止使用 rc4-hmac 并仅允许使用更新的编码方式,因此我请求我的基础架构部门生成带有旧的 rc4-hmac 编码的新密钥表。
这一步使我进一步了解到以下错误:在密钥表中找不到 HTTP/is.k01.mydomain.com@MYDOMAIN.COM kvno 4 的请求票证服务器;密钥表可能已过期*
这非常奇怪,因为密钥表不可能过期,密码在一小时前生成密钥表时是100%有效的且未更改,并且网上没有任何关于“在密钥表中找不到 kvno 4”的信息 - 在 Google 搜索只返回 4 条结果。
**** 编辑
最终,我成功地解决了问题 :)
“在密钥表中找不到 kvno 4”的问题在于 krb5.conf 文件,我为了强制使用 aes 加密而添加了以下行
# default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes256-cts-hmac-sha1-9
# default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes256-cts-hmac-sha1-9
# permitted_enctypes = aes256-cts-hmac-sha1-96 aes256-cts-hmac-sha1-9
我将它们注释掉后,使用Negotiate进行身份验证开始工作了。我已经测试了使用 .net 5 的 NTLM,但仍无法正常工作。
在上述构建的Docker容器中,Negotiate使用的krb5.conf文件如下:
[appdefaults]
default_lifetime = 25hrs
krb4_convert = false
krb4_convert_524 = false
ksu = {
forwardable = false
}
pam = {
minimum_uid = 100
forwardable = true
}
pam-afs-session = {
minimum_uid = 100
}
[libdefaults]
default_realm = MYDOMAIN.COM
[realms]
MYDOMAIN.COM = {
kdc = DC02.MYDOMAIN.COM
default_domain = MYDOMAIN.COM
}
[domain_realm]
mydomain.com. = MYDOMAIN.COM
.mydomain.com. = MYDOMAIN.COM
[logging]
default = CONSOLE
default = SYSLOG:INFO
default = FILE:/var/log/krb5-default.log
kdc = CONSOLE
kdc = SYSLOG:INFO:DAEMON
kdc = FILE:/var/log/krb5-kdc.log
admin_server = SYSLOG:INFO
admin_server = DEVICE=/dev/tty04
admin_server = FILE:/var/log/krb5-kadmin.log
现在的问题是:有没有办法允许多个服务运行协商协议,而不需要逐个添加到spn中,并手动设置浏览器?
目前每个新的Web服务都必须具备以下要求:
setspn -S HTTP/mywebservice.mydomain.com mymachine
setspn -S HTTP/mywebservice@MYDOMAIN.COM mymachine
必须在Internet Explorer的设置中允许以下内容:Security > Web > Details > 在那里列出域名。
在Firefox中,需在about:config > network.negotiate-auth.trusted-uris中进行设置。
据我所知,Chrome采用Internet Explorer的设置。
我认为可以通过域组策略以某种方式更新Internet Explorer的设置。有人有任何想法吗?
****编辑 我已经在浏览器中测试了使用通配符的域名协商设置,以下是结果:
- Chrome:支持*.k01.mydomain.com
- IE:支持*.k01.mydomain.com
- Firefox(73.0.1(64位)):不支持*.k01.mydomain.com——只支持完整域名,例如is.k01.mydomain.com
- Edge 44.18362.449.0 - 不知道为什么,没有一个IE设置被传播...不适用于*.k01.mydomain.com或is.k01.mydomain.com
****编辑 我已开始使用Negotiate的Win身份验证,但现在在.NET Core中遇到了一些问题。
在IIS Express下运行的此代码以MYDOMAIN\myuser的形式显示用户:
var userId = string.Join(',', User?.Identities?.Select(c => c.Name)) ?? "?";
在Linux中,它显示为myuser@mydomain.com。
在IIS Express下,User.Indentities.First()是WindowsIdentity,我可以列出用户的所有组。
在Linux下,User.Indentities.First()是ClaimsIdentity,没有组信息。
当我尝试在IIS Express中通过组来限制它时,我得到以下结果:
//Access granted
[Authorize(Roles = "MYDOMAIN\\GROUP1")]
//403
[Authorize(Roles = "MYDOMAIN\\GROUP_NOT_EXISTS")]
使用Negotiate的Linux kestrel:
//403
[Authorize(Roles = "MYDOMAIN\\GROUP1")]
看起来,kestrel中的negotiate无法正确列出组。现在我将调查如何在kestrel中获取WindowsIdentity。