Pergunta

I am using ASP.NET4.5 with C#. In my web-application, there is a form authentication implemented that uses cookie to store authentication information.

In web.config it is specified as :

<authentication mode="Forms">
      <forms loginUrl="~/login.aspx" />
</authentication>

Now, I have a WCF RESTfull service for which I am using custom basic authentication. For each service call I need to set an authentication header and if it is not valid then I have to return response with 401 code.

The code is as below :

public class BasicAuthenticationInterceptor : RequestInterceptor
{
    MembershipProvider provider;
    string realm;

    public BasicAuthenticationInterceptor(MembershipProvider provider, string realm)
        : base(false)
    {
        this.provider = provider;
        this.realm = realm;
    }

    protected string Realm
    {
        get { return realm; }
    }

    protected MembershipProvider Provider
    {
        get { return provider; }
    }

    public override void ProcessRequest(ref RequestContext requestContext)
    {
        HttpRequestMessageProperty request = (HttpRequestMessageProperty)requestContext.RequestMessage.Properties[HttpRequestMessageProperty.Name];
        string[] credentials = ExtractCredentials(requestContext.RequestMessage);

        if (credentials.Length > 0 && AuthenticateUser(credentials[0], credentials[1]))
        {
            InitializeSecurityContext(requestContext.RequestMessage, credentials[0]);
        }
        else
        {
            try
            {
                Message reply = Message.CreateMessage(MessageVersion.None, "Invalid Action", "Access Denied");
                HttpResponseMessageProperty responseProperty = new HttpResponseMessageProperty() { StatusCode = HttpStatusCode.Unauthorized };

                responseProperty.Headers.Add("WWW-Authenticate",
                String.Format("Basic realm=\"{0}\"", Realm));
                responseProperty.Headers[HttpResponseHeader.ContentType] = "text/html";
                reply.Properties[HttpResponseMessageProperty.Name] = responseProperty;
                requestContext.Reply(reply);
                requestContext = null;
            }
            catch (Exception ex)
            {
                throw ex.InnerException;
            }
        }
    }
}

Now, to prevent form authetication for WCF call, I have added following tag in web.config :

<location path="MyService.svc">
   <system.web>
      <authorization>
          <allow users="*"/>
      </authorization>
   </system.web>
</location>

Note that, the WCF placed in "Service" directory of my project, I have tried using path="~/service/MyService.svc", path="service/MyService.svc", path="service" in location tab, but it is returning 200, NOT 401 code.

Now, I have tested the service call using Fire-fox RESTClient add-on and found that for invalid request it is still returning 200 code and in row-body I am getting HTML of my login.aspx page. That means it is still redirecting to login.aspx.

If I change the authetication mode in web.config to "None" then service call works fine with returning 401 code for invalid request. But I can not set authentication mode to "None".

Please let me know how to prevent the form authentication for WCF call.

Foi útil?

Solução

Resolved it my self :

I have added following code in Application_AuthenticateRequest() event of Global.asax and it is working fine now :

HttpApplication context = (HttpApplication)sender;

if (context.Request.Url.ToString().Contains(".svc"))
{
    context.Response.SuppressFormsAuthenticationRedirect = true;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top