.NetCore with SoapCore how make the authentication

4.4k views Asked by At

I want to add authentication as NetworkCredential but I do not know how do I set the authentication

var binding = new BasicHttpBinding();
        var endpoint = new EndpointAddress(new Uri(string.Format("http://{0}:5050/Service.svc", Environment.MachineName)));
        var channelFactory = new ChannelFactory<ISampleService>(binding, endpoint);
        var serviceClient = channelFactory.CreateChannel();
2

There are 2 answers

1
kavanka On

You can inspire in my code. It took me some time and some investigation. Remember, service contract interface is implemented by controller, I did not find any other way to put the service request to http pipeline. Due to this configuration I can run REST and SOAP branches on one code.

In Startup.cs:

using SoapCore;
using ZNetCS.AspNetCore.Authentication.Basic;
using ZNetCS.AspNetCore.Authentication.Basic.Events;

public void ConfigureServices (IServiceCollection services)
{
   services.AddScoped<YourNamespace.BasicAuthValidator>();
   services.AddSingleton<YourNamespace.Contracts.IEnityService, YourNamespace.Controllers.ApiController>();
   services.AddAuthentication(BasicAuthenticationDefaults.AuthenticationScheme)
        .AddBasicAuthentication(op => {
            op.Realm = "YourRealm";
            op.EventsType = typeof(YourNamespace.BasicAuthValidator);
        });
    services.AddControllers();          
}

public void Configure (IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();
    app.UseEndpoints(endpoints => {
    endpoints.MapControllers().RequireAuthorization(); //Use DefaultAuthorizationPolicy, ie. require authenticated users on REST interface
    endpoints.UseSoapEndpoint<YourNamespace.Contracts.IEnityService>("/SOAP/YourService.svc", this.CreateBindingForSOAP(), SoapSerializer.DataContractSerializer).RequireAuthorization();
}

BasicHttpBinding CreateBindingForSOAP ()
{
    var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport); //security is on HTTP level
    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic; //http challenges filling Authorization header
    return binding;
}

Then create class for handling basic authentication:

public class BasicAuthValidator:BasicAuthenticationEvents
{
    public override Task ValidatePrincipalAsync (ValidatePrincipalContext context)
    {
        if ((context.UserName == "userName") && (context.Password == "password")) {
            var claims = new List<Claim>{new Claim(ClaimTypes.Name, context.UserName, context.Options.ClaimsIssuer)};

            var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, context.Scheme.Name));
            context.Principal = principal;
        } 
            
        return Task.CompletedTask;
    }
}
0
martinoss On

If you just need the SOAP endpoints and want to do mutual authentication, I came up with following solution:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme)
        .AddCertificate(options => 
        {                    
            options.Events = new CertificateAuthenticationEvents
            {
                OnCertificateValidated = context =>
                {
                    // Add additional validation
                    return Task.CompletedTask;
                }
            };
        });

    services.AddAuthorization();
    services.AddSingleton<IMyService, MyService>();
    services.AddSoapCore();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseCertificateForwarding();
    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.UseSoapEndpoint<IMyService>((options) =>
        {
            options.Path = "/myservice";
            options.Binding = new BasicHttpBinding();
            options.SoapSerializer = SoapSerializer.XmlSerializer;
        })
        .RequireAuthorization();
    });
}

Note: Your implemented SOAP service doesn't need to be an API controller. Also read here about client certificates in .NET Core