From what I understand, if you're only using Windows Authentication, you don't need to worry about GrantResourceOwnerCredentials. Are you trying to use the token authentication as well as the Windows authentication? you should only use Windows Authentication for a Web Api that is going to run on your intranet.
Forgive me if I say things you already know, but from the research I've done, and my thanks go to Dominick Baier on pluralsight, you need to:
- Install the Microsoft.Owin and Microsoft.Owin.Security.OAuth nuget packages
- Set Windows Authentication to "Enabled" on the Project (F4 properties window) or in the config file
- Make sure you have the [Authorize] attribute on your controller and inherit from the ApiController
- Specifically implement the Owin middleware (you will need to create three classes and make sure they are configured in the startup.cs class) Have a look at the following code:
1st Middleware class: declare the function
public class ClaimsTransformationOptions
{
public Func<ClaimsPrincipal, Task<ClaimsPrincipal>> ClaimsTransformation { get; set; }
}
2nd Middleware class: this is where the Invoke method is
public class ClaimsTransformationMiddleware
{
readonly ClaimsTransformationOptions _options;
readonly Func<IDictionary<string, object>, Task> _next;
public ClaimsTransformationMiddleware(Func<IDictionary<string, object>, Task> next, ClaimsTransformationOptions options)
{
_next = next;
_options = options;
}
public async Task Invoke(IDictionary<string, object> env)
{
// use Katana OWIN abstractions (optional)
var context = new OwinContext(env);
if (context.Authentication != null &&
context.Authentication.User != null)
{
var transformedPrincipal = await _options.ClaimsTransformation(context.Authentication.User);
context.Authentication.User = new ClaimsPrincipal(transformedPrincipal);
}
await _next(env);
}
}
3rd Middleware class: this is an extension class
public static class ClaimsTransformationMiddlewareExtensions
{
public static IAppBuilder UseClaimsTransformation(this IAppBuilder app,
Func<ClaimsPrincipal, Task<ClaimsPrincipal>> transformation)
{
return app.UseClaimsTransformation(new ClaimsTransformationOptions
{
ClaimsTransformation = transformation
});
}
public static IAppBuilder UseClaimsTransformation(this IAppBuilder app, ClaimsTransformationOptions options)
{
if (options == null)
{
throw new ArgumentNullException("options");
}
app.Use(typeof(ClaimsTransformationMiddleware), options);
return app;
}
}
In the startup class:
public void Configuration(IAppBuilder app)
{
app.UseClaimsTransformation(Transformation);
}
private async Task<ClaimsPrincipal> Transformation(ClaimsPrincipal incoming)
{
if (!incoming.Identity.IsAuthenticated)
{
return incoming;
}
var name = incoming.Identity.Name;
// go to a datastore - find the app specific claims
var claims = new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier, name),
new Claim(ClaimTypes.Role, "foo"),
new Claim(ClaimTypes.Email, "foo@foo.com")
};
var id = new ClaimsIdentity("Windows");
id.AddClaims(claims);
return new ClaimsPrincipal(id);
}
In the Controller (Make sure it has the [Authorize] attribute and inherits from ApiController
public IEnumerable<ViewClaim> Get()
{
var principal = User as ClaimsPrincipal;
return from c in principal.Claims
select new ViewClaim
{
Type = c.Type,
Value = c.Value
};
}