HTTP 请求未经客户端身份验证方案“匿名”授权;动态资产净值

发布于 2025-01-17 00:28:41 字数 2574 浏览 4 评论 0原文

我有一个关于 .net core 应用程序 (3.1) 尝试从 Dynamics Nav Server 使用 WS (SOAP) 的问题。 (内部部署)。 当我处于调试模式时,一切正常,但是当我将应用程序部署到本地 IIS 服务器时,我不断收到 “HTTP 请求未经客户端身份验证方案‘匿名’的授权。从服务器收到的身份验证标头是‘oRswGaADCgEAoxIEEAEA=,Negotiate’。”

客户端初始化

private async Task<TXSiteUser_PortClient> GetInstanceAsync()
{
            EndpointAddress endpointAddress = new EndpointAddress(serviceUrl);
            BasicHttpBinding basicHttpBinding = new BasicHttpBinding()
            {
                MaxReceivedMessageSize = int.MaxValue,
                MaxBufferSize = int.MaxValue,
                OpenTimeout = TimeSpan.MaxValue,
                CloseTimeout = TimeSpan.MaxValue,
                ReceiveTimeout = TimeSpan.MaxValue,
                SendTimeout = TimeSpan.MaxValue
            };

            return await Task.Run(() => new TXSiteUser_PortClient(basicHttpBinding, endpointAddress));
        }

调用 WS 的示例

var client = await GetInstanceAsync();

var user = await client.ReadAsync(new Read { Id = id });

await client.CloseAsync();

return user.TXSiteUser;

Dynamics 服务器的凭据类型为“Windows”。 下面是 web.config

<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath=".\ArtoilPortal.exe" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
    </system.webServer>
  </location>
</configuration>

奇怪的是,当我处于调试模式并从 Swagger 测试端点时,一切正常。另外,每次我尝试使用邮递员时,无论身份验证类型如何(基本、NTML),我都会收到 401。 我也尝试过

basicHttpBinding.Security.Mode = BasicHttpSecurityMode.Transport;
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
var username = _appSettings.NAVCredentials.UserName;
var password = _appSettings.NAVCredentials.Password;

像这样添加和扩展 PortClient 方法,

        public TXSiteUser_PortClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress, string userName, string password) : 
                base(binding, remoteAddress)
        {

            this.ChannelFactory.Credentials.UserName.UserName = userName;
            this.ChannelFactory.Credentials.UserName.Password = password;
            ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
        }

但没有成功

I have an issue regarding an .net core app (3.1) trying to consume a WS (SOAP) from a Dynamics Nav Server. (on-premise).
When I'm in debugging mode everything works fine, but when I deployed the app to local IIS server I keep getting
"The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'oRswGaADCgEAoxIEEAEA=,Negotiate'."

Client initialization

private async Task<TXSiteUser_PortClient> GetInstanceAsync()
{
            EndpointAddress endpointAddress = new EndpointAddress(serviceUrl);
            BasicHttpBinding basicHttpBinding = new BasicHttpBinding()
            {
                MaxReceivedMessageSize = int.MaxValue,
                MaxBufferSize = int.MaxValue,
                OpenTimeout = TimeSpan.MaxValue,
                CloseTimeout = TimeSpan.MaxValue,
                ReceiveTimeout = TimeSpan.MaxValue,
                SendTimeout = TimeSpan.MaxValue
            };

            return await Task.Run(() => new TXSiteUser_PortClient(basicHttpBinding, endpointAddress));
        }

Example of call to a WS

var client = await GetInstanceAsync();

var user = await client.ReadAsync(new Read { Id = id });

await client.CloseAsync();

return user.TXSiteUser;

The Dynamics server has the credential type "Windows".
And below is the web.config

<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath=".\ArtoilPortal.exe" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
    </system.webServer>
  </location>
</configuration>

The weird thing is that when I'm in debugging mode and testing the endpoints from Swagger, everything works ok. Also, everytime I try to use postman I get a 401, no matter of Auth type (Basic,NTML).
Also i've tried adding

basicHttpBinding.Security.Mode = BasicHttpSecurityMode.Transport;
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
var username = _appSettings.NAVCredentials.UserName;
var password = _appSettings.NAVCredentials.Password;

and extended the PortClient method like this

        public TXSiteUser_PortClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress, string userName, string password) : 
                base(binding, remoteAddress)
        {

            this.ChannelFactory.Credentials.UserName.UserName = userName;
            this.ChannelFactory.Credentials.UserName.Password = password;
            ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
        }

with no luck

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浮萍、无处依 2025-01-24 00:28:41

设法解决了错误。
首先,通过使用“TransportCredentialOnly”而不是“Transport”修复了客户端初始化代码。

 basicHttpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;

当 Dynamics NAV 服务器上没有为 SOAP 服务配置 SSL 时,将使用 TransportCredentialOnly 模式。

对我有用的“PortClient”方法的版本如下所示:

public TXSiteUser_PortClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress, string userName, string password) : 
            base(binding, remoteAddress)
    {
        this.ClientCredentials.Windows.ClientCredential.UserName = userName;
        this.ClientCredentials.Windows.ClientCredential.Password = password;
        this.ClientCredentials.Windows.ClientCredential.Domain = "";
        ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
    }

在原来的帖子中,我正在设置

 this.ChannelFactory.Credentials.UserName.UserName = userName;

它应该在的位置

 this.ClientCredentials.Windows.ClientCredential.UserName = userName;

希望这会在某个时候对某人有所帮助

managed to solve the errors.
Firstly, the client initialization code was fixed by using "TransportCredentialOnly" instead of "Transport"

 basicHttpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;

TransportCredentialOnly mode is used when there's no SSL configured for the SOAP services on Dynamics NAV server.

And the version of "PortClient" method that works for me looks like this:

public TXSiteUser_PortClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress, string userName, string password) : 
            base(binding, remoteAddress)
    {
        this.ClientCredentials.Windows.ClientCredential.UserName = userName;
        this.ClientCredentials.Windows.ClientCredential.Password = password;
        this.ClientCredentials.Windows.ClientCredential.Domain = "";
        ConfigureEndpoint(this.Endpoint, this.ClientCredentials);
    }

In the original post I was setting

 this.ChannelFactory.Credentials.UserName.UserName = userName;

Where it should've been

 this.ClientCredentials.Windows.ClientCredential.UserName = userName;

Hopefully this will help somebody at some point

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文