I setup my HttpListener to allow Basic and Anonymous authentication. I also add a new MessageHandler called AuthenticationHandler to my configuration.
public void Configuration(IAppBuilder appBuilder)
{
var listener = (HttpListener)appBuilder.Properties["System.Net.HttpListener"];
listener.AuthenticationSchemes = AuthenticationSchemes.Basic | AuthenticationSchemes.Anonymous;
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
//...
config.MessageHandlers.Add(new AuthenticationHandler());
appBuilder.UseWebApi(config);
}
AuthenticationHandler
is a DelegatingHandler
. I set up my claims, identity and principal as below:
if (validCredentials)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, userName),
new Claim(ClaimTypes.AuthenticationMethod, AuthenticationMethods.Password),
};
var roles = user.Roles.ToString().Split(',');
// Make sure to add all the user's roles to the claims
claims.AddRange(roles.Select(role => new Claim(ClaimTypes.Role, role)));
var identity = new ClaimsIdentity(claims, Scheme);
var principal = new ClaimsPrincipal(new [] {identity});
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
HttpContext.Current.User = principal;
}
If I check Thread.CurrentPrincipal in the debugger my principal has my identity and all the claims that I've added. All seems fine inside the DelegatingHandler, however these claims are not making their way to my controller.
In my controller I have a simple [Authorize(Roles="Admin")]
attribute on a function. However, if I check the User
in the debugger, the only claim listed is the username. So [Authorize]
works, as does [Authorize(Users="admin')]
, however, obviously role based authentication will not work. I could of course look the username up in the database and manually check the roles in the function, but that is clearly not the correct way of going about this. What am I doing wrong?