Registering bundles in web host was straight foward but this line doesn't work in self hosted mode. I'm not sure where to find them or how to register them in self hosted mode?
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Neither of these lines works in self hosted mode?
I created a filter to handle authentication in my api:
public class BasicAuthenticationAttribute : ActionFilterAttribute
{
static IAuthenticationMethod authMethod = new DefaultAuthentication();
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
if (actionContext.Request.Headers.Authorization == null)
{
actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
}
else
{
string authToken = actionContext.Request.Headers.Authorization.Parameter;
string decodedToken = "";
AuthenticatedIdentity authUser = null;
if (authToken.StartsWith("token="))
{
string test = authToken.Substring(7, authToken.Length - 8);
//sessionId
decodedToken = Encoding.UTF8.GetString(Convert.FromBase64String(authToken.Substring(7, authToken.Length - 8)));
authUser = authMethod.AuthenticateUser(decodedToken);
}
else
{
//username/password
decodedToken = Encoding.UTF8.GetString(Convert.FromBase64String(authToken));
string username = decodedToken.Substring(0, decodedToken.IndexOf(":"));
string password = decodedToken.Substring(decodedToken.IndexOf(":") + 1);
authUser = authMethod.AuthenticateUser(username, password);
}
if (authUser.IsAuthenticated)
{
if (HttpContext.Current != null) HttpContext.Current.User = new GenericPrincipal(authUser, new string[] { });
base.OnActionExecuting(actionContext);
}
else
{
actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized);
}
}
}
}
This works nicely in the Web Api because I can use HttpContext.Current.User to keep track of some user information and possibly use it to modify what some of the controllers return (authorization). When the api is self hosted, however, httpcontext.current
is null. Does anyone have any solutions for handling this in self hosted mode?
I'm also pretty new to MVC so there's a lot of things I probably don't know yet. Does anyone have any ideas on the above issues?
The whole point of REST is for it to be stateless obviously. Personally a true REST API shouldn't be handling this mechanism. So a couple thoughts on this. As theoretically your api could be used with various platforms assuming HttpContext won't work. Hence
really the API should just be responding with the status code and let the web application or whatever decide what to do with that.
Essentially that is what's happening in your hosted version. Just because you have your Web API in your MVC project together with the Web API doesn't mean its not interfacing as I'm describing.
API's I've built in the past don't handle any auth. I'll have a database or whatever with authorized third party apps that use pub/priv keys and a callback url. When the client hits the data if there is no authorization it hits the callback gets logged in
then accesses whatever. So the third party app or website handles all authentication to the RESTful urls and only it is able to access it directly.
Otherwise just handle the token or basic auth on the client side and send it with each request. Seems odd because we're so used to having some sort of FormsAuthenticationTicket or something but is easy to setup.
I know that's not an answer but thought I've give my .02.
When self-hosted and IIS hosted you should be setting both HttpContext.User *and* Thread.CurrentPrincipal. When only self-hosted you will only be setting Thread.CurrentPrincipal. This also means to be host agnostic, you should only access the current use
via Thread.CurrentPrincipal.
hurricane766
Member
2 Points
12 Posts
From Web host to Self host - HttpContext and more
Jun 22, 2012 09:35 PM|LINK
I've started out with a web hosted api and I'm attemping to create a self hosted app using much of the same code.
I'm finding it hard to find the equivents in self host for some of the web hosted stuff, for instance:
Registering bundles in web host was straight foward but this line doesn't work in self hosted mode. I'm not sure where to find them or how to register them in self hosted mode?
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } );Neither of these lines works in self hosted mode?
I created a filter to handle authentication in my api:
public class BasicAuthenticationAttribute : ActionFilterAttribute { static IAuthenticationMethod authMethod = new DefaultAuthentication(); public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext) { if (actionContext.Request.Headers.Authorization == null) { actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized); } else { string authToken = actionContext.Request.Headers.Authorization.Parameter; string decodedToken = ""; AuthenticatedIdentity authUser = null; if (authToken.StartsWith("token=")) { string test = authToken.Substring(7, authToken.Length - 8); //sessionId decodedToken = Encoding.UTF8.GetString(Convert.FromBase64String(authToken.Substring(7, authToken.Length - 8))); authUser = authMethod.AuthenticateUser(decodedToken); } else { //username/password decodedToken = Encoding.UTF8.GetString(Convert.FromBase64String(authToken)); string username = decodedToken.Substring(0, decodedToken.IndexOf(":")); string password = decodedToken.Substring(decodedToken.IndexOf(":") + 1); authUser = authMethod.AuthenticateUser(username, password); } if (authUser.IsAuthenticated) { if (HttpContext.Current != null) HttpContext.Current.User = new GenericPrincipal(authUser, new string[] { }); base.OnActionExecuting(actionContext); } else { actionContext.Response = new System.Net.Http.HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized); } } } }This works nicely in the Web Api because I can use HttpContext.Current.User to keep track of some user information and possibly use it to modify what some of the controllers return (authorization). When the api is self hosted, however, httpcontext.current is null. Does anyone have any solutions for handling this in self hosted mode?
I'm also pretty new to MVC so there's a lot of things I probably don't know yet. Does anyone have any ideas on the above issues?
chazelton
Member
102 Points
53 Posts
Re: From Web host to Self host - HttpContext and more
Sep 03, 2012 08:20 PM|LINK
The whole point of REST is for it to be stateless obviously. Personally a true REST API shouldn't be handling this mechanism. So a couple thoughts on this. As theoretically your api could be used with various platforms assuming HttpContext won't work. Hence really the API should just be responding with the status code and let the web application or whatever decide what to do with that.
Essentially that is what's happening in your hosted version. Just because you have your Web API in your MVC project together with the Web API doesn't mean its not interfacing as I'm describing.
API's I've built in the past don't handle any auth. I'll have a database or whatever with authorized third party apps that use pub/priv keys and a callback url. When the client hits the data if there is no authorization it hits the callback gets logged in then accesses whatever. So the third party app or website handles all authentication to the RESTful urls and only it is able to access it directly.
Otherwise just handle the token or basic auth on the client side and send it with each request. Seems odd because we're so used to having some sort of FormsAuthenticationTicket or something but is easy to setup.
I know that's not an answer but thought I've give my .02.
BrockAllen
All-Star
27434 Points
4891 Posts
MVP
Re: From Web host to Self host - HttpContext and more
Sep 03, 2012 08:27 PM|LINK
When self-hosted and IIS hosted you should be setting both HttpContext.User *and* Thread.CurrentPrincipal. When only self-hosted you will only be setting Thread.CurrentPrincipal. This also means to be host agnostic, you should only access the current use via Thread.CurrentPrincipal.
Also, here's a post related to that:
http://leastprivilege.com/2012/06/25/important-setting-the-client-principal-in-asp-net-web-api/
DevelopMentor | http://www.develop.com
thinktecture | http://www.thinktecture.com/