当前位置: 首页 > 知识库问答 >
问题:

Linux docker容器中的Windows身份验证

孟哲
2023-03-14

我试图在kubernetes下的linux docker容器中使用windows身份验证。

我遵循以下设置:https://docs.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-3.1

应用程序在. net core3中,具有nuget Microsoft. AspNetCore.身份验证.在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映像,并添加以下环境变量,还将build复制到/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

该应用程序正在逐个运行。嘘

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中,我添加了网络。协商授权。我的应用程序的受信任URI

然而,我得到的登录对话框没有成功登录

所以问题是:

如何启用Microsoft的调试日志。AspNetCore。认证。谈判方案?

我的假设是,这个包不能与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 =>
{

在初创阶段。cs one可以跟踪协商事件:

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;
            }
        };
    }
);

****编辑

同时,我的目标是允许windows身份验证进入。net core docker web app我正在浏览其源代码。net core、corefx和trucated将验证代码添加到此示例控制台应用程序:

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);
}

所以我发现图书馆与系统通信。网与系统通信的身份验证。网安全NegotiateStreamPal,它与unix版本的Interop进行通信。网络安全。InitSecContext

这应该会触发操作系统中的GSSAPI

在dotnet运行时git中,他们告诉我们需要gss-ntlmssp才能工作,即使在aspnet核心留档中没有提到。

https://github.com/dotnet/runtime/issues?utf8=✓

尽管如此,我还是编译了gss ntlmssp,发现如果没有这个库,它会抛出错误“请求了一个不受支持的机制”。在my library中,它抛出错误“没有提供凭据,或者凭据不可用或无法访问。”,但永远不要使用任何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虚拟机、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

到目前为止,我已经从麻省理工学院源代码处编译了最新的gssapi,发现它向我抛出了一个错误“请求了一个不受支持的机制”因为gssapi需要未提供的gss解释器。在centos7中,我遇到了另一个问题,即openssl库使用的是不兼容的共享kerberos库,因此yum停止了工作。

***编辑

我发现gss ntlmssp有标记gss_C_MA_NOT_DFLT_MECH,因此它失败,并显示消息“未提供凭据,或凭据不可用或无法访问”。解决方案是构建没有此属性的定制gss ntlmssp,因为我希望将其用作默认身份验证机制

我的示例控制台应用程序检查凭据现在可以工作了,我将尝试将其放入docker容器中。

***编辑

我能够在库伯内特斯成功运行我的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_从……获得信誉。。

    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()返回错误,因为我没有特定的文件设置,因为我想验证来自ad的用户

external_get_creds()在此失败:

    wbc_status = wbcCredentialCache(&params, &result, NULL);
    if(!WBC_ERROR_IS_OK(wbc_status)) goto done;

external_get_creds尝试使用winbind库进行身份验证,显然在凭据缓存中没有用户

我设法用samba提供的winbind库编译了它

所以现在的问题是:如何设置winbind库与AD通信?

***编辑

我试着用它。net 5作为github的一员,我被告知NTLM在中国工作。净5。然而,我得到的结果与使用相同。净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 html" target="_blank">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核心3.1.

wbcCreentialCache(samba lib)在找不到缓存的凭据时失败

这是我的krb5。形态:

[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。不支持通配符。。。

然而,似乎我将无法运行. net核心5网络应用程序与ntlm,所以我将尝试设置它没有gssntlmssp库现在与一些默认kerberos机制。任何想法是什么问题与我的krb5.conf设置?

****所以我现在尝试两种不同的方法:

  1. NTLM-在我看来,这是最好的方式,因为我已经看到ntlm验证用户在iis Express例如没有对话框,并且不需要任何特殊配置在火狐或通过组策略(请修复我,如果我错了)
  2. 谈判

关于谈判,我已设法取得了一些进展。。

有了这个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

然而,现在我遇到了另一个问题:请求票证服务器HTTP/is。k01。我的域名。com@MYDOMAIN.com在keytab中找到kvno 3,但不使用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,只允许更新的编码,所以我要求我的infra部门用旧的rc4 hmac编码生成新的密钥表。

这一步让我更进一步,我得到了这个错误:请求票证服务器HTTP/is。k01。我的域名。com@MYDOMAIN.COM在keytab中未找到kvno 4;keytab可能已经过时了*

这是非常奇怪的,因为keytabs不能过时,密码没有被更改,并且在一个小时前生成keytab时是100%有效的,并且在网络上没有信息-"kvno 4 not找到keytab"在google中只获取4个结果。

****编辑

所以我终于成功了:)

