41

I have got a web service programmed in c# / asp.net.

[WebService(Namespace = "http://example.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
[System.ComponentModel.ToolboxItem(false)]
public class Service: System.Web.Services.WebService
{

    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public Result GetData()
    {
        User user = GetUser();

        if (user.LoggedIn)
        {
            return GetData();
        }
        else
        {
            // raise exception -> return error 403
        }
    }

How is it possible to return error 403 out of this web service? I can throw an exception - but this shows the exeption and not his error.

Any ideas?

bernhardrusch
  • 11,670
  • 12
  • 48
  • 59
  • You return value from service only if user is 'LoggedIn' you must return that 'Result' type from that method. – 1110 Apr 13 '11 at 13:28
  • and how do I return this 'Result' type ? – bernhardrusch Apr 13 '11 at 13:40
  • You declare your method to return 'Result' type. And you must return object of that type from your method. What is 'Data()'? You cant return something from only one 'if' block, because if that block is false your method will not return anything. – 1110 Apr 13 '11 at 13:49
  • I thought I can raise an exceptino or something like this and then the web service would return 403 – bernhardrusch Apr 13 '11 at 13:55
  • 3
    Code 401 would be more appropriate as the user could access the resource if he loggs in – Daniel Mar 15 '13 at 10:16

10 Answers10

35

If you were using MVC you'd do the following:

            return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
Bryan Legend
  • 6,790
  • 1
  • 59
  • 60
32

You don't need to set both Context.Response.Status and Context.Response.StatusCode. Simply setting

Context.Response.StatusCode = (int)System.Net.HttpStatusCode.Forbidden

will automatically set Response.Status for you.

Jay Tomten
  • 1,657
  • 1
  • 14
  • 23
23

To answer the question completely - this is the code I've used (thank you strider for more information):

[WebService(Namespace = "http://example.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
[System.ComponentModel.ToolboxItem(false)]
public class Service: System.Web.Services.WebService
{

    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public Result GetData()
    {
        User user = GetUser();

        if (user.LoggedIn)
        {
            return GetData();
        }
        else
        {
            Context.Response.Status = "403 Forbidden"; 
            //the next line is untested - thanks to strider for this line
            Context.Response.StatusCode = 403;
            //the next line can result in a ThreadAbortException
            //Context.Response.End(); 
            Context.ApplicationInstance.CompleteRequest(); 
            return null;
        }
    }
bernhardrusch
  • 11,670
  • 12
  • 48
  • 59
  • This gives me a ThreadAbortException when used with WebMethod and ScriptMethod. – Eterm Jul 20 '15 at 13:18
  • try using Context.ApplicationInstance.CompleteRequest() instead of Context.Response.End() – bernhardrusch Jul 20 '15 at 14:21
  • 2
    Worth mentioning that `Response.Status = "403 Forbidden"; ` is the complete `status` that consists of `Response.StatusCode` and `Response.StatusDescription`. It might be better to use `Response.StatusDescription` instead of `Response.Status` – G. Stoynev Sep 20 '16 at 20:40
  • In my case it's called "ActionContext" instead of "Context" – Zohar Aug 02 '22 at 14:29
7

You can protect all your methods by placing the code in your WebService constructor. This prevents your WebMethod from even being called:

public Service(): base()
{
    if (!GetUser().LoggedIn)
    {
        Context.Response.StatusCode = (int)System.Net.HttpStatusCode.Forbidden;
        Context.Response.End();
    }
}
Andy Joiner
  • 5,932
  • 3
  • 45
  • 72
  • Not necessarily correct....I leverage WebMethods through AJAX calls and I have to work to authenticate the user(s) through encrypted cookies – GoldBishop Mar 15 '18 at 13:03
  • This doesn't make sense. Your constructor isn't called when your web methods are called. Refer to @bernhardrusch's answer. – Exegesis Jan 04 '21 at 19:08
6

In Asp.Net Web Api 2, you'd use:

return new StatusCodeResult(HttpStatusCode.Forbidden, this);
arviman
  • 5,087
  • 41
  • 48
3
Context.Response.StatusCode = 403;
Mark Cidade
  • 98,437
  • 31
  • 224
  • 236
1

Your web service requests will first encounter your global.asax file. You can check & return there.

Chuck Savage
  • 11,775
  • 6
  • 49
  • 69
1

aspnet core you can return forbidResult. This is an IResult.

return new ForbidResult();
Mike
  • 623
  • 6
  • 26
0

Forbidden 403 would be a result of access to forbidden content on your website. I think what you want here is to return a message as part of your Result that is "User is not logged on"

Orin
  • 351
  • 5
  • 13
0

The return Forbid(); creates a ForbidResult (Status403Forbidden by default).

https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controllerbase.forbid?view=aspnetcore-3.1