0

I have an ASP.NET Core web application, which I'm using to host a WCF Core service. This is my Program.cs:

using System.Text;
using CoreWCF;
using CoreWCF.Channels;
using CoreWCF.Configuration;
using CoreWCF.Description;
using Microsoft.AspNetCore.Authentication;
using WebApplication1;

const string HOST_IN_WSDL = "localhost";

var builder = WebApplication.CreateBuilder(args);

// Add WSDL support
builder.Services.AddServiceModelServices().AddServiceModelMetadata();

// Use the scheme/host/port used to fetch WSDL as that service endpoint address in generated WSDL 
builder.Services.AddSingleton<IServiceBehavior, UseRequestHeadersForMetadataAddressBehavior>();


builder.Services.AddHttpContextAccessor();
builder.Services.AddAuthentication("MyScheme")
    .AddScheme<AuthenticationSchemeOptions, MyAuthenticationHandler>("MyScheme", null);

builder.Services.AddAuthorization();


var app = builder.Build();

app.UseServiceModel(builder =>
{


    builder.AddService(typeof(MyService), (serviceOptions) =>
    {
        serviceOptions.BaseAddresses.Add(new Uri($"https://{HOST_IN_WSDL}/MyService"));
    })
        .AddServiceEndpoint(typeof(MyService),
            typeof(IMyService),
           new WSHttpBinding(SecurityMode.Transport), // SOAP 1.2
           new Uri("", UriKind.RelativeOrAbsolute), (Uri)null, null);

});

// Enable WSDL for http & https
var serviceMetadataBehavior = app.Services.GetRequiredService<ServiceMetadataBehavior>();
serviceMetadataBehavior.HttpGetEnabled = serviceMetadataBehavior.HttpsGetEnabled = true;

app.MapGet("/", () => "Hello World!");

app.UseAuthentication();
app.UseAuthorization();

app.Run();

MyService.cs:

internal class MyService : IMyService
{
    public async Task<string> HelloWorld(string name)
    {
        await Task.Delay(1);
        return $"Hello, {name}!";
    }
}

IMyService.cs:

using CoreWCF;

[ServiceContract(Namespace = "http://schemas.test.com/myengine")]
public interface IMyService
{
    [OperationContract(AsyncPattern = true)]
    Task<string> HelloWorld(string name);
}

MyAuthenticationHandler.cs:

using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Options;
using System.Security.Claims;
using System.Text.Encodings.Web;

namespace WebApplication1
{
    public class MyAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
    {
        public MyAuthenticationHandler(
            IOptionsMonitor<AuthenticationSchemeOptions> options,
            ILoggerFactory logger,
            UrlEncoder encoder
       )
            : base(options, logger, encoder)
        {
        }



        protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            // Retrieve the current principal
            var currentPrincipal = System.Web.HttpContext.Current.User;

            // Create a ClaimsPrincipal if the current principal is not a ClaimsPrincipal
            var claimsPrincipal = currentPrincipal as ClaimsPrincipal ?? new ClaimsPrincipal(currentPrincipal);
            return AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal, Scheme.Name));
            //            return AuthenticateResult.Fail("Invalid credentials");
        }
    }
}

When I call my service with SoapUI, I get this error:

HTTP/1.1 500 Internal Server Error Content-Type: text/plain; charset=utf-8 Date: Wed, 06 Aug 2025 14:00:58 GMT Server: Kestrel Transfer-Encoding: chunked

System.InvalidOperationException: No authentication handler is registered for the scheme 'Negotiate'. The registered schemes are: MyScheme. Did you forget to call AddAuthentication().AddSomeAuthHandler? at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme) at CoreWCF.Channels.RequestDelegateHandler.HandleRequest(HttpContext context) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at CoreWCF.Channels.ServiceModelHttpMiddleware.InvokeAsync(HttpContext context) at CoreWCF.Channels.MetadataMiddleware.InvokeAsync(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

HEADERS ======= Connection: keep-alive Host: localhost:7075 User-Agent: Apache-HttpClient/4.5.5 (Java/17.0.12) Accept-Encoding: gzip,deflate Content-Type: application/soap+xml;charset=UTF-8;action="http://schemas.test.com/myengine/IMyService/HelloWorld" Content-Length: 432

I would like to handle authentication myself. What do I need to change to stop it from checking the Negotiate scheme?

1 Answer 1

0
    var text = new TextMessageEncodingBindingElement(
        MessageVersion.CreateVersion(EnvelopeVersion.Soap12, AddressingVersion.None),
        Encoding.UTF8);
    var https = new HttpsTransportBindingElement();
    var binding = new CustomBinding(text, https);

This custombinding was the fix for me.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.