Thanks to some good feedback from @grumpydev, @loudej and Chriss Ross – I changed my original claims transformation middleware (see here). What I learned is, that for better compatibility and discoverability, you should not expose the types of a specific framework (in my case Katana) on your public API surface. It is OK to use that framework internally – if you can live with that dependency. Here’s my 2nd take:
public class ClaimsTransformationMiddleware
readonly ClaimsTransformationOptions _options;
readonly Func<IDictionary<string, object>, Task> _next;
Func<IDictionary<string, object>, Task> next,
_next = next;
_options = options;
public async Task Invoke(IDictionary<string, object> env)
// use Katana OWIN abstractions (optional)
var context = new OwinContext(env);
var transformer = _options.ClaimsAuthenticationManager;
if (context.Authentication != null &&
context.Authentication.User != null)
context.Authentication.User = transformer.Authenticate(
Note that I am not deriving from OwinMiddleware anymore and also use the AppFunc on the Invoke method (instead of IOwinContext).
Note: This middleware does not work with Katana’s passive authentication mode. But that’s another issue.