使用 Owin 和 Web API 以及 SimpleInjector 找不到资源
The resource cannot be found using Owin and Web API and SimpleInjector
当我在 owin OAUth 旁边使用 Simpleinjector 进行基于令牌的登录时,Simpleinjector 无法解析我的控制器并且我收到 404 错误 "The resource cannot be found" 消息。
我使用 owin 管道处理我的请求,并使用 Owin Security 来生成和验证用户令牌。
作为 DI 的简单注入器和 ASP.NET 5
我在 Whosebug 上尝试了这个解决方案:
和这个在 simpleinjector 文档中:
http://simpleinjector.readthedocs.io/en/latest/owinintegration.html
而这个对我不起作用(我没有 BeginExecutionContextScope
)
WebApi + Simple Injector + OWIN
这是我的 startup.cs:
public class Startup
{
public void Configuration(IAppBuilder app)
{
SimpleInjectorBootstrapper.Initialize();
app.Use(async (context, next) => {
using (AsyncScopedLifestyle.BeginScope(SharedLayer.Core.CoreObject.container))
{
await next();
}
});
ConfigureOAuth(app);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
FilterConfig.RegisterHttpFilters(GlobalConfiguration.Configuration.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
HttpConfiguration config = new HttpConfiguration();
WebApiConfig.Register(config);
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(SharedLayer.Core.CoreObject.container));
config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(SharedLayer.Core.CoreObject.container);
app.Use<ExceptionMiddleware>();
app.Map(new PathString("/api"), application => { application.Use<AuthenticateMiddleware>(); });
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}
public void ConfigureOAuth(IAppBuilder app)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
Provider = new AuthorizationProvider(),
};
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
}
这是我的简单注入器引导程序:
public static class SimpleInjectorBootstrapper
{
public static void Initialize()
{
// Create a new Simple Injector container
var container = new Container();
// Set default Scope
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
// Configure the container (register)
var businessAssembly = typeof(BusinessLayer.Bootstrap.SimpleInjectorBootstrapper).Assembly;
// get services based on conditions
var registerations = from type in businessAssembly.GetExportedTypes()
where type.Namespace.Contains("BusinessLayer.Logic")
where type.GetInterfaces().Any()
select new
{
Service = type.GetInterfaces().First(),
Implementation = type
};
// register each service
foreach (var reg in registerations)
{
container.Register(reg.Service, reg.Implementation, Lifestyle.Scoped);
}
// init nested bootstrapper
BusinessLayer.Bootstrap.SimpleInjectorBootstrapper.Initialize(container);
// Register Root services
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.RegisterMvcIntegratedFilterProvider();
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
// Optionally verify the container's configuration.
container.Verify();
// Store the container for use by the application
//DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
// Assign SimpleInjectorWebApiDependencyResolver to DependencyResolver
//GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
// store container in a static variable for DI in class libraries
SharedLayer.Core.CoreObject.container = container;
}
}
当我评论这两行时,我的应用程序工作正常:
ConfigureOAuth(app);
app.Map(new PathString("/api"), application => { application.Use<AuthenticateMiddleware>(); });
我的错误在哪里?
编辑:
我发现当我评论这一行时我的项目工作正常:
app.Map(new PathString("/api"), application => {
application.Use<AuthenticateMiddleware>();
});
这是我的 AuthenticateMiddleware 代码:
public class AuthenticateMiddleware : OwinMiddleware
{
public AuthenticateMiddleware(OwinMiddleware next)
: base(next)
{}
public async override Task Invoke(IOwinContext context)
{
string username = "";
if (context.Request.Method.Equals(HttpMethod.Get.Method))
{
if (context.Request.Query.Any(e => e.Key == "username" && e.Value != null))
username = context.Request.Query.Get("username");
}
else
{
var body = new StreamReader(context.Request.Body).ReadToEndAsync().Result;
var dict = HttpUtility.ParseQueryString(body);
var json = new JavaScriptSerializer().Serialize(dict.AllKeys.Where(e => e.Equals("username")).ToDictionary(k => k, k => dict[k]));
JObject jsonObject = JsonConvert.DeserializeObject<JObject>(json);
username = jsonObject["username"] != null ? jsonObject["username"].ToString() : "";
}
if (username == "")
throw new ArgumentNullException("username is required.");
if (!context.Authentication.User.HasClaim("username", username))
throw new SecurityException("token is invalid.");
await Next.Invoke(context);
}
}
在挑战我的项目并将其搁置 2 周后,我找到了所有问题的解决方案,谢谢@Steven
主要问题是 owin 映射。
我必须从路线定义中删除 api 段,我还不知道为什么,但它有效。谢谢@Tracher
当我在 owin OAUth 旁边使用 Simpleinjector 进行基于令牌的登录时,Simpleinjector 无法解析我的控制器并且我收到 404 错误 "The resource cannot be found" 消息。
我使用 owin 管道处理我的请求,并使用 Owin Security 来生成和验证用户令牌。
作为 DI 的简单注入器和 ASP.NET 5
我在 Whosebug 上尝试了这个解决方案:
和这个在 simpleinjector 文档中: http://simpleinjector.readthedocs.io/en/latest/owinintegration.html
而这个对我不起作用(我没有 BeginExecutionContextScope
)
WebApi + Simple Injector + OWIN
这是我的 startup.cs:
public class Startup
{
public void Configuration(IAppBuilder app)
{
SimpleInjectorBootstrapper.Initialize();
app.Use(async (context, next) => {
using (AsyncScopedLifestyle.BeginScope(SharedLayer.Core.CoreObject.container))
{
await next();
}
});
ConfigureOAuth(app);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
FilterConfig.RegisterHttpFilters(GlobalConfiguration.Configuration.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
HttpConfiguration config = new HttpConfiguration();
WebApiConfig.Register(config);
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(SharedLayer.Core.CoreObject.container));
config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(SharedLayer.Core.CoreObject.container);
app.Use<ExceptionMiddleware>();
app.Map(new PathString("/api"), application => { application.Use<AuthenticateMiddleware>(); });
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}
public void ConfigureOAuth(IAppBuilder app)
{
OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/token"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
Provider = new AuthorizationProvider(),
};
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
}
这是我的简单注入器引导程序:
public static class SimpleInjectorBootstrapper
{
public static void Initialize()
{
// Create a new Simple Injector container
var container = new Container();
// Set default Scope
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
// Configure the container (register)
var businessAssembly = typeof(BusinessLayer.Bootstrap.SimpleInjectorBootstrapper).Assembly;
// get services based on conditions
var registerations = from type in businessAssembly.GetExportedTypes()
where type.Namespace.Contains("BusinessLayer.Logic")
where type.GetInterfaces().Any()
select new
{
Service = type.GetInterfaces().First(),
Implementation = type
};
// register each service
foreach (var reg in registerations)
{
container.Register(reg.Service, reg.Implementation, Lifestyle.Scoped);
}
// init nested bootstrapper
BusinessLayer.Bootstrap.SimpleInjectorBootstrapper.Initialize(container);
// Register Root services
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.RegisterMvcIntegratedFilterProvider();
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
// Optionally verify the container's configuration.
container.Verify();
// Store the container for use by the application
//DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
// Assign SimpleInjectorWebApiDependencyResolver to DependencyResolver
//GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
// store container in a static variable for DI in class libraries
SharedLayer.Core.CoreObject.container = container;
}
}
当我评论这两行时,我的应用程序工作正常:
ConfigureOAuth(app);
app.Map(new PathString("/api"), application => { application.Use<AuthenticateMiddleware>(); });
我的错误在哪里?
编辑:
我发现当我评论这一行时我的项目工作正常:
app.Map(new PathString("/api"), application => {
application.Use<AuthenticateMiddleware>();
});
这是我的 AuthenticateMiddleware 代码:
public class AuthenticateMiddleware : OwinMiddleware
{
public AuthenticateMiddleware(OwinMiddleware next)
: base(next)
{}
public async override Task Invoke(IOwinContext context)
{
string username = "";
if (context.Request.Method.Equals(HttpMethod.Get.Method))
{
if (context.Request.Query.Any(e => e.Key == "username" && e.Value != null))
username = context.Request.Query.Get("username");
}
else
{
var body = new StreamReader(context.Request.Body).ReadToEndAsync().Result;
var dict = HttpUtility.ParseQueryString(body);
var json = new JavaScriptSerializer().Serialize(dict.AllKeys.Where(e => e.Equals("username")).ToDictionary(k => k, k => dict[k]));
JObject jsonObject = JsonConvert.DeserializeObject<JObject>(json);
username = jsonObject["username"] != null ? jsonObject["username"].ToString() : "";
}
if (username == "")
throw new ArgumentNullException("username is required.");
if (!context.Authentication.User.HasClaim("username", username))
throw new SecurityException("token is invalid.");
await Next.Invoke(context);
}
}
在挑战我的项目并将其搁置 2 周后,我找到了所有问题的解决方案,谢谢@Steven
主要问题是 owin 映射。
我必须从路线定义中删除 api 段,我还不知道为什么,但它有效。谢谢@Tracher