我正在尝试在 kubernetes 下的 linux docker 容器中使用 windows 身份验证。
应用程序位于 .net core3 中,使用 nuget Microsoft.AspNetCore.Authentication.Negotiate 并在 kestrel 中运行
我添加了
services.AddAuthentication(Microsoft.AspNetCore.Authentication.Negotiate.NegotiateDefaults.AuthenticationScheme).AddNegotiate();
也
app.UseAuthentication();
并将我的 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 --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 的源代码,并将身份验证代码压缩到这个示例控制台应用程序中:
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 核心文档中无论如何都没有提到它。
https://github.com/dotnet/runtime/issues?utf8=%E2%9C%93&q=gss-ntlmssp
尽管如此,我已经编译了 gss-ntlmssp 并发现如果没有这个库,它会抛出错误“请求了不支持的机制。 ”。对于我的库,它会抛出错误“没有提供凭据,或者凭据不可用或无法访问。 ”,但永远不会访问任何 gss_* 方法。
我通过将日志条目添加到从未发生过的文件中测试了 gss 方法的使用.. fe:
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 vm、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,发现它向我抛出了错误“请求了不受支持的机制”。因为 gssapi 需要未提供的 gss 解释器。在 centos7 中,我遇到了另一个问题,即 openssl 库正在使用不兼容的共享 kerberos 库,因此 yum 停止工作。
*** 编辑
我发现 gss-ntlmssp 具有标志 GSS_C_MA_NOT_DFLT_MECH 因此失败并显示消息“未提供凭据,或者凭据不可用或无法访问。”。解决方案是构建没有此属性的自定义 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..
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);
}
}
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 通信?
*** 编辑
我曾尝试在 github 上使用 .net 5,有人告诉我 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 然后协商,因为据我所知,浏览器不支持协商。例如,在 Firefox 中,该人必须为协商服务器设置 about:config。不支持通配符,...
尽管如此,我似乎无法使用 ntlm 运行 .net core 5 Web 应用程序,所以我现在将尝试在没有 gssntlmssp 库的情况下使用一些默认的 kerberos 机制来设置它。知道我的 krb5.conf 设置有什么问题吗?
****编辑所以我现在尝试两种不同的方法:
- NTLM - 我认为这是更可取的方式,因为我已经看到 ntlm 在 iis express 中验证用户,例如没有对话框,并且不需要在 firefox 中或通过组策略进行任何特殊配置(如果我错了,请纠正我)
- 谈判
关于谈判,我设法取得了一些进展。
使用这个 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
但是现在我有其他问题: Request ticket server HTTP/is.k01.mydomain.com@MYDOMAIN.com kvno 3 found in keytab but not with enctype 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 编码生成新的密钥表。
这一步让我更进一步,我得到了这个错误:Request ticket server HTTP/is.k01.mydomain.com@MYDOMAIN.COM kvno 4 not found in keytab; keytab 可能已过时*
这很奇怪,因为 keytabs 不能过期,密码没有更改,并且在一小时前生成 keytab 时 100% 有效,并且网络上没有信息 - “kvno 4 not found in keytab”仅获取 4结果在谷歌。
**** 编辑
所以最后我设法让它工作了:)
“kvno 4 not found in keytab”的问题是在 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,但它仍然无法正常工作。
krb5.conf 文件在 docker 容器中进行协商,如上述构建工作:
[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 > 设置 > 安全 > 网络 > 详细信息 > 域中列出
我认为互联网浏览器设置应该可以通过域组策略以某种方式更新..有人知道怎么做吗?
**** 编辑我已经在域中测试了通配符以在浏览器中进行协商设置,结果如下:
- 铬:支持 *.k01.mydomain.com
- 即:支持 *.k01.mydomain.com
- firefox(73.0.1(64 位)):不支持 *.k01.mydomain.com - 仅支持完整域,例如 is.k01.mydomain.com
- 边缘44.18362.449.0 - 不知道为什么,但没有一个 ie 设置被传播.. 不适用于 *.k01.mydomain.com 和 is.k01.mydomain.com
**** 编辑我已经开始使用带有协商的win auth,但是我现在在.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")]
Linux kestrel 与协商:
//403
[Authorize(Roles = "MYDOMAIN\\GROUP1")]
因此,kestrel 中的协商似乎没有正确列出组。所以我现在要调查,如何在 kestrel 中获取 WindowsIdentity。