与"kvno 4未在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

在我把它们注释掉之后,使用协商的身份验证开始工作。我已经测试了NTLM。net 5,但它仍然不起作用。

在docker容器中与之协商的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中使用

我认为internet explorer设置应该可以通过域组策略进行更新。。有人知道怎么做吗?

****编辑我已经测试通配符在域中的协商设置在浏览器中,这些是结果:

  • chrome:支持*。k01。我的域名。com

****编辑我已经开始使用谈判的胜利授权,但是我现在在. net核心中遇到了一些问题

IIS express下的此代码以MYDOMAIN\myuser的形式显示用户:

var userId = string.Join(',', User?.Identities?.Select(c => c.Name)) ?? "?";

在linux中,它显示为myuser@mydomain.com

使用者身份认同。IIS express下的第一个()是WindowsIdentity,我可以列出用户的所有组

使用者身份认同。Linux下的First()是没有组信息的ClaimsEntity

当我试图限制它与组在IIS快递我得到:

//Access granted
[Authorize(Roles = "MYDOMAIN\\GROUP1")]
//403
[Authorize(Roles = "MYDOMAIN\\GROUP_NOT_EXISTS")]

Linux红隼与谈判:

//403
[Authorize(Roles = "MYDOMAIN\\GROUP1")]

因此,红隼中的谈判似乎没有正确列出群体。所以我现在要调查,如何在红隼中获得Windows身份。

共有2个答案

姬俊远
2023-03-14

在dotnet runtime git中,他们告诉我们,即使在aspnet核心文档中没有提到gss ntlmssp,它也需要gss ntlmssp才能工作。

gss-ntlmssp包是一个插件,用于支持GSS-API的NTLM协议。它支持原始的NTLM协议,也支持在使用“谈判”(SPNEGO协议)时从Kerberos到NTLM的回退。参考文献:https://docs.microsoft.com/en-us/openspecs/windows_protocols/MS-SPNG/f377a379-c24f-4a0f-a3eb-0d835389e28a

通过阅读上面的讨论和您发布的图片,应用程序似乎试图实际使用NTLM而不是Kerberos。因为based64编码的令牌以“T”而不是“Y”开头,所以您可以分辨出来。

ASP。NET Core server(Kestrel)根本不支持Linux上的NTLM服务器端。它只提供将“Www身份验证:协商”发送回客户端的功能。通常这意味着将使用Kerberos。协商可以退回到使用NTLM。然而,这在ASP中不起作用。净核心,除了在。NET 5尚未发货。

您是否希望您的应用程序回到NTLM?如果没有,那么可能Kerberos环境还没有完全设置好。这可能是由多种问题造成的,包括SPN和Linux密钥表文件不正确。这也可能是由于客户端试图使用不属于Kerberos领域的用户名/密码造成的。

这里正在讨论这个问题:https://github.com/dotnet/aspnetcore/issues/19397

我建议在aspnet核心回购问题讨论中继续进行对话。

李敏学
2023-03-14

这篇文章是一个很好的例子,说明了人们对事物如何运作的误解。我完全不建议遵循作者在这里描述的方式(就像我所做的那样)。

相反,我建议您了解Kerberos身份验证、它的工作原理以及它需要的设置。这篇文章把它形象化了。

