locked
Self Hosted API is always returning 401 RRS feed

  • Question

  • User-1946294156 posted

    For starters, I am following the below article for the security portion:

    http://www.colinkraft.com/code/webapi-selfhosting.htm

    I have a Self Hosted Web API with a simple controller, just returns a string.  When I set my StartUp Class with this Configuration Method, I am always getting 401, unauthorized:

    public class Startup
        {
            public void Configuration(IAppBuilder appBuilder)
            {
                HttpListener listener = (HttpListener)appBuilder.Properties["System.Net.HttpListener"];
                listener.AuthenticationSchemes = AuthenticationSchemes.IntegratedWindowsAuthentication;
    
                HttpConfiguration config = new HttpConfiguration();
                config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
    
                config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
                
                appBuilder.UseWebApi(config);
            }
        }

    When I comment out the below lines, I get a different unauthorized:

    //HttpListener listener = (HttpListener)appBuilder.Properties["System.Net.HttpListener"];
    //listener.AuthenticationSchemes = AuthenticationSchemes.IntegratedWindowsAuthentication;

    I still get the Unauthorized, but I get the below message returned.  "Authorization has been denied for this request." This is leading me to believe That when the listener is setup with the authentication Scheme of Integrated Windows Auth, it is automatically denying me and not even getting to the controller.  

    How do I setup the Authentication Scheme to work with this type of setup?

    Thursday, March 17, 2016 4:01 PM

Answers

  • User36583972 posted

    Hi bobj181,

    I have made a sample on my side. I reproduce your error. I solve the error with the following code. You can refer it and get some ideas.

    Program:

    class Program
        {
            static void Main(string[] args)
            {
                string baseAddress = "http://localhost:9000/";
                // Start OWIN host 
                using (WebApp.Start<Startup>(url: baseAddress))
                {
    
                    //ICredentials cred = new NetworkCredential("mydomain\\myuser", "mypassword");// you should host web api in IIS with windows authentication.
    
                    ICredentials cred = CredentialCache.DefaultNetworkCredentials;//self host
                    var rq = WebRequest.CreateHttp(baseAddress + "api/values");
                    rq.Credentials = cred;
                    //rq.PreAuthenticate = true;
                    var rsp = rq.GetResponse();
                    var strm = rsp.GetResponseStream();
                    var rsr = new StreamReader(strm);
                    var res = rsr.ReadToEnd();
                    Console.WriteLine(res.ToString());
                }
                Console.ReadLine();
            }
        }

    Startup:

    class Startup
        {
            // This code configures Web API. The Startup class is specified as a type
            // parameter in the WebApp.Start method.
            public void Configuration(IAppBuilder appBuilder)
            {
                HttpListener listener = (HttpListener)appBuilder.Properties["System.Net.HttpListener"];
                listener.AuthenticationSchemes = AuthenticationSchemes.IntegratedWindowsAuthentication;
    
                //Configure Web API for self-host. 
                HttpConfiguration config = new HttpConfiguration();
                //config.Filters.Add(new AuthorizeAttribute());
                config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
                appBuilder.UseWebApi(config);
            }
    
        }

    ValuesController:

    [Authorize]
        public class ValuesController : ApiController
        {
            // GET api/values 
            [Authorize]
            public IEnumerable<string> Get()
            {
                return new string[] { "value1", "value2" };
            }
            [Authorize]
            // GET api/values/5 
            public string Get(int id)
            {
                return "value";
            }
            [Authorize]
            // POST api/values 
            public void Post([FromBody]string value)
            {
            }
            [Authorize]
            // PUT api/values/5 
            public void Put(int id, [FromBody]string value)
            {
            }
            [Authorize]
            // DELETE api/values/5 
            public void Delete(int id)
            {
            }
        }

    The following tutorials for your reference.

    1: If you are using Microsoft.Owin.Host.HttpListener to self-host Katana, you can enable Windows Authentication directly on the HttpListener instance.

    Enabling Windows Authentication in Katana:

    http://www.asp.net/aspnet/overview/owin-and-katana/enabling-windows-authentication-in-katana

    2: Authentication and Authorization in ASP.NET Web API

    http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api

    3: ASP.NET Web API Self-Host with Windows Authentication

    http://stackoverflow.com/questions/9571445/asp-net-web-api-self-host-with-windows-authentication

    Best Regards,

    Yohann Lu

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, March 18, 2016 5:53 AM