I'm trying to implement OAuth using OWIN for a Web API v2 endpoint on my local intranet. The API is hosted in IIS using built-in Windows Authentication. In short, this is what I want to happen.
When I ask for my Token at /token
Pull the WindowsPrincipal out of the OWIN context
Use the SID from the WindowsPrincipal to look up some roles for this user in a SQL table.
Create a new ClaimsIdentity that stores the username and roles
Turn that into a Json Web Token (JWT) that I sent bak
When I request a resource from my API using my token
Convert the JWT Bearer token back to the ClaimsIdentity
Use that ClaimsIdentity for authorizing requests to the resource by role
This way I don't have to do a database lookup for user roles on each request. It's just baked into the JWT.
I think I'm setting everything up correctly. My Startup.Configuration method looks like this.
public void Configuration(IAppBuilder app)
{
// token generation
// This is what drives the action when a client connects to the /token route
app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
// for demo purposes
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromHours(8),
AccessTokenFormat = GetMyJwtTokenFormat(),
Provider = new MyAuthorizationServerProvider()
});
//// token consumption
app.UseOAuthBearerAuthentication(
new OAuthBearerAuthenticationOptions()
{
Realm = "http://www.ccl.org",
Provider = new OAuthBearerAuthenticationProvider(),
AccessTokenFormat = GetMyJwtTokenFormat()
}
);
app.UseWebApi(WebApiConfig.Register());
}
MyAuthorizationServerProvider looks like this...
public class MyAuthorizationServerProvider : OAuthAuthorizationServerProvider { public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { // Since I'm hosting in IIS with Windows Auth enabled // I'm expecting my WindowsPrincipal to be here, but it's null :( var windowsPrincipal = context.OwinContext.Request.User.Identity; // windowsPrincipal is null here. Why? // Call SQL to get roles for this user // create the identity with the roles var id = new ClaimsIdentity(stuff, more stuff); context.Validated(id); } }
My problem is that context.Request.User is null here. I can't get to my WindowsPrincipal. If I create some other dummy middleware, I can get to the WindowsPrincipal without issue. Why is it null in this context? Am I doing something wrong?