* Scenario: *
I have got a web api service application made in C# Visual Studio 2012. This web service has an "Areas" folder with the default project of Web Api Help Page.
* Problem: *
By requeriment, I must to implement a manual input to authenthicate and authorize the user that can read the Web Api Help Page. But NOT in the web service.
So far so good, I've made an account controller, log in procedures, get roles from the database, etc etc.
But now, what I try to realize is how to write the Application_PostAuthenticateRequest procedure in the global.asax, because the only global.asax that I've is from the main project, the Web API Help Page has not his own.
* QUESTION *
How can I write the Application_PostAuthenticateRequest method without impacting on the main service, in order to use the Authorization attributes ONLY in the Web API Help Page?
Thanks and kind regards,
If I understand your question you want to route to just a specific path with Authorization only?
If this is the case you can use routing as part of WebAPI 2
Within the WebAPIConfig.cs
add the following configuration
public static void Register(HttpConfiguration config)
{
//Enable attribute routing
config.MapHttpAttributeRoutes();
//... additional configuraitons
}
Then within your API controller you can setup a route independent of the default and add whatever attribute you need:
[Route("apiname/authroizedLogin")]
[Authorize(Roles="admin")]
public void IHttpActionResult(string username, stringpassword)
{
try
{
dosomething...
return Ok(somecontext);
}
catch(exception e)
{
return BadResponse(e.message);
}
}
Here is a link with more information on routes in WebAPI 2
Edit
With regards to accessing the role. It depends on your implementation. I'm personally not a fan of using the global.asx as it would make a db request more frequently. I'd need more info on your implementation to make any real recommendation. However here are a few options. If you are using claims based authentication the role can be a part of the claim and would be passed to the API as part of the http context/request. From here you can derive the identity as:
public long RoleId
{
get
{
var identity = (ClaimsPrincipal)Thread.CurrentPrincipal;
string id = identity.Claims.Where(c => c.Type == "http://myschema.com/app/claims/roleid")
.Select(c => c.Value).SingleOrDefault();
//return 0 if no claim is located
return (!String.IsNullOrEmpty(id)) ? Convert.ToInt32(id) : 0;
}
set
{
_userId = value;
}
}
If you're not using claims another option would be to generate a FormsAuthenticaitonTicket which could be encrypted and stored as a cookie once the user is authenticated.