0

I have a normal WCF service that is exposed as a SOAP service and I need to secure it with an ApiKey that will be provided in either the HTTP header or as a HTTP query parameter. Both the retrieval of the WSDL and the consuming of the web service must be protected but this ApiKey. Finally, if validation fails, an empty document with an HTTP status code must be returned.

I have tried various stuff using behaviors but the best effort only secured the consuming part and I was unable to return an empty document (always returned a SOAP fault XML document with my exception details). I have not been able to intercept the WSDL generation and return 401/403 HTTP status code.

I realize this is non-standard, but this is how the requirements are presented to me.

I assume this is possible, but I am at a loss.

The project basically only has 1 .cs file containing the required interface and the implementation thereof:

[ServiceContract]
public interface IFooService
{
    [OperationContract]
    barOut Lookup(string baz);
}

If anyone has done this, I'd like to get some pointers.

galmok
  • 869
  • 10
  • 21
  • You can check out the solution provided by [this thread](https://stackoverflow.com/questions/5314625/causing-http-error-status-to-be-returned-in-wcf). – Lan Huang May 10 '22 at 08:38
  • I had a look at it, and it doesn't activate for me. I tried adding the attribute all places I could think of, but nothing worked. Also, looking at the code, this seems to fix the HTTP status code problem (if I could make it work), but will still return a SoapFault XMLdocument. And unfortunately it does nothing to the WSDL security. – galmok May 10 '22 at 09:08
  • You can check this post on [how to add SOAP security headers.](https://stackoverflow.com/questions/19111773/how-to-add-soap-security-header) – Lan Huang May 11 '22 at 08:50

1 Answers1

0

The solution turned out to be quite simple. I could use the Application_BeginRequest override in Global.asax.cs that is being called on each request, it being WSDL retrieval or consuming the SOAP service:

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        if (!Validate(HttpContext.Current.Request))
        {
            HttpContext.Current.Response.StatusCode = 401;
            var httpApplication = sender as HttpApplication;
            httpApplication.CompleteRequest();
        }
    }

    private bool Validate(HttpRequest request)
    {
        var allowedApiToken = Kernel.Get<IServiceConfiguration>().ApiKey;
        var apiToken = request?.Headers["X-ApiKey"];
        if (apiToken == null)
        {
            apiToken = request?.QueryString["api_key"];
        }
        if (apiToken != allowedApiToken)
        {
            return false;
        }
        return true;
    }
galmok
  • 869
  • 10
  • 21