Pretty new to Authorization and Authentication so maybe I'm missing some important step... Just looking at numerous references, guides, and tutorials.
I may need to do something in my WebApiConfig?
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Or possibly in my Global.asax:
public class WebApiApplication : System.Web.HttpApplication
{
private const string RootDocument = "/index.html";
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
}
protected void Application_BeginRequest(Object sender, EventArgs e)
{
// Stuff to redirect to index.html unless it's an api url
}
}
This is an ASP.Net Web API project targeting .NET Framework 4.5.2 with an Angular 2 frontend and I do nothing manually on the front end, maybe I need to do that? My Local Storage, Session Storage, and Cookies are all empty on the browser.
The SQL Server I'm accessing has a very simple user logon method which returns a role and userId, which I call in my repository here:
public static DbUser Logon(AuthUser user)
{
var parameters = new List<SqlParameter>();
{
// Add parameters, get the DbUser (contains role and userId), and return the DbUser
}
}
Logon frontend is built with Angular 2 and makes an HttpPost call with username and password upon submit to the following API method, creating an identity and principal, and setting the Thread and HttpContext:
// POST api/<controller>
[HttpPost]
public TokenUser Post(AuthUser user)
{
var dbUser = DBAccess.Repository.User.Logon(user);
var identity = new ClaimsIdentity();
identity.AddClaim(new Claim(ClaimTypes.Name, "CwRole"));
identity.AddClaim(new Claim(ClaimTypes.Role, dbUser.AccessLevel));
identity.AddClaim(new Claim(ClaimTypes.UserData, dbUser.ID.ToString()));
var principal = new ClaimsPrincipal(identity);
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
HttpContext.Current.User = principal;
// Other stuff and a return statement =>
// Note I'm not actually doing anything manually with the token on the front end
// which may be why I'm not seeing it in the debugger's Resources tab...
}
When I step through that code I can see clearly that Thread.CurrentPrincipal and HttpContext.Current.User are both being populated, appropriately it would seem.
But if I decorate an action with the [Authorize] attribute, I can't access it whether logged in or not.
// Works fine
public IEnumerable<ItemGroup> Get()
{
return DBAccess.Repository.Item.GetItemGroups();
}
// Responds with 401 (Unauthorized) no matter what
[Authorize]
public IEnumerable<RequestItem> Get()
{
return DBAccess.Repository.Item.GetRequestItems();
}
So I created these methods, accessed them via browser url after the above logon process and stepped through, only to find that the User is never actually set (claims are all empty, etc...)
public class AuthController : ApiController
{
public bool Get()
{
// Stepping through, looks like User.Identity is not even set...
var authenticated = User.Identity.IsAuthenticated;
return authenticated;
}
public bool Get(string role)
{
// As a matter of fact, User doesn't have any claims or anything...
var user = User;
return user != null && user.IsInRole(role);
}
}
So what step am I missing to make the principal accessible after it's set? Do I need to access it with something other than WebApi's built-in "User" methods or set something on my configuration, or do something manually on the front end?