Correct way to authorize an ASMX .NET web service from MVC 4 Project

Jimbo picture Jimbo · Mar 7, 2016 · Viewed 10.5k times · Source

I have an ASP.NET MVC application that has a .asmx web service

I wrote an action filter attribute that I wanted to use on web methods on the web service, to check the Request headers for a UserID and Password, and throw an unauthorized response code if invalid or not present.

However, they dont appear to get called! Breakpoints just dont get hit.

Firstly, is using MVC attributes an acceptable way of authorizing web service called on an ASMX web service?

Secondly, is there a better/more efficient way of authorizing web service method calls?

Answer

Dave Alperovich picture Dave Alperovich · Mar 25, 2016

In answer to your first question, MVC filters and Web API filters cannot be triggered by ASMX web services.

  1. Action Filters are part of the MVC pipeline, triggered before (or after) an Action Method on a Controller (or API Controller) is executed. They can only be used within the MVC framework.

    Action Filter override a virtual method on a MVC Controller (OnActionExecuting). As only MVC Controllers have such methods, and only the MVC pipeline checks for them

  2. To make matters worse, ASMX services, by default, use SOAP protocol rather than HTTP protocol. SOAP services are not able to access HTTP contexts (e.g. HttpContext.Current.User) or HTTP Frameworks.

    Web services can be configured to use the HTTP protocol. But, even then, MVC specific attributes are of no help to you.


Ways to Authenticate legacy ASMX services

  • Ideal way is to add a Service Reference to your MVC 4 project, calling your ASMX method like any class library method from an [Authorize] secured Action Method or Web API method.

    This way, you can leverage your MVC or Web API Authentication filters.

  • If you prefer to secure your ASMX service directly, you can check to HttpContext.Current.User with Forms Authentication by configuring your ASMX service to use HTTP protocol.

in your web.config

<location path="SecuredMethod.asmx">
  <system.web>
    <webServices>
      <protocols>
        <add name="HttpGet"/>
        <add name="HttpPost"/>
      </protocols>
    </webServices>
  </system.web>
</location>