首先,如果您配置来自浏览器的超文本传输协议流量(例如用户Fiddler),您可以在第二个请求中找到TGS令牌。

  • 如果它以协商TlR开始,那么您正在通过NTLM进行身份验证

其次,就像David在ASP. NET Core 3.1之前所说的,Linux上根本不支持NTLM。因此,如果您有TlR令牌和ntlm-gssapi机制,您将得到"未提供凭据,或者凭据不可用或无法访问。"错误。如果您有TlR令牌并使用默认Kerberos机制,您将得到"请求不支持的机制"。

接下来,让你的应用运行良好的唯一方法是创建SPN并正确生成keytab用于Kerberos身份验证。不幸的是,这没有很好的文档记录。所以,我要在这里举一个例子来让事情更清楚。

假设你有:

  • 广告域名<代码>我的域名。COM

关于此处描述的说明,您需要执行以下操作:

  1. 将新的Web服务SPN添加到机器帐户:
  • setspn-S HTTP/webapp。网络服务领域。com我的机器
  • setspn-S HTTP/webapp@MYDOMAIN.COM我的机器
  • ktpass-princ HTTP/webapp.webservicedomain.com@MYDOMAIN.COM-pass myKeyTabFilePassword-mapuser MYDOMAIN\my机$-pTypeKRB5_NT_PRINCIPAL-out c:\temp\my机. HTTP. keytab-Crypto AES256-SHA1*.

*确保MYDOMAIN\mymachine在AD中允许AES256-SHA1

最后,在完成上述所有事情并将应用程序部署到带keytabLinux容器中后,集成的视窗身份验证应该运行良好。我的实验表明,你可以在任何你想要的地方使用keytab,而不仅仅是在名为“我的机器”的主机上。

 类似资料:
  • 赛贝斯ASE版本15或以上,并使用ADO. net连接到赛贝斯。是否可以使用Windows身份验证登录到赛贝斯ASE?

  • 问题内容: 下面是我的AutoIt脚本(UI3_Authentication.au3),用于处理Windows身份验证弹出窗口。 以下是我对上述AutoIt exe文件的Selenium代码调用。 当我运行上述Selenium文件时,它将打开页面并弹出身份验证。但这不是在插入用户名和密码。它等待用户输入。 问题答案: 我解决了 其实这是我的坏事。以前,我的代码是这样的: 我在get()之前添加了a

  • 我们正在尝试做一些具有登录屏幕的网站。但是我们有一个问题。我们的域是本地主机/登录/用户。但是,如果用户进入localhost/Home/Index,他/她无需登录即可访问我们的主站点。因此,我们将 [授权] 写入索引控制器。但我不知道我必须使用什么。我是否必须在我们的项目中使用AuthorizeAttribute? 如何访问LoginController/Authentication函数中的索引

  • 问题内容: 当使用node.js作为客户端时,是否可以使用Windows集成身份验证连接到服务器(例如,连接到IIS时)? 我对此的搜索仅显示将node.js用作服务器的结果。 问题答案: 2015更新: 现在有些模块实现了Windows集成的身份验证。 node- sspi 使用SSPI(Windows安全API)来处理服务器端的事务,但不执行client auth 。有几种客户端实现,例如ht

  • 我的问题是,我们有一组运行SiteMinder但非常糟糕的遗留代码。它允许IIS匿名并避免使用Active Directory。 我们正在重建此应用程序,并希望将SiteMinder与IIS和集成。净额4.0。我知道我可以构建自己的安全框架,无需用户名和密码即可完成所有工作(因为我们不希望SiteMinder提供),但我想知道是否有办法使用内置的Windows身份验证(窗体或Windows)与Si

  • 问题内容: 如何在Elasticsearch中定义安全性访问?我有elasticsearch-head插件,但是您的访问不需要任何安全性。 问题答案: 不再积极支持此答案中提到的插件。 elasticsearch中没有内置的访问控制。因此,您需要设置一个反向代理(这是一个博客文章,介绍如何设置nginx),使用第三方的Elasticsearch插件之一,例如https://github.com